Closures/Value capture: Difference between revisions
Content added Content deleted
(→{{header|TXR}}: Add desugared version.) |
(→Desugared: Adding continuation-based solution.) |
||
Line 1,388: | Line 1,388: | ||
(mapcar (lambda () |
(mapcar (lambda () |
||
(lambda () (* x x))) '(1 2 3 4 5 6 7 8 9 10)))</lang> |
(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}}== |
=={{header|zkl}}== |