Closures/Value capture: Difference between revisions

→‎Desugared: Adding continuation-based solution.
(→‎{{header|TXR}}: Add desugared version.)
(→‎Desugared: Adding continuation-based solution.)
Line 1,388:
(mapcar (lambda ()
(lambda () (* x x))) '(1 2 3 4 5 6 7 8 9 10)))</lang>
 
====Delimited Continuations====
 
In this interactive example, we capture delimited continuations inside a simple <code>for</code> loop. Because the variable binding environment is not necessarily in the stack which is captured, we rebind the loop variable.
 
<pre>This is the TXR Lisp interactive listener of TXR 124.
Use the :quit command or type Ctrl-D on empty line to exit.
1> (let ((conts))
(for ((i 0)) ((< i 10) (nreverse conts)) ((inc i))
(let ((cap i))
(push (block sqr
(suspend sqr f (op f nil))
(* cap cap))
conts))))
(#<interpreted fun: lambda #:rest-0112> #<interpreted fun: lambda #:rest-0112>
#<interpreted fun: lambda #:rest-0112> #<interpreted fun: lambda #:rest-0112>
#<interpreted fun: lambda #:rest-0112> #<interpreted fun: lambda #:rest-0112>
#<interpreted fun: lambda #:rest-0112> #<interpreted fun: lambda #:rest-0112>
#<interpreted fun: lambda #:rest-0112> #<interpreted fun: lambda #:rest-0112>)
2> (call (first *1))
0
3> (call (second *1))
1
4> (call (fifth *1))
16
5> (call [*1 4]))
16
6> (call [*1 7]))
49</pre>
 
The <code>suspend<code> operator suspends the execution of the <code>sqr</code> block, causing it to return the function <code>(op f nil)</code>. The variable <code>f</code> represents the captured continuation as a function. Continuation functions take one mandatory argument. We don't need that here, hence the <code>(op f nil)</code> expression is returned: it curries the one arg continuation function <code>f</code> to a function with no arguments.
 
The loop pushes these suspended continuations into a list, and then <code>nreverse<code>-s it.
 
We then interactively call the continuations in the list.
 
Whenever we call a continuation, the <code>(block sqr ...)</code> environment is restored. and the suspended computation inside the block resumes by returning out of the <code>(suspend ...)</code> form normally. The block then executes to completion, returning the <code>(* cap cap)</code> form's value. At that point, our call to the continuation terminates, yielding that value.
 
=={{header|zkl}}==
543

edits