(define (segments->painter segment-list)
(lambda (frame)
(for-each
(lambda (segment)
(draw-line
((frame-coord-map frame)
(start-segment segment))
((frame-coord-map frame)
(end-segment segment))))
segment-list)))
Some of you have already seen this sicp example before but for the first timers a brief explanation: segments->painter procedure takes arguments from segment list which has values are segments made up from vectors. for-each procedure acts like map but instead returns a list of value, it does operations like printing or in this code it draws lines. frame-coord-map scales frames according to unit square frame. What I don't understand in this code is where does first lambda function takes its argument (frame) from.
Here is a case of currying.
In your code
(define (segments->painter segment-list)
(lambda (frame)
...))
when you call segments->painter, scheme will return an object of some type, let us call figure. When you apply a graphical frame on this object, scheme will be able to draw your object.
(define obj1 (segments->painter seg1))
obj1 is an object of type figure and this object is able to receive frames. It is able to do only one action when it receives a frame, namely to get drawn in that frame: (obj1 frame1), (obj1 frame2), etc are actions you can do on that object.
Before to apply the graphical data on some object, it does make sense to talk about that object but it does not make sense to talk about a real representation of that object. In your case, the object can do one single action: to get drawn.
Between calling the contructor for the figure object and drawing the object you can do some (static) preprocessing, such that in the moment when you call the drawing method, you have already precomputed something.
This is how types are implemented in programming languages. This Peter Henderson's language is a first introduction to types and to combinators. This will be developped further in the 4th chapter, where the interpreter uses some precomputed data to execute (it converts the list input format to internal format).
Let's look at a simpler example:
(define (adder x)
(lambda (y)
(+ x y))
The analogous question would be, "Where does y come from, if you can call adder with only x?" As discussed in the comments, it comes from whoever calls the lambda that adder returns. You may write:
(define plus5 (adder 5))
(plus5 8) ; 13
(plus5 1) ; 6
At the point that you call adder, there is no y. In the next call, y is 8, and after that it is 1.
Likewise in your actual code, there is no frame until someone calls the returned lambda.
Related
The parameter of call/cc is a procedure taking as its argument a continuation. Is the procedure written in CPS?
No.
CPS-styled functions expect other normal functions as their argument(s), and may call them in tail position. These functions are confusingly called "continuations" in Scheme vernacular. I prefer "contingencies", to disambiguate.
The argument function to call/cc expects an actual undelimited continuation as its argument. That actual continuation is not a function. Calling it with a value returns that value into that continuation's return context which is thus saved along with the continuation -- a feat unheard of w.r.t. simple functions.
A tail-called function returns its result into its calling function's caller's context.
A continuation which is called returns the supplied value to its creating call/cc call's context. It is thus not a function. Thus a function using it is not written in CPS.
Firstly, what is CPS? Continuation-Passing Style is a way of compiling a program which relies on continuations (i.e. uses the call/cc operator) into a target language which doesn't support continuation, but does support lexical closures and tail calls (or some facsimile of tail calls, like the ability to roll back the stack when it gets too deep with actual call frames).
A program transformed with CPS is itself not written in the continuation-passing style. It doesn't have to be; it has a call/cc operator provided by the CPS translator, which gives it access to the current continuation wherever it is needed.
Because CPS is mostly a source-to-source transformation, it is illustrated and taught using hand-written, explicit CPS. Quite often, the Scheme language is used for this. The Scheme language already has call/cc, but when experimenting with explicit, hand-written CPS, we have to pretend that call/cc doesn't exist. Under the CPS paradigm, we can, of course, provide an operator called my-call/cc which is built on our CPS, and has nothing to do with the underlying Scheme's call/cc.
In a CPS-compiled language implementation, every procedure has a continuation argument (with the necessary exception of procedures in the host language's library). The functional argument of call/cc, the function which receives the continuation, is no exception. Being a procedure in a CPS-world, it has to have continuation parameter, so that it is compatible with procedure calls, which pass that argument.
The argument procedure of call/cc can in fact use that continuation argument, and the very first example of the Wikipedia demonstrates this. Here is a copy of that example, in which I renamed the return parameter to c, to reduce confusion:
(define (f c) ;; function used for capturing continuation
(c 2) ;; invoke continuation
3) ;; if continuation returns, return 3.
(display (f (lambda (x) x))) ; displays 3
(display (call/cc f)) ; displays 2
The procedure f's c argument doesn't have to be a continuation; in the first call it's just the dummy function (lambda (x) x). f calls it, and that function returns, and so then control falls through to the 3.
Under CPS, f has a hidden argument, which we can reveal with hand-written CPS:
(define (f c k)
(c 2 k)
(k 3 k))
When 3 is being returned, it's because the hidden continuation is invoked. Since the program can do that, f has to have one.
Note that c and k are different continuations! Maybe that's where the confusion comes in. The c continuation is the caller's current one that is passed by call/cc, and is part of the explicit semantics of call/cc. The k is the hidden one added by the CPS transformer. It's f's own continuation. Every function has one in the CPS-transformed world. Under the CPS paradigm, if f wishes to return, it calls k (which is why I renamed return to c). If f wishes to continue the suspended call/cc, it calls c.
By the way, under automatic CPS, k is not going to be literally called k, because that wouldn't be hygienic: programs can freely bind the k symbol. It will have to be a machine-generated symbol (gensym), or receive some other form of hygienic treatment.
The only function that have to be treated specially under CPS so that they don't have continuation arguments are library functions in the host language/VM that are to be available to the CPS-translated language. When the CPS-translated language calls (display obj) to print an object, that display function either has to be a renamed wrapper that can take the continuation argument (and then ignore it and call the real display function without it), or else the call to display has to be specially handled by the CPS translator to omit the continuation argument.
Lastly, why can CPS implement continuations in a language/VM that doesn't natively provide them? The reason is that all function calls in CPS-transformed programs are tail calls, and so never return. The tricky part in implementing continuations is capturing the entire call stack so that when a continuation is resumed, it can return. Such a feature can only be added at the language implementation level. In the 1970's, InterLisp used "spaghetti stacks" to implement this: stack frames are garbage collected heap objects, pointing to parent frames. But what if functions don't do such a thing as returning? Then the need to add a spaghetti stack to the implementation goes away. Note that the spaghetti stack has not exactly gone away: we have something equivalent under CPS, namely chains of captured lexical environments. A continuation is a lambda, which captures the surrounding procedure's k parameter, which is itself a lambda that has captured its parent's k parameter, ... and so on: it's a chain of environments, similar to stack frames, in which the hidden k parameters are frame pointers. But the host language already gave us lexically capturing lambdas; we have just leveraged these lambdas to de facto represent the continuation spaghetti stack, and so we didn't have to go down to the implementation level to do anything.
How does one call a method object as a function?
Closer-mop and clos packages both provide method-function for turning a method object into a function. However, is there a way to do it without including another package? And if not, which package? (Using SBCL), but if a package is needed then how does the discrimination function do it?
Here is an example of using find-method to get a method object. The question is then how to call method-to-be-called.
(defclass a () ((x :accessor x :initform 0)))
(defgeneric inc (i))
(defmethod inc ((i a)) (incf (x i)))
(defvar r (make-instance 'a))
;; ... in a land far far away:
(defvar method-to-be-called (find-method #'inc '() '(a)))
(funcall method-to-be-called r);; crashes and burns
As a secondary question, the docs say that the discrimination function first tries to compute-applicable-methods-by-class to find a method object, and if that fails, it uses compute-applicable-methods. Why do this two layer approach? Is it correct to assume the find-method is doing this two layer approach, so it is better to use find-method ?
-- Appendix --
In the comments below Rainer Joswig pointed out that this find-method form is implementation dependent:
(find-method #'inc '() '(a))) ; works on sbcl 1.3.1
He says the specifier list should be classes and suggests instead:
(find-method #'inc '() (list (find-class 'a))))
So I thought to just put my class in there:
(find-method #'inc '() (list a)) ; crashes and burns
Apparently (defclass a ... ) does not set a to a class. In fact it doesn't set it to anything!
* (defclass a () ((x :accessor x :initform 0)))
#<STANDARD-CLASS COMMON-LISP-USER::A>
* a
...
The variable A is unbound.
However, this works:
* (defvar ca (defclass a () ((x :accessor x :initform 0))))
CA
* (defmethod inc ((i a)) (incf (x i)))
WARNING: Implicitly creating new generic function COMMON-LISP-USER::INC.
#<STANDARD-METHOD COMMON-LISP-USER::INC (A) {1005EE8263}>
enter code here
* (find-method #'inc '() (list ca))
#<STANDARD-METHOD COMMON-LISP-USER::INC (A) {1005EE8263}>
*
So a class is the return value from the defclass, not the value of the symbol that is provided to defclass.
(find-method #'inc '() '(a))
Above does not work. We need a list of classes, not a list of symbols.
(funcall (method-function (find-method #'inc
'()
(list (find-class 'a))))
r)
Since the function method-function belongs to the MOP, many implementations provide it and it is in some implementation specific package. CLOSER-MOP makes it available, too.
But usually, if you are already trying extracting method functions, then you are probably using CLOS the wrong way or you are really knowing what you are doing...
How does one call a method object as a function?
Honest question: why do you want to do that? Did you specify how the method's function is built in the first place, or not?
Even with closer-mop, I believe that the function returned by closer-mop:method-function is, at most, consistent with closer-mop:make-method-lambda in terms of its lambda-list, so perhaps you can use a package to know what you can count on portably.
A method's function does not have to be a function with the same lambda-list as the generic function, and usually it isn't due to next-method-p and call-next-method. Some implementations might use dynamic bindings for the next method list, so these might have a method lambda-list congruent with the generic function. Just don't count on it, generically.
I believe SBCL is not one of these implementations, the next method list is passed to the method's function to support next-method-p and call-next-method.
Why do this two layer approach?
Because it allows memoizing (or caching) based on the list of classes, when possible. If the generic function is called again with arguments of the same classes, and the generic function has not been updated (see "Dependent Maintenance Protocol" in the MOP), it can reuse the last result without further processing, for instance, by keeping the results in a hash table which keys are lists of classes.
However, if compute-applicable-methods-using-classes returns a false second value, then compute-applicable-methods is used. The reason is that no method could be found using classes alone, and this means some method has a non-class specializer.
This is different than saying there are no applicable methods, for instance, if all methods are specialized on classes and there are no applicable methods, compute-applicable-methods-using-classes should return an empty list and a true second value. There's no point in calling compute-applicable-methods, it won't (or rather, it shouldn't, if well implemented) find anything further.
It's still possible to perform memoization when compute-applicable-methods is used, but the memoization is no longer as trivial as, for instance, using a list of classes as a key in a hash table. Perhaps you could use a tree structure where you'd try to look up a method for each specializer (instance, then class) sequentially for each argument, until a tree node matched the whole specializable parameter list.
With non-standard specializers, you'd have to change the search order for each node. Unless such specializer's priority is not strictly before, between or after eql and a class, then you're in uncharted areas.
Actually, you'll have to change compute-applicable-methods-using-classes to recognize the non-standard specializers and return false early, and you'll have to change compute-applicable-methods to process these specializers, anyway, so perhaps you'll have a good knowledge on, if possible, how to memoize with the results of compute-applicable-methods anyway.
Is it correct to assume the find-method is doing this two layer approach, so it is better to use find-method ?
No, the purpose of find-method is to find a specific method, not an applicable method. It does not use compute-applicable-methods-using-classes or compute-applicable-methods at all. In fact, it couldn't use the latter ever, as it takes actual arguments instead of specializers.
For the particular case of method-function, closer-mop for SBCL simply reexport the existing symbol from sb-pcl, as seen in closer-mop-packages.lisp. The whole file make use of read-time conditionals (see 1.5.2.1 Use of Implementation-Defined Language Features).
That means that if you are working with SBCL, you might call sb-pcl:method-function (PCL means Portable Common Loops).
The generic function compute-applicable-methods-by-class allows you to know which methods are applicable given classes. This is useful if you don't have actual instances on which you can operate.
It seems also that compute-applicable-methods-using-classes allows the implementation to memoize the applicable methods when the second return value is true. This generic method does not allow you to find applicable methods specialized with eql specializers.
I am speculating here, but it makes sense to fall back on compute-applicable-methods to allow for example eql-specializers or because it is slightly easier to define a method for compute-applicable-methods.
Note the paragraph about consistency:
The following consistency relationship between compute-applicable-methods-using-classes and compute-applicable-methods must be maintained: for any given generic function and set of arguments, if compute-applicable-methods-using-classes returns a second value of true, the first value must be equal to the value that would be returned by a corresponding call to compute-applicable-methods. The results are undefined if a portable method on either of these generic functions causes this consistency to be violated.
I don't think there is a find-method-using-classes generic function specified anywhere.
I have been playing around with continuations in scheme (specifically guile) over the last couple of days and am a little puzzled by the results that some of the functions have and was wondering if anyone could explain exactly what is going on here.
There is a function called (get-token) that will retrieve the next found token in a given file. For example, if the next 3 tokens were "a", "b", and "c", calling (get-token) would return "a" the first time it is called, "b" the second time it is called, and "c" the third time it is called.
What I would like to do is have a function (peek-token) that will call (get-token), return the token, and then return to a state before the (get-token) function was called. I have attempted a number of different methods to achieve this result, and the one I currently have is:
;; make things a little easier to write
(define-syntax bind/cc
(syntax-rules ()
((bind/cc var . body)
(call/cc (lambda (var) . body)))))
;; function should return next token and then
;; revert to previous state
(define (peek-token)
(bind/cc return
(let ((token (get-token)))
(return token))))
How I understand it right now, the bind/cc will save a continuation at the first return and then execute the following block of code. Then when return is hit again, the program jumps back to where the continuation was bound and the token value is given as a result.
However, when I run the above function the results are exactly the same as the original (get-token) function.
I would be very grateful if anyone could explain where I am going wrong, or express a better way to get the same result (I know some people hate going the way of call/cc).
To hack a Mark Twain misquote to pieces: The reports of call/cc's capabilities are greatly exaggerated.
More specifically, call/cc captures call state, not program state. That means that it captures information about where the flow of code goes when the continuation is invoked. It does not capture information on variables, and in particular, if your get-token saves its iteration state by set!ting a variable, that is not going to be restored when you invoke your continuation.
In fact, your expression of (call/cc (lambda (k) (let ((token (get-token))) (k token)))) should behave identically to simply (get-token); there should not be any observable differences between the two expressions.
I need to implement a function of one argument -- obj -- that returns a Scheme expression that, when evaluated, will return a copy of obj.
Any ideas on how to proceed with the problem?
I'm guessing that you meant to write "a function expr-returning [that accepts an] obj [and] returns a Scheme expression that, when evaluated, ..."
Assuming this is the case: what you really need here is the design recipe. To begin with: write down examples of what your function accepts, and what it returns. This will clarify what you're trying to do, both to others and (probably more importantly) to yourself.
Hope this is helpful; sorry to be so opaque...
If you want your procedure to be able to duplicate any object, then the object could be any one of Scheme's basic types. By virtue of being different types, they have differing "natures," or structure, or what have you, and so making a copy of an object of one type is necessarily going to involve different strategies from making a copy of another object of a different type.
So how you approach this is to examine each of Scheme's types (or rather, the subset of Scheme's types you care about handling) and puzzle out what it means to duplicate an object of that type. If you do this in the obvious way, you should end up with a set of specialized procedures like COPY-NUMBER, COPY-SYMBOL, etc. (spoiler: a lot of these procedures aren't going to be very interesting.)
To unite these specialized procedures into a single one that can duplicate any object you give it reduces down to determining the object's real type and calling out to the COPY-FOO procedure to do the work (you could as well expand the procedure inline). You can organize this really easily with a COND and the type-determining predicates:
(define (copy-object obj)
(cond ((number? obj) (copy-number obj))
((boolean? obj) (copy-boolean obj))
...
))
This is a general design pattern for performing an operation on a datum regardless of its type called "dispatch on type." It's actually a pretty piss-poor way to do generic programming, not that that matters too much in this situation.
The last thing is the added wrinkle of returning a thing you can evaluate to get the copies. Might as well tell you what that is straight up: encapsulate a call to COPY-OBJECT inside a lambda-expression of no arguments:
(define (expr-returning obj)
(lambda () (copy-object obj)))
Then you can do stuff like
guile> (define x (list 1 2 3 4))
guile> (define y (expr-returning x))
guile> (define cx (y))
guile> x
(1 2 3 4)
guile> cx
(1 2 3 4)
guile> (set-cdr! x 'foo)
guile> x
(1 . foo)
guile> z
(1 2 3 4)
etc.
I am reading DrRacket document http://docs.racket-lang.org/guide/binding.html
There is a function
(define f
(lambda (append)
(define cons (append "ugly" "confusing"))
(let ([append 'this-was])
(list append cons))))
> (f list)
'(this-was ("ugly" "confusing"))
I see that we define function f, inside we define lambda that takes (append), why ?
Procedure (body) for lambda is another function called cons, that appends two strings.
I don't understand this function at all.
Thanks !
The section that you're referring to demonstrates lexical scope in Racket. As in other Scheme implementations, the main point is that you can "shadow" every binding in the language. Unlike most "mainstream" languages, there are no real keywords that are "sacred" in the sense that they can never be shadowed by a local binding.
Note that a really good tool to visualize what is bound where is DrRacket's "check syntax" button: click it, and you'll see your code with highlights that shows which parts are bindings, which are special forms -- and if you hover the mouse over a specific name, you'll see an arrow that tells you where it came from.
Scheme takes some getting used to :)
f is assigned the function returned by the lambda.
lambda defines the function that takes a parameter (called append).
(define cons (append "ugly" "confusing")) is not a function per se, but calls append with the two strings as parameter and assigns the result to cons.
inside the let block, append is re-assigned a different value, the symbol this-was.
the let block creates a list of append (which now contains 'this-was) and cons (which contains '("ugly" "confusing") from 3 above
since 5 is the last statement that value is returned by the whole function which is called f
f is called with the parameter list (the list function). which gets passed as the parameter append. And this is why 3 above creates a list '("ugly" "confusing") which gets assigned to cons.
Hope that cleared up things a bit.
Cheers!