Function evaluating to lambda cannot be used to define new function within scope - scheme

In scheme you can define functions which return a lambda expression and use them to define new functions. For example, you can write this code
(define (pow-iter base exp r)
(if (= exp 1)
r
(pow-iter base (- exp 1) (* base r))))
(define (pow exp)
(lambda (base)
(pow-iter base exp base)))
(define cubic (pow 3))
(cubic 2)
We have here a function pow which takes the exponent as argument and evaluates to a lambda function which evaluates to the nth power of the given base.
However, if we put that within a scope like this:
(define (do-cubic x)
(define (pow-iter base exp r)
(if (= exp 1)
r
(pow-iter base (- exp 1) (* base r))))
(define (pow exp)
(lambda (base)
(pow-iter base exp base)))
(define cubic (pow 3))
(cubic x))
(do-cubic 2)
I get an error
pow: undefined; cannot use before initialization
Why does this error occur and is there any way to fix it without changing the logic of the program?

This program provokes the same error:
#lang r5rs
(let ()
(define (foo x) (lambda (y) (+ 42 x)))
(define bar (foo 1))
(bar 2))
Output:
foo: undefined;
cannot use before initialization
The reason you get an error is that "internal definitions" are rewritten into a letrec expression all the bindings are in effect while their initial values are being computed, thus allowing mutually recursive definitions.
(letrec ((foo (lambda (x) (lambda (y) (+ 42 x))))
(bar (foo 1)))
(bar 2))
In R5RS the initialization expressions are evaluated in an unspecified order. This means that in the first snippet above it is possible for (define bar (foo 1)) to be evaluated before (define (foo x) ...). In other words the value of foo is needed before foo have been initialized.
In Racket (#lang racket) internal definitions use letrec*-semantics (i.e. the initialization expressions are evaluated in the order they appear in the code. Thus the program runs without errors.
Note also that the letrec in #lang racket corresponds to what letrec* does in "R5RS"-implementations.
For more information on letrec vs letrec* see the introduction of http://www.cs.indiana.edu/~dyb/pubs/letrec-reloaded.pdf

Related

Why does let not allow mutually recursive definitions, whereas letrec can?

I suspect that I fundamentally misunderstand Scheme's evaluation rules. What is it about the way that let and letrec are coded and evaluated that makes letrec able to accept mutually recursive definitions whereas let cannot? Appeals to their basic lambda forms may be helpful.
The following is even? without let or letrec:
(define even?
( (lambda (e o) <------. ------------.
(lambda (n) (e n e o)) -----* |
) |
(lambda (n e o) <------. <---+
(if (= n 0) #t (o (- n 1) e o))) -----* |
(lambda (n e o) <------. <---*
(if (= n 0) #f (e (- n 1) e o))))) -----*
This defines the name even? to refer to the result of evaluating the application of the object returned by evaluating the (lambda (e o) (lambda (n) (e n e o)) ) expression to two objects produced by evaluating the other two lambda expressions, the ones in the arguments positions.
Each of the argument lambda expressions is well formed, in particular there are no references to undefined names. Each only refers to its arguments.
The following is the same even?, written with let for convenience:
(define even?-let-
(let ((e (lambda (n e o) <------. <---.
(if (= n 0) #t (o (- n 1) e o)))) -----* |
(o (lambda (n e o) <------. <---+
(if (= n 0) #f (e (- n 1) e o)))) -----* |
) |
(lambda (n) (e n e o)) )) ----------------------------*
But what if we won't pass those e and o values around as arguments?
(define even?-let-wrong- ^ ^
(let ((e (lambda (n) <-----------------|--|-------.
(if (= n 0) #t (o (- n 1))))) --* | |
(o (lambda (n) | |
(if (= n 0) #f (e (- n 1))))) --* |
) |
(lambda (n) (e n)) )) ---------------------------*
What are the two names o and e inside the two lambda's if expressions refer to now?
They refer to nothing defined in this piece of code. They are "out of scope".
Why? It can be seen in the equivalent lambda-based expression, similar to what we've started with, above:
(define even?-wrong- ^ ^
( (lambda (e o) <----. ----|---|---------.
(lambda (n) (e n)) --* | | |
) | | |
(lambda (n) | | <------+
(if (= n 0) #t (o (- n 1)))) ---* | |
(lambda (n) | <------*
(if (= n 0) #f (e (- n 1)))))) -----*
This defines the name even?-wrong- to refer to the result of evaluating the application of the object returned by evaluating the (lambda (e o) (lambda (n) (e n)) ) expression to two objects produced by evaluating the other two lambda expressions, the ones in the arguments positions.
But each of them contains a free variable, a name which refers to nothing defined in its scope. One contains an undefined o, and the other contains an undefined e.
Why? Because in the application (<A> <B> <C>), each of the three expressions <A>, <B>, and <C> is evaluated in the same scope -- that in which the application itself appears; the enclosing scope. And then the resulting values are applied to each other (in other words, the function call is made).
A "scope" is simply a textual area in a code.
Yet we need the o in the first argument lambda to refer to the second argument lambda, not anything else (or even worse, nothing at all). Same with the e in the second argument lambda, which we need to point at the first argument lambda.
let evaluates its variables' init expressions in the enclosing scope of the whole let expression first, and then it creates a fresh environment frame with its variables' names bound to the values which result from those evaluations. The same thing happens with the equivalent three-lambdas expression evaluation.
letrec, on the other hand, first creates the fresh environment frame with its variables' names bound to as yet-undefined-values (such that referring to those values is guaranteed to result in an error) and then it evaluates its init expressions in this new self-referential frame, and then it puts the resulting values into the bindings for their corresponding names.
Which makes the names inside the lambda expressions refer to the names inside the whole letrec expression's scope. In contrast to the let's referring to the outer scope:
^ ^
| |
(let ((e | |
(... o ...)) |
(o |
(............ e .........)))
.....)
does not work;
.----------------.
| |
(letrec ((e <--|--------. |
(..... o ...)) | |
(o <-----------|-------*
(.............. e .........)))
.....)
works fine.
Here's an example to further clarify things:
1. consider ((lambda (a b) ....here a is 1.... (set! a 3) ....here a is 3....) 1 2)
now consider ((lambda (a b) .....) (lambda (x) (+ a x)) 2).
the two as are different -- the argument lambda is ill-defined.
now consider ((lambda (a b) ...(set! a (lambda (x) (+ a x))) ...) 1 2).
the two as are now the same.
so now it works.
let can't create mutually-recursive functions in any obvious way because you can always turn let into lambda:
(let ((x 1))
...)
-->
((λ (x)
...)
1)
and similarly for more than one binding:
(let ((x 1)
(y 2))
...)
-->
((λ (x y)
...)
1 2)
Here and below, --> means 'can be translated into' or even 'could be macroexpanded into'.
OK, so now consider the case where the x and y are functions:
(let ((x (λ (...) ...))
(y (λ (...) ...)))
...)
-->
((λ (x y)
...)
(λ (...) ...)
(λ (...) ...))
And now it's becoming fairly clear why this can't work for recursive functions:
(let ((x (λ (...) ... (y ...) ...))
(y (λ (...) ... (x ...) ...)))
...)
-->
((λ (x y)
...)
(λ (...) (y ...) ...)
(λ (...) (x ...) ...))
Well, let's make this more concrete to see what goes wrong: let's consider a single recursive function: if there's a problem with that then there certainly will be problems with sets of mutually recursive functions.
(let ((factorial (λ (n)
(if (= n 1) 1
(* n (factorial (- n 1)))))))
(factorial 10))
-->
((λ (factorial)
(factorial 10))
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
OK, what happens when you try to evaluate the form? We can use the environment model as described in SICP . In particular consider evaluating this form in an environment, e, in which there is no binding for factorial. Here's the form:
((λ (factorial)
(factorial 10))
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
Well, this is just a function application with a single argument, so to evaluate this you simply evaluate, in some order, the function form and its argument.
Start with the function form:
(λ (factorial)
(factorial 10))
This just evaluates to a function which, when called, will:
create an environment e' which extends e with a binding of factorial to the argument of the function;
call whatever is bound to factorial with the argument 10 and return the result.
So now we have to evaluate the argument, again in the environment e:
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1)))))
This evaluates to a function of one argument which, when called, will:
establish an environment e'' which extends e with a binding of n to the argument of the function;
if the argument isn't 1, will try to call some function bound to a variable called factorial, looking up this binding in e''.
Hold on: what function? There is no binding of factorial in e, and e'' extends e (in particular, e'' does not extend e'), but by adding a binding of n, not factorial. Thus there is no binding of factorial in e''. So this function is an error: you will either get an error when it's evaluated or you'll get an error when it's called, depending on how smart the implementation is.
Instead, you need to do something like this to make this work:
(let ((factorial (λ (n) (error "bad doom"))))
(set! factorial
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
(factorial 10))
-->
((λ (factorial)
(set! factorial
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
(factorial 10))
(λ (n) (error "bad doom")))
This will now work. Again, it's a function application, but this time all the action happens in the function:
(λ (factorial)
(set! factorial
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1))))))
(factorial 10))
So, evaluating this in e results in a function which, when called will:
create an environment e', extending e, in which there is a binding of factorial to whatever its argument is;
mutate the binding of factorial in e', assigning a different value to it;
call the value of factorial in e', with argument 10, returning the result.
So the interesting step is (2): the new value of factorial is the value of this form, evaluated in e':
(λ (n)
(if (= n 1) 1
(* n (factorial (- n 1)))
Well, this again is a function which, when called, will:
create an environent, e'', which extends e' (NOTE!) with a binding for n;
if the value of the binding of n is not 1, call whatever is bound to factorial in the e'' environment.
And now this will work, because there is a binding of factorial in e'', because, now, e'' extends e' and there is a binding of factorial in e'. And, further, by the time the function is called, e' will have been mutated so that the binding is the correct one: it's the function itself.
And this is in fact more-or-less how letrec is defined. In a form like
(letrec ((a <f1>)
(b <f2>))
...)
First the variables, a and b are bound to some undefined values (it is an error ever to refer to these values). Then <f1> and <f2> are evaluated in some order, in the resulting environment (this evaluation should not refer to the values that a and b have at that point), and the results of these evaluations are assigned to a and b respectively, mutating their bindings and finally the body is evaluated in the resulting environment.
See for instance R6RS (other reports are similar but harder to refer to as most of them are PDF):
The <variable>s are bound to fresh locations, the <init>s are evaluated in the resulting environment (in some unspecified order), each <variable> is assigned to the result of the corresponding <init>, the <body> is evaluated in the resulting environment, and the values of the last expression in <body> are returned. Each binding of a <variable> has the entire letrec expression as its region, making it possible to define mutually recursive procedures.
This is obviously something similar to what define must do, and in fact I think it's clear that, for internal define at least, you can always turn define into letrec:
(define (outer a)
(define (inner b)
...)
...)
-->
(define (outer a)
(letrec ((inner (λ (b) ...)))
...))
And perhaps this is the same as
(letrec ((outer
(λ (a)
(letrec ((inner
(λ (b)
...)))
...)))))
But I am not sure.
Of course, letrec buys you no computational power (neither does define): you can define recursive functions without it, it's just less convenient:
(let ((facter
(λ (c n)
(if (= n 1)
1
(* n (c c (- n 1)))))))
(let ((factorial
(λ (n)
(facter facter n))))
(factorial 10)))
or, for the pure of heart:
((λ (facter)
((λ (factorial)
(factorial 10))
(λ (n)
(facter facter n))))
(λ (c n)
(if (= n 1)
1
(* n (c c (- n 1))))))
This is pretty close to the U combinator, or I always think it is.
Finally, it's reasonably easy to write a quick-and-dirty letrec as a macro. Here's one called labels (see the comments to this answer):
(define-syntax labels
(syntax-rules ()
[(_ ((var init) ...) form ...)
(let ((var (λ x (error "bad doom"))) ...)
(set! var init) ...
form ...)]))
This will work for conforming uses, but it can't make referring to the initial bindings of the variables is an error: calling them is, but they can leak out. Racket, for instance, does some magic which makes this be an error.
Let's start with my version of everyone's favorite mutually recursive example, even-or-odd.
(define (even-or-odd x)
(letrec ((internal-even? (lambda (n)
(if (= n 0) 'even
(internal-odd? (- n 1)))))
(internal-odd? (lambda (n)
(if (= n 0) 'odd
(internal-even? (- n 1))))))
(internal-even? x)))
If you wrote that with let instead of letrec, you'd get an error that internal-even? in unbound. The descriptive reason for why that is is that the expressions that define the initial values in a let are evaluated in a lexical environment before the variables are bound whereas letrec creates an environment with those variables first, just to make this work.
Now we'll have a look at how to implement let and letrec with lambda so you can see why this might be.
The implementation of let is fairly straightforward. The general form is something like this:
(let ((x value)) body) --> ((lambda (x) body) value)
And so even-or-odd written with a let would become:
(define (even-or-odd-let x)
((lambda (internal-even? internal-odd?)
(internal-even? x))
(lambda (n)
(if (= n 0) 'even
(internal-odd? (- n 1))))
(lambda (n)
(if (= n 0) 'odd
(internal-even? (- n 1))))))
You can see that the bodies of internal-even? and internal-odd? are defined outside the scope of where those names are bound. It gets an error.
To deal with this problem when you want recursion to work, letrec does something like this:
(letrec (x value) body) --> ((lambda (x) (set! x value) body) #f)
[Note: There's probably a much better way of implementing letrec but that's what I'm coming up with off the top of my head. It'll give you the idea, anyway.]
And now even-or-odd? becomes:
(define (even-or-odd-letrec x)
((lambda (internal-even? internal-odd?)
(set! internal-even? (lambda (n)
(if (= n 0) 'even
(internal-odd? (- n 1)))))
(set! internal-odd? (lambda (n)
(if (= n 0) 'odd
(internal-even? (- n 1)))))
(internal-even? x))
#f #f))
Now internal-even? and internal-odd? are being used in a context where they've been bound and it all works.

Why Scheme requires apply in Y-combinator implementation, but Racket doesn't?

Here is the Y-combinator in Racket:
#lang lazy
(define Y (λ(f)((λ(x)(f (x x)))(λ(x)(f (x x))))))
(define Fact
(Y (λ(fact) (λ(n) (if (zero? n) 1 (* n (fact (- n 1))))))))
(define Fib
(Y (λ(fib) (λ(n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))))))
Here is the Y-combinator in Scheme:
(define Y
(lambda (f)
((lambda (x) (x x))
(lambda (g)
(f (lambda args (apply (g g) args)))))))
(define fac
(Y
(lambda (f)
(lambda (x)
(if (< x 2)
1
(* x (f (- x 1))))))))
(define fib
(Y
(lambda (f)
(lambda (x)
(if (< x 2)
x
(+ (f (- x 1)) (f (- x 2))))))))
(display (fac 6))
(newline)
(display (fib 6))
(newline)
My question is: Why does Scheme require the apply function but Racket does not?
Racket is very close to plain Scheme for most purposes, and for this example, they're the same. But the real difference between the two versions is the need for a delaying wrapper which is needed in a strict language (Scheme and Racket), but not in a lazy one (Lazy Racket, a different language).
That wrapper is put around the (x x) or (g g) -- what we know about this thing is that evaluating it will get you into an infinite loop, and we also know that it's going to be the resulting (recursive) function. Because it's a function, we can delay its evaluation with a lambda: instead of (x x) use (lambda (a) ((x x) a)). This works fine, but it has another assumption -- that the wrapped function takes a single argument. We could just as well wrap it with a function of two arguments: (lambda (a b) ((x x) a b)) but that won't work in other cases too. The solution is to use a rest argument (args) and use apply, therefore making the wrapper accept any number of arguments and pass them along to the recursive function. Strictly speaking, it's not required always, it's "only" required if you want to be able to produce recursive functions of any arity.
On the other hand, you have the Lazy Racket code, which is, as I said above, a different language -- one with call-by-need semantics. Since this language is lazy, there is no need to wrap the infinitely-looping (x x) expression, it's used as-is. And since no wrapper is required, there is no need to deal with the number of arguments, therefore no need for apply. In fact, the lazy version doesn't even need the assumption that you're generating a function value -- it can generate any value. For example, this:
(Y (lambda (ones) (cons 1 ones)))
works fine and returns an infinite list of 1s. To see this, try
(!! (take 20 (Y (lambda (ones) (cons 1 ones)))))
(Note that the !! is needed to "force" the resulting value recursively, since Lazy Racket doesn't evaluate recursively by default. Also, note the use of take -- without it, Racket will try to create that infinite list, which will not get anywhere.)
Scheme does not require apply function. you use apply to accept more than one argument.
in the factorial case, here is my implementation which does not require apply
;;2013/11/29
(define (Fact-maker f)
(lambda (n)
(cond ((= n 0) 1)
(else (* n (f (- n 1)))))))
(define (fib-maker f)
(lambda (n)
(cond ((or (= n 0) (= n 1)) 1)
(else
(+ (f (- n 1))
(f (- n 2)))))))
(define (Y F)
((lambda (procedure)
(F (lambda (x) ((procedure procedure) x))))
(lambda (procedure)
(F (lambda (x) ((procedure procedure) x))))))

Scheme - How do I return a function?

This function is displaying the correct thing, but how do I make the output of this function another function?
;;generate an Caesar Cipher single word encoders
;;INPUT:a number "n"
;;OUTPUT:a function, whose input=a word, output=encoded word
(define encode-n
(lambda (n);;"n" is the distance, eg. n=3: a->d,b->e,...z->c
(lambda (w);;"w" is the word to be encoded
(if (not (equal? (car w) '()))
(display (vtc (modulo (+ (ctv (car w)) n) 26)) ))
(if (not (equal? (cdr w) '()))
((encode-n n)(cdr w)) )
)))
You're already returning a function as output:
(define encode-n
(lambda (n)
(lambda (w) ; <- here, you're returning a function!
(if (not (equal? (car w) '()))
(display (vtc (modulo (+ (ctv (car w)) n) 26))))
(if (not (equal? (cdr w) '()))
((encode-n n)(cdr w))))))
Perhaps a simpler example will make things clearer. Let's define a procedure called adder that returns a function that adds a number n to whatever argument x is passed:
(define adder
(lambda (n)
(lambda (x)
(+ n x))))
The function adder receives a single parameter called n and returns a new lambda (an anonymous function), for example:
(define add-10 (adder 10))
In the above code we created a function called add-10 that, using adder, returns a new function which I named add-10, which in turn will add 10 to its parameter:
(add-10 32)
=> 42
We can obtain the same result without explicitly naming the returned function:
((adder 10) 32)
=> 42
There are other equivalent ways to write adder, maybe this syntax will be easier to understand:
(define (adder n)
(lambda (x)
(+ n x)))
Some interpreters allow an even shorter syntax that does exactly the same thing:
(define ((adder n) x)
(+ n x))
I just demonstrated examples of currying and partial application - two related but different concepts, make sure you understand them and don't let the syntax confound you.

Scheme letrec infinite environment

I'm currently writing metacircular evaluator in Scheme, following the SICP book's steps.
In the exercise I am asked to implement letrec, which I do in the following way:
(define (letrec->let exp)
(define (make-unassigned var)
(list var '*unassigned*))
(define (make-assign binding)
(list 'set! (letrec-binding-var binding)
(letrec-binding-val binding)))
(let ((orig-bindings (letrec-bindings exp)))
(make-let
(map make-unassigned
(map letrec-binding-var orig-bindings))
(sequence->exp
(append
(map make-assign orig-bindings)
(letrec-body exp))))))
However, when I evaluate the expression as follows, it goes into infinite loop:
(letrec
((a (lambda () 1)))
(+ 1 (a)))
Do I miss anything?
(Full Source Code at GitHub).
I checked result transformation result of (let ((x 1)) x) and got:
((lambda (x) (x)) 1)
instead of:
((lambda (x) x) 1)
obviously problem is in let body processing. If I were you, I would use utility function:
(define (implicit-begin exps)
(if (= 1 (length x))
(car x)
(cons 'begin x)))
By the way: I would say, that your letrec implementation is not very correct. Your transformation returns:
(let ((x1 *unassigned*>) ... (xn *unassigned*))
(set! x1 ...)
...
(set! xn ...)
body)
It much more resembles letrec* which evaluates expressions for variable bindings in left-ro-right order (Scheme itself doesn't specify arguments evaluation order):
syntax: letrec* bindings body
Similar to ‘letrec’, except the INIT expressions are bound to their
variables in order.
‘letrec*’ thus relaxes the letrec restriction, in that later INIT
expressions may refer to the values of previously bound variables.
The more correct code would be:
(let ((x1 *unassigned*) ... (xn *unassigned*))
(let ((t1 ...) ... (tn ...))
(set! x1 t1)
...
(set! xn tn))
body)

Anonymous lambdas directly referring to themselves

Does Scheme or do any dialects of scheme have a kind of "self" operator so that anonymous lambdas can recur on themselves without doing something like a Y-combinator or being named in a letrec etc.
Something like:
(lambda (n)
(cond
((= n 0) 1)
(else (* n (self (- n 1)))))))
No. The trouble with the "current lambda" approach is that Scheme has many hidden lambdas. For example:
All the let forms (including let*, letrec, and named let)
do (which expands to a named let)
delay, lazy, receive, etc.
To require the programmer to know what the innermost lambda is would break encapsulation, in that you'd have to know where all the hidden lambdas are, and macro writers can no longer use lambdas as a way to create a new scope.
All-round lose, if you ask me.
There is a tradition of writing “anaphoric” macros that define special names in the lexical scope of their bodies. Using syntax-case, you can write such a macro on top of letrec and lambda. Note that the definition below is as hygienic as possible considering the specification (in particular, invisible uses of alambda will not shadow self).
;; Define a version of lambda that binds the
;; anaphoric variable “self” to the function
;; being defined.
;;
;; Note the use of datum->syntax to specify the
;; scope of the anaphoric identifier.
(define-syntax alambda
(lambda (stx)
(syntax-case stx ()
[(alambda lambda-list . body)
(with-syntax ([name (datum->syntax #'alambda 'self)])
#'(letrec ([name (lambda lambda-list . body)])
name))])))
;; We can define let in terms of alambda as usual.
(define-syntax let/alambda
(syntax-rules ()
[(_ ((var val) ...) . body)
((alambda (var ...) . body) val ...)]))
;; The let/alambda macro does not shadow the outer
;; alambda's anaphoric variable, which is lexical
;; with regard to the alambda form.
((alambda (n)
(if (zero? n)
1
(let/alambda ([n-1 (- n 1)])
(* (self n-1) n))))
10)
;=> 3628800
Most people avoid anaphoric operators since they make the structure of the code less recognizable. In addition, refactoring can introduce problems rather easily. (Consider what happens when you wrap the let/alambda form in the factorial function above in another alambda form. It's easy to overlook uses of self, especially if you're not reminded of it being relevant by having to type it explicitly.) It is therefore generally preferable to use explicit names. A “labeled” version of lambda that allows this can be defined using a simple syntax-rules macro:
;; Define a version of lambda that allows the
;; user to specifiy a name for the function
;; being defined.
(define-syntax llambda
(syntax-rules ()
[(_ name lambda-list . body)
(letrec ([name (lambda lambda-list . body)])
name)]))
;; The factorial function can be expressed
;; using llambda.
((llambda fac (n)
(if (zero? n)
1
(* (fac (- n 1)) n)))
10)
;=> 3628800
I have found a way using continuations to have anonymous lambdas call themselves and then using Racket macros to disguise the syntax so the anonymous lambda appears to have a "self" operator. I don't know if this solution is possible in other versions of Scheme since it depends on the Call-with-composable-continuation function of racket and the Macro to hide the syntax uses syntax parameters.
The basic idea is this, illustrated with the factorial function.
( (lambda (n)
(call-with-values
(lambda () (call-with-composable-continuation
(lambda (k) (values k n))))
(lambda (k n)
(cond
[(= 0 n) 1]
[else (* n (k k (- n 1)))])))) 5)
The continuation k is the call to the anonymous factorial function, which takes two arguments, the first being the continuation itself. So that when in the body we execute (k k N) that is equivalent to the anonymous function calling itself (in the same way that a recursive named lambda would do).
We then disguise the underlying form with a macro. Rackets syntax-parameters allow the transformation of (self ARGS ...) to (k k ARGS ... )
so we can have:
((lambda-with-self (n)
(cond
[(= 0 n) 0]
[(= 1 n) 1]
[else (* n (self (- n 1)))])) 5)
The complete Racket program to do this is:
#lang racket
(require racket/stxparam) ;required for syntax-parameters
( define-syntax-parameter self (λ (stx) (raise-syntax-error #f "not in `lambda-with-self'" stx)))
(define-syntax-rule
(lambda-with-self (ARG ... ) BODY ...)
(lambda (ARG ...)
(call-with-values
(lambda ()(call/comp (lambda (k) (values k ARG ...))))
(lambda (k ARG ...)
(syntax-parameterize ([self (syntax-rules ( )[(self ARG ...) (k k ARG ...)])])
BODY ...)))))
;Example using factorial function
((lambda-with-self (n)
(cond
[(= 0 n) 0]
[(= 1 n) 1]
[else (* n (self (- n 1)))])) 5)
This also answers my previous question about the differences between the different kinds of continuations.
Different kinds of continuations in Racket
This only works because unlike call-with-current-continuation, call-with-composable-continuation doesn't abort back to a continuation prompt but invokes the continuation at the place it was invoked.

Resources