Kurt Nørmark
Department of Computer Science, Aalborg University, Denmark
Abstract Previous lecture Next lecture Index References Contents | In this lecture we will study how to approach a number of other programming paradigms from the functional programming paradigm - in Scheme. This includes imperative programming and object-oriented programming. Coroutines and trampolining will also be studied. |
Object-oriented Programming |
Program: The forms discussed. |
|
Functions and closures revisited Slide Annotated slide Contents Index References | On this page we review some of the properties of function object - also known as closures. The contents of this pages is taken directly from an earlier pages in this material. |
The concept function object: A function object represents a function at run time. A function object is created as the value of a lambda expression | A function object is a first class value at run time, in the same way as numbers, lists and other data are values. This is different from more traditional programming languages, where procedural and functional abstractions have another status than ordinary data. | |
The concept closure: A function object is also known as a closure. | The name 'closure' is related to the interpretation of free names in the body expression of the function. Free names are used, but not defined in the body. In a function object (or closure) the free names are bound in the context of the lambda expression. This is a contrast to the case where the free names are bound in the context of the application of the function. |
|
|
Classes and objects Slide Annotated slide Contents Index References |
|
|
Program: The definition of a 'class Point ' with methods getx , gety , add , and type-of. On this page we have also defined the syntactical convenience function send that sends a message to an object. In Racket be sure that you define send before Point (such that send in the add method refers to our send , and not an already existing and unrelated definition of
the name send ). |
|
Program: The send method which is used in the Point class. The function apply calls a function
on a list of parameters. This should be seen in contrast to a normal call, in which the individual parameters
are passed. |
|
Exercise 3.2. Points and Rectangle | The purpose of this exercise is to strengthen your understanding of functions used as classes in Scheme. First, play with the existing Point class defined on this page available from the on-line version of this material. As an example, construct two points and add them together. Also, construct two lists of each four points, and add them together pair by pair. Define a new method in the Point class called (move dx dy), which displaces a point with dx units in the x direction and dy units in the y direction. We encourage you to make a functional solution in which move creates a new displaced point. (After that you may consider an imperative solution, in which the state of the receiving point can be changed with an assignment, set!). Finally, define a new class, Rectangle, which aggregates two points to a representation of a rectangle. Define move and area methods in the new class. As a practical remark to the 'class Point ' and the send primitive, be sure to define send before you define Point . (This is done to redefine an existing send procedure in Racket). |
A general pattern of classes Slide Annotated slide Contents Index References |
|
Program: A general template of a simulated class. construction-parameters are typically transferred to the let construct, which we want to play the role as
instance variables. Next comes explicitly defined methods, and last is the object handle called self .
Notice that the value returned by the class is the value of self - the object handle. |
|
Program: Accompanying functions for instantiation and message passing. |
|
|
Example of the general class pattern Slide Annotated slide Contents Index References |
|
Program: The class Point implemented with use of the general class template. The Point class corresponds to the Point class defined on an earlier page.
Notice that the bindings of x and y in the let construct is superfluous in the example.
But due to the simultaneous name binding used in let constructs, they make sense.
Admittedly, however, the let construct looks a little strange.
|
|
Program: All the necessary stuff to play with Point. | ![]() |
Program: A sample construction and dialogue with point. |
|
A general pattern of classes with inheritance Slide Annotated slide Contents Index References |
|
Program: A general template of a simulated class with inheritance. |
|
Program: The root of a class hierarchy. |
|
Program: Accompanying functions for instantiation, message passing, and method lookup. |
|
An example of classes with inheritance Slide Annotated slide Contents Index References |
|
Program: A specialization of Point which is called ColorPoint. |
|
Program: Class Point - A subclass of object - with a new method point-info. |
|
Program: All necessary stuff to play with ColorPoint. | ![]() |
Program: A sample construction and sample dialogue with ColorPoint. |
|
The interpretation of self Slide Annotated slide Contents Index References |
|
Figure. Two different interpretations of self . We see two linear class hierarchies. The class C inherits from B, which in turn inherits from A. And similarly, F inherits from E, which inherits from D. The one to the left - in the green class hierarchy - is the naive one we have obtained in our templates and examples until now. The one to the right - in the yellow class hierarchy, shows another interpretation of self . Following this interpretation, self at all levels refer to the most specialized object part. | ![]() |
A general pattern of a class hierarchy with virtual methods Slide Annotated slide Contents Index References |
|
Program: A general template of a simulated class with inheritance. |
|
Program: The functions new-instance, virtual-operations, and others. | ![]() |
An example of virtual methods Slide Annotated slide Contents Index References |
|
Program: All necessary stuff to play with ColorPoint. | ![]() |
Program: A sample construction and sample dialogue with ColorPoint. |
|
Exercise 3.4. Color Point Extensions | On this page we have seen the class ColorPoint, which inherits from Point. The classes make use of virtual methods. In this exercise you should start with the code in this file.
|
Exercise 3.4. Representing HTML with objects in Scheme | This is an open exercise - maybe the start of a minor project - The exercises relates to LAML. I do not recommend this exercise in this variant of PP. In the original mirror of HTML in Scheme, the HTML mirror functions, return strings. In the current version, the mirror functions return an internal syntax tree representation of the web documents. With this, it is realistic to validate a document against a grammar while it is constructed. In this exercise we will experiment with an object representation of a web document. We will use the class and object representation which we have introduced in this lecture. Construct a general class html-element which implement the general properties of a HTML element object. These include:
In addition, construct one or more examples of specific subclasses of html-element , such as html , head , or body. These subclasses should have methods to access particular, required constituents of an element instance, such as the head and the body of a HTML element, and title of a head element. Also, the concrete validation predicate must be redefined for each specific element. |
Summing up: Simulation of OOP in Scheme Slide Annotated slide Contents Index References |
|
|
|
Imperative Programming |
Imperative Programming in a Functional Language Slide Annotated slide Contents Index References |
|
|
Sequential Control Slide Annotated slide Contents Index References |
|
|
Jumps in Functional Programs Slide Annotated slide Contents Index References |
|
Table. Programs with goto. In the Scheme expression, notice that the calls of L2 (twice) and L1 (once) in L1 are all tail calls. Therefore in these calls, there is no need to return to L1 after the simulation of a goto. Consequently, we simple leave L1 when/if L1 or L2 is called. |
|
|
|
Selection Control Slide Annotated slide Contents Index References |
|
|
|
Iterative Control Slide Annotated slide Contents Index References |
|
|
Table. Euclid's gcd function programming in C with a while loop, and in Scheme with a tail recursive function |
|
Assignments in Functional Programs Slide Annotated slide Contents Index References |
|
Table. We illustrate the handling of single assignments (first row) |
|
State in Functional Programs Slide Annotated slide Contents Index References |
|
Table. We illustrate the handling of state transitioning |
|
Object Mutation Slide Annotated slide Contents Index References |
|
Table. We illustrate object mutation - a point in C and Scheme. In Scheme we use a cons pair for the x and y coordinates. |
|
Continuations |
Introduction and motivation Slide Annotated slide Contents Index References | We start by motivating our interest in continuations. One part of the story is the usefulness of a mechanism that allows us to 'jump out of a deep subexpression'. Another part is the possibility of controlling and manipulating the 'remaining part of the calculation' relative to some given control point. |
|
|
|
The catch and throw idea Slide Annotated slide Contents Index References |
|
Syntax: |
|
Syntax: |
|
|
|
A catch and throw example Slide Annotated slide Contents Index References | We now give a Common Lisp like example of catch and throw. |
|
Program: An example using catch and throw. Please notice that the example is not a proper Scheme program.
Catch and throw are not defined in Scheme. |
|
|
|
The intuition behind continuations Slide Annotated slide Contents Index References |
The concept continuation: A continuation of the evaluation of an expression E in a surrounding context C represents the future of the computation, which waits for, and depends on, the value of E |
Table. An intuitive understanding of continuations of an expression in some context. |
|
Being more precise Slide Annotated slide Contents Index References | Instead of relying of an informal understanding of continuations we will now introduce lambda expressions that represent the continuations. |
|
Table. A more precise notation of the continuations of E |
|
The capturing of continuations Slide Annotated slide Contents Index References | It is now time to introduce the Scheme primitive that allows us to capture a continuation. |
|
Table. Use of call/cc and capturing of continuations. |
|
Capturing, storing, and applying continuations Slide Annotated slide Contents Index References |
|
Table. Capturing and applying continuations. The captured continuations are stored in a global variable. The application of the continuation is shown in the third column, and the result of the application of the continuation is shown in the fourth column. |
|
Use of continuations for escaping purposes Slide Annotated slide Contents Index References |
|
Table. Capturing and use of a continuation for escaping purposes |
|
Practical example: Length of an improper list Slide Annotated slide Contents Index References |
|
Program: The function list-length, which returns the symbol 'improper-list in case it encounters an improper list. |
|
|
Practical example: Searching a binary tree Slide Annotated slide Contents Index References |
|
Program: A tree search function which uses a continuation found if we find what we search for. Notice that this examples requires the function subtree-list, in order to work.
The function returns #f in case we do not find node we are looking for.
Notice that it makes sense in this example to have both the if expression and the
#f value in sequence! |
|
|
|
Continuation Passing Style |
Continuation Passing Style Slide Annotated slide Contents Index References |
|
|
Program: A function programmed in both direct style and continuation passing style. |
|
Program: Functions w, f, g and h programmed in direct style. |
|
Program: The same functions programmed in continuation passing style. |
|
Exercise 3.5. A discriminant function in continuation passing style | Program the following discriminant function (lambda (a b c) (- (* b b) (* 4 a c))) in continuation passing style (CPS).
In the program above we have provided auxilliary functions for squaring, multiplication and subtraction. These functions must be provided with an extra continuation parameter when you program the CPS variants of the functions. Consider different evaluation orders, and how it affects the CPS variant of the functions. |
|
Program: The usual recursive factorial function - in direct and continuation passing style. |
|
Program: The tail recursive factorial function - in direct and continuation passing style. |
|
Program: The list-length function - continuation passing style - handling improper lists. |
|
Program: An iterative list-length function - continuation passing style - handling improper lists. |
|
|
Observations about continuation passing style Slide Annotated slide Contents Index References |
|
|
Coroutines |
Coroutines Slide Annotated slide Contents Index References |
|
Figure. The flow of control among functions (F1 calls F2) left, and among coroutines (C1 and C2 resume each other). | ![]() |
Simulating Coroutines in Scheme Slide Annotated slide Contents Index References |
|
|
Program: Template for resuming C2 from C1. | ![]() |
A simpel producer and consumer Slide Annotated slide Contents Index References |
|
Program: Producer Consumer - pure functional programming in Scheme. | ![]() |
|
Program: Alternative Producer Consumer - the other coroutine is maintained in mutable state. | ![]() |
|
Simultaneous traversal of two binary trees (1) Slide Annotated slide Contents Index References |
|
Figure. Two binary trees together with the results of the simultaneous traversals | ![]() |
|
Simultaneous traversal of two binary trees (2) Slide Annotated slide Contents Index References |
|
|
Program: The tree traversal functions. | ![]() |
Program: The controller function. | ![]() |
Program: Tree stuff, traversal, and controller - in one file. | ![]() |
Trampolining |
Trampolining Slide Annotated slide Contents Index References |
|
Program: A few functions - to be trampolined below. |
|
Program: Augmenting with bounce and return. |
|
Program: Redefining bounce and return. |
|
Program: Introducing a single threaded scheduler: pogo-stick. |
|
Exercise 3.7. Trampolining a recursive factorial function without tail calls?! | On the accompanying slide we have studied so-called trampolining of tail calls. In this exercise we will understand if/why it is necessary to apply trampolining on tail calls. Use return and bounce in a 'normal, (non-tail)recursive factorial function' fact-rec or a similar function that does not make use of tail calls. What happens if we call the function, and if we attempt to drive or schedule the computation of (fact-rec 5) with pogo-stick? Explain your findings, and draw your conclusions. |
Program: Multithreaded schedulers: seesaw and trampoline. |
|
Exercise 3.7. A variant of seesaw that completes both threads | The function seesaw, as discussed on the slide, only completes one of the threads. This may be convenient in some situations (if one of the threads runs infinitly), but in general we are interested in the results of both threads. Here is the version of seesaw that we discuss: (define (seesaw thread-1 thread-2) (cond ((eqv? 'done (tag-of thread-1)) (tag-value thread-1)) ((eqv? 'doing (tag-of thread-1)) (seesaw thread-2 (call (tag-value thread-1)))))) Program a version of seesaw that - at the very end - return a list of length 2: First element must be the value finally returned by thread-1, and the second element must be the value finally returned by thread-2. Here is an example of the call of the new version of seesaw: > (seesaw (fact-iter 5 1) (fib 8)) (120 21) Your variant of seesaw may be seen as an example of a loop which maintains some state (the two threads, their status (doing/done), and their values - if they exist). As such, this exercise is a good example of programming an iterative, tail-recursive, state-transitioning function in Scheme. Here is all you need to get started: (define (return x) (tag 'done x)) (define (bounce thunk) (tag 'doing thunk)) (define (call thunk) (thunk)) (define (tag label thing) (cons label thing)) (define tag-of car) (define tag-value cdr) (define (fact-iter n acc) (if (zero? n) (return acc) (bounce (lambda () (fact-iter (- n 1) (* acc n)))))) (define (mem? n lst) (cond ((null? lst) (return #f)) ((= (car lst ) n) (return #t)) (else (bounce (lambda () (mem? n (cdr lst))))))) (define (fib n) (fib-iter n 0 0 1)) (define (fib-iter n i small large) (if (< i n) (bounce (lambda () (fib-iter n (+ i 1) large (+ large small)))) (return small))) (define (pogo-stick thread) (cond ((eqv? 'done (tag-of thread)) (tag-value thread)) ((eqv? 'doing (tag-of thread)) (pogo-stick (call (tag-value thread)))))) ; A version of seesaw that delivers 'the value of the fastest thread'. ; The one from the video. (define (seesaw thread-1 thread-2) (cond ((eqv? 'done (tag-of thread-1)) (tag-value thread-1)) ((eqv? 'doing (tag-of thread-1)) (seesaw thread-2 (call (tag-value thread-1)))))) |
|
|
More exercises Slide Annotated slide Contents Index References |
Exercise 3.9. Can you read and understand an expression with call/cc? | Take a look at this expression: (let ((x 1) (y 2) (z 3) (v 5)) (cons x (call/cc (lambda (e) (cons y (cons z (if (even? v) v (e (+ v 1))))))))) What is the value of the expression? [Needless to say: Figure it out without just putting it into your Scheme REPL.] Play with it - and try out possible variations. The same for: (let ((x 1) (y 2) (z 3) (v 5)) (+ x (call/cc (lambda (e) (+ y (+ z (if (even? v) v (e (+ v 1))))))))) |
Exercise 3.9. Capturing a continuation when traversing a list | This exercises is strange! Therefore, I discourage you from making it. Most likely, you will be more confused about continuations after having made this exercise than before... Write a simple recursive function square-list that traverse a list of numbers, with the purpose of squaring each element in the list. Modify your function such that it captures a continuation of the handling of the third element in the list (if such an element exists). Replace the squared number with this continuation. Are you able to access the captured contination from the list, and demonstrate how to use it? Try this: > (define xxx (square-list (list 1 2 3 4 5 6))) > ((caddr xxx) '()) Explain your results (or lack of results). caddr is a convenient composition of car, cdr and cdr. Now try to assign the captured continuation (with set!) to a global variable remember-continuation. After you have called square-list, play with your captured and stored continuation: > (square-list (list 1 2 3 4 5 6)) > remember-continuation > (remember-continuation '()) > (remember-continuation '(10 11 12)) Discuss and explain the results you obtain. |
Chapter 3: Simulation of other Paradigms and Continuations
Course home Author home About producing this web Previous lecture (top) Next lecture (top) Previous lecture (bund) Next lecture (bund)
Generated: August 17, 2021, 12:49:21