Closures/Value capture: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 17: | Line 17: | ||
=={{header|11l}}== |
=={{header|11l}}== |
||
< |
<syntaxhighlight lang="11l">[(() -> Int)] funcs |
||
L(i) 10 |
L(i) 10 |
||
funcs.append(() -> @=i * @=i) |
funcs.append(() -> @=i * @=i) |
||
print(funcs[3]())</ |
print(funcs[3]())</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 31: | Line 31: | ||
One way to realize closures in Ada is the usage of protected objects. |
One way to realize closures in Ada is the usage of protected objects. |
||
< |
<syntaxhighlight lang="Ada">with Ada.Text_IO; |
||
procedure Value_Capture is |
procedure Value_Capture is |
||
Line 60: | Line 60: | ||
Ada.Text_IO.Put(Integer'Image(A(I).Result)); |
Ada.Text_IO.Put(Integer'Image(A(I).Result)); |
||
end loop; |
end loop; |
||
end Value_Capture;</ |
end Value_Capture;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 68: | Line 68: | ||
{{works with|ALGOL 68G|2.8}} |
{{works with|ALGOL 68G|2.8}} |
||
< |
<syntaxhighlight lang="algol68"> |
||
[1:10]PROC(BOOL)INT squares; |
[1:10]PROC(BOOL)INT squares; |
||
Line 81: | Line 81: | ||
FOR i FROM 1 TO 10 DO print(squares[i](FALSE)) OD |
FOR i FROM 1 TO 10 DO print(squares[i](FALSE)) OD |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 91: | Line 91: | ||
=={{header|AntLang}}== |
=={{header|AntLang}}== |
||
< |
<syntaxhighlight lang="AntLang">fns: {n: x; {n expt 2}} map range[10] |
||
(8 elem fns)[]</ |
(8 elem fns)[]</syntaxhighlight> |
||
=={{header|AppleScript}}== |
=={{header|AppleScript}}== |
||
{{trans|JavaScript}} |
{{trans|JavaScript}} |
||
< |
<syntaxhighlight lang="AppleScript">on run |
||
set fns to {} |
set fns to {} |
||
Line 112: | Line 112: | ||
end |λ| |
end |λ| |
||
end script |
end script |
||
end closure</ |
end closure</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>9</pre> |
<pre>9</pre> |
||
Line 118: | Line 118: | ||
Or, in a more functional pattern of composition: |
Or, in a more functional pattern of composition: |
||
< |
<syntaxhighlight lang="AppleScript">-- CLOSURE -------------------------------------------------------------------- |
||
script closure |
script closure |
||
Line 171: | Line 171: | ||
end script |
end script |
||
end if |
end if |
||
end mReturn</ |
end mReturn</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>9</pre> |
<pre>9</pre> |
||
Line 177: | Line 177: | ||
=={{header|Axiom}}== |
=={{header|Axiom}}== |
||
Using the Spad compiler: |
Using the Spad compiler: |
||
< |
<syntaxhighlight lang="Axiom">)abbrev package TESTP TestPackage |
||
TestPackage() : with |
TestPackage() : with |
||
test: () -> List((()->Integer)) |
test: () -> List((()->Integer)) |
||
== add |
== add |
||
test() == [(() +-> i^2) for i in 1..10]</ |
test() == [(() +-> i^2) for i in 1..10]</syntaxhighlight> |
||
This can be called from the interpreter using: |
This can be called from the interpreter using: |
||
< |
<syntaxhighlight lang="Axiom">[x() for x in test()]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="Axiom">[1,4,9,16,25,36,49,64,81,100] |
||
Type: List(Integer)</ |
Type: List(Integer)</syntaxhighlight> |
||
=={{header|Babel}}== |
=={{header|Babel}}== |
||
< |
<syntaxhighlight lang="babel">((main { |
||
{ iter |
{ iter |
||
1 take bons 1 take |
1 take bons 1 take |
||
Line 201: | Line 201: | ||
10 times |
10 times |
||
collect ! |
collect ! |
||
{eval %d nl <<} each }))</ |
{eval %d nl <<} each }))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="babel">100 |
||
81 |
81 |
||
64 |
64 |
||
Line 213: | Line 213: | ||
9 |
9 |
||
4 |
4 |
||
1</ |
1</syntaxhighlight> |
||
Essentially, a function has been constructed for each value to be squared (10 down to 1). The cp operator ensures that we generate a fresh copy of the number to be squared, as well as the code for multiplying, {*}. |
Essentially, a function has been constructed for each value to be squared (10 down to 1). The cp operator ensures that we generate a fresh copy of the number to be squared, as well as the code for multiplying, {*}. |
||
Line 219: | Line 219: | ||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
< |
<syntaxhighlight lang="bracmat">( -1:?i |
||
& :?funcs |
& :?funcs |
||
& whl |
& whl |
||
Line 227: | Line 227: | ||
& whl'(!funcs:%?func %?funcs&out$(!func$)) |
& whl'(!funcs:%?func %?funcs&out$(!func$)) |
||
); |
); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>0 |
<pre>0 |
||
Line 245: | Line 245: | ||
Non-portable. Copying a function body depends on implementation-specific semantics of volatile, if the replacement target still exists after optimization, if the dest memory is suitably aligned, if the memory is executable, if it makes any function calls to a relative offset, if it refers to any memory location with an absolute address, etc. It only very occasionally works. |
Non-portable. Copying a function body depends on implementation-specific semantics of volatile, if the replacement target still exists after optimization, if the dest memory is suitably aligned, if the memory is executable, if it makes any function calls to a relative offset, if it refers to any memory location with an absolute address, etc. It only very occasionally works. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <string.h> |
#include <string.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 285: | Line 285: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<lang>func[0]: 0 |
<syntaxhighlight lang="text">func[0]: 0 |
||
func[1]: 1 |
func[1]: 1 |
||
func[2]: 4 |
func[2]: 4 |
||
Line 295: | Line 295: | ||
func[6]: 36 |
func[6]: 36 |
||
func[7]: 49 |
func[7]: 49 |
||
func[8]: 64</ |
func[8]: 64</syntaxhighlight> |
||
===Greenspunned mini Lisp dialect=== |
===Greenspunned mini Lisp dialect=== |
||
Line 301: | Line 301: | ||
See [[Closures/Variable_capture/C]] for complete code. The relevant excerpt is: |
See [[Closures/Variable_capture/C]] for complete code. The relevant excerpt is: |
||
< |
<syntaxhighlight lang="c">void init(void) |
||
{ |
{ |
||
t = intern(lit("t")); |
t = intern(lit("t")); |
||
Line 333: | Line 333: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
Here, we create an environment explicitly as an association list |
Here, we create an environment explicitly as an association list |
||
Line 356: | Line 356: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
===Using Linq=== |
===Using Linq=== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Linq; |
using System.Linq; |
||
Line 370: | Line 370: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<lang>0 |
<syntaxhighlight lang="text">0 |
||
1 |
1 |
||
4 |
4 |
||
Line 380: | Line 380: | ||
36 |
36 |
||
49 |
49 |
||
64</ |
64</syntaxhighlight> |
||
===Using delegates only=== |
===Using delegates only=== |
||
< |
<syntaxhighlight lang="csharp"> |
||
using System; |
using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
Line 407: | Line 407: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<lang>0 |
<syntaxhighlight lang="text">0 |
||
1 |
1 |
||
4 |
4 |
||
Line 417: | Line 417: | ||
36 |
36 |
||
49 |
49 |
||
64</ |
64</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
{{works with|C++11}} |
{{works with|C++11}} |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <functional> |
#include <functional> |
||
#include <vector> |
#include <vector> |
||
Line 432: | Line 432: | ||
std::cout << f( ) << std::endl ; |
std::cout << f( ) << std::endl ; |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>0 |
<pre>0 |
||
Line 447: | Line 447: | ||
=={{header|Ceylon}}== |
=={{header|Ceylon}}== |
||
< |
<syntaxhighlight lang="ceylon">shared void run() { |
||
//create a list of closures with a list comprehension |
//create a list of closures with a list comprehension |
||
Line 455: | Line 455: | ||
print("closure number ``i`` returns: ``closure()``"); |
print("closure number ``i`` returns: ``closure()``"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="clojure">(def funcs (map #(fn [] (* % %)) (range 11))) |
||
(printf "%d\n%d\n" ((nth funcs 3)) ((nth funcs 4)))</ |
(printf "%d\n%d\n" ((nth funcs 3)) ((nth funcs 4)))</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>9 |
<pre>9 |
||
Line 466: | Line 466: | ||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
< |
<syntaxhighlight lang="coffeescript"> |
||
# Generate an array of functions. |
# Generate an array of functions. |
||
funcs = ( for i in [ 0...10 ] then do ( i ) -> -> i * i ) |
funcs = ( for i in [ 0...10 ] then do ( i ) -> -> i * i ) |
||
Line 472: | Line 472: | ||
# Call each function to demonstrate value capture. |
# Call each function to demonstrate value capture. |
||
console.log func() for func in funcs |
console.log func() for func in funcs |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">CL-USER> (defparameter alist |
||
(loop for i from 1 to 10 |
(loop for i from 1 to 10 |
||
collect (cons i (let ((i i)) |
collect (cons i (let ((i i)) |
||
Line 483: | Line 483: | ||
4 |
4 |
||
CL-USER> (funcall (cdr (assoc 8 alist))) |
CL-USER> (funcall (cdr (assoc 8 alist))) |
||
64</ |
64</syntaxhighlight> |
||
The ''loop'' mutates its binding ''i''. The purpose of <code>(let ((i i)) ...)</code> is to create a different binding ''i'' for each ''lambda'' to capture. Otherwise, all 10 lambdas would capture the same binding and return 100. |
The ''loop'' mutates its binding ''i''. The purpose of <code>(let ((i i)) ...)</code> is to create a different binding ''i'' for each ''lambda'' to capture. Otherwise, all 10 lambdas would capture the same binding and return 100. |
||
Line 489: | Line 489: | ||
=={{header|D}}== |
=={{header|D}}== |
||
===Less Functional Version=== |
===Less Functional Version=== |
||
< |
<syntaxhighlight lang="d">import std.stdio; |
||
void main() { |
void main() { |
||
Line 498: | Line 498: | ||
writeln(funcs[3]()); |
writeln(funcs[3]()); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>9</pre> |
<pre>9</pre> |
||
===More Functional Version=== |
===More Functional Version=== |
||
< |
<syntaxhighlight lang="d">void main() { |
||
import std.stdio, std.range, std.algorithm; |
import std.stdio, std.range, std.algorithm; |
||
10.iota.map!(i => () => i ^^ 2).map!q{ a() }.writeln; |
10.iota.map!(i => () => i ^^ 2).map!q{ a() }.writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</pre> |
<pre>[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</pre> |
||
Line 512: | Line 512: | ||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
{{works with|Delphi 2009}} |
{{works with|Delphi 2009}} |
||
< |
<syntaxhighlight lang="Delphi">program Project1; |
||
type |
type |
||
Line 538: | Line 538: | ||
for i := Low(Funcs) to High(Funcs) do |
for i := Low(Funcs) to High(Funcs) do |
||
Writeln(Funcs[i]()); |
Writeln(Funcs[i]()); |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>0 |
<pre>0 |
||
Line 555: | Line 555: | ||
Dyalect captures variables by reference, therefore a way to achieve this is to capture a variable through a closure which in its turn returns a anonymous function like so: |
Dyalect captures variables by reference, therefore a way to achieve this is to capture a variable through a closure which in its turn returns a anonymous function like so: |
||
< |
<syntaxhighlight lang="dyalect">var xs = [] |
||
let num = 10 |
let num = 10 |
||
Line 564: | Line 564: | ||
for x in xs { |
for x in xs { |
||
print(x()) |
print(x()) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 582: | Line 582: | ||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
(define (fgen i) (lambda () (* i i))) |
(define (fgen i) (lambda () (* i i))) |
||
(define fs (for/vector ((i 10)) (fgen i))) ;; vector of 10 anonymous functions |
(define fs (for/vector ((i 10)) (fgen i))) ;; vector of 10 anonymous functions |
||
((vector-ref fs 5)) ;; calls fs[5] |
((vector-ref fs 5)) ;; calls fs[5] |
||
→ 25 |
→ 25 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
ELENA 4.1 : |
ELENA 4.1 : |
||
< |
<syntaxhighlight lang="elena">import system'routines; |
||
import extensions; |
import extensions; |
||
Line 599: | Line 599: | ||
functions.forEach:(func) { console.printLine(func()) } |
functions.forEach:(func) { console.printLine(func()) } |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>0 |
<pre>0 |
||
Line 613: | Line 613: | ||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
< |
<syntaxhighlight lang="elixir">funs = for i <- 0..9, do: (fn -> i*i end) |
||
Enum.each(funs, &IO.puts &1.())</ |
Enum.each(funs, &IO.puts &1.())</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 633: | Line 633: | ||
As of Emacs 24.3, lexical closures are supported, therefore alleviating hacks such as lexical-let. |
As of Emacs 24.3, lexical closures are supported, therefore alleviating hacks such as lexical-let. |
||
< |
<syntaxhighlight lang="lisp">;; -*- lexical-binding: t; -*- |
||
(mapcar #'funcall |
(mapcar #'funcall |
||
(mapcar (lambda (x) |
(mapcar (lambda (x) |
||
Line 639: | Line 639: | ||
(* x x))) |
(* x x))) |
||
'(1 2 3 4 5 6 7 8 9 10))) |
'(1 2 3 4 5 6 7 8 9 10))) |
||
;; => (1 4 9 16 25 36 49 64 81 100)</ |
;; => (1 4 9 16 25 36 49 64 81 100)</syntaxhighlight> |
||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Erlang uses lexical scoping and has anonymous functions. |
Erlang uses lexical scoping and has anonymous functions. |
||
< |
<syntaxhighlight lang="erlang"> |
||
-module(capture_demo). |
-module(capture_demo). |
||
-export([demo/0]). |
-export([demo/0]). |
||
Line 657: | Line 657: | ||
io:fwrite("~B~n",[F()]) |
io:fwrite("~B~n",[F()]) |
||
end, Funs). |
end, Funs). |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
1> capture_demo:demo(). |
1> capture_demo:demo(). |
||
Line 675: | Line 675: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
Nearly identical to OCaml |
Nearly identical to OCaml |
||
< |
<syntaxhighlight lang="fsharp">[<EntryPoint>] |
||
let main argv = |
let main argv = |
||
let fs = List.init 10 (fun i -> fun () -> i*i) |
let fs = List.init 10 (fun i -> fun () -> i*i) |
||
do List.iter (fun f -> printfn "%d" <| f()) fs |
do List.iter (fun f -> printfn "%d" <| f()) fs |
||
0</ |
0</syntaxhighlight> |
||
With List.map |
With List.map |
||
< |
<syntaxhighlight lang="fsharp">[<EntryPoint>] |
||
let main argv = |
let main argv = |
||
let fs = List.map (fun i -> fun () -> i*i) [0..9] |
let fs = List.map (fun i -> fun () -> i*i) [0..9] |
||
do List.iter (fun f -> printfn "%d" <| f()) fs |
do List.iter (fun f -> printfn "%d" <| f()) fs |
||
0</ |
0</syntaxhighlight> |
||
With List.mapi |
With List.mapi |
||
< |
<syntaxhighlight lang="fsharp">[<EntryPoint>] |
||
let main argv = |
let main argv = |
||
let fs = List.mapi (fun i x -> fun () -> i*i) (List.replicate 10 None) |
let fs = List.mapi (fun i x -> fun () -> i*i) (List.replicate 10 None) |
||
do List.iter (fun f -> printfn "%d" <| f()) fs |
do List.iter (fun f -> printfn "%d" <| f()) fs |
||
0</ |
0</syntaxhighlight> |
||
With an infinite sequence |
With an infinite sequence |
||
< |
<syntaxhighlight lang="fsharp">[<EntryPoint>] |
||
let main argv = |
let main argv = |
||
let fs = Seq.initInfinite (fun i -> fun () -> i*i) |
let fs = Seq.initInfinite (fun i -> fun () -> i*i) |
||
do Seq.iter (fun f -> printfn "%d" <| f()) (Seq.take 10 fs) |
do Seq.iter (fun f -> printfn "%d" <| f()) (Seq.take 10 fs) |
||
0</ |
0</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 718: | Line 718: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
===Using lexical variables=== |
===Using lexical variables=== |
||
< |
<syntaxhighlight lang="factor">USING: io kernel locals math prettyprint sequences ; |
||
[let |
[let |
||
Line 731: | Line 731: | ||
seq nth call . |
seq nth call . |
||
] each |
] each |
||
]</ |
]</syntaxhighlight> |
||
<pre>$ ./factor script.factor |
<pre>$ ./factor script.factor |
||
Line 744: | Line 744: | ||
Forget the variable! Each ''fried quotation'' captures some values by pulling them from the stack. |
Forget the variable! Each ''fried quotation'' captures some values by pulling them from the stack. |
||
< |
<syntaxhighlight lang="factor">USING: fry io kernel math prettyprint sequences ; |
||
! Push a sequence of 10 quotations |
! Push a sequence of 10 quotations |
||
Line 755: | Line 755: | ||
over nth call . |
over nth call . |
||
] each |
] each |
||
drop</ |
drop</syntaxhighlight> |
||
=={{header|Fantom}}== |
=={{header|Fantom}}== |
||
< |
<syntaxhighlight lang="fantom"> |
||
class Closures |
class Closures |
||
{ |
{ |
||
Line 777: | Line 777: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 785: | Line 785: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
< |
<syntaxhighlight lang="forth">: xt-array here { a } |
||
10 cells allot 10 0 do |
10 cells allot 10 0 do |
||
:noname i ]] literal dup * ; [[ a i cells + ! |
:noname i ]] literal dup * ; [[ a i cells + ! |
||
loop a ; |
loop a ; |
||
xt-array 5 cells + @ execute .</ |
xt-array 5 cells + @ execute .</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<lang |
<syntaxhighlight lang="forth">25</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
Line 800: | Line 800: | ||
FreeBASIC doesn't support closures or anonymous methods, as such. However, what we can do is to create an array of objects to capture their index and then call a method on those objects which squares the index. This approach is similar to how some other object oriented languages implement closures 'under the hood'. |
FreeBASIC doesn't support closures or anonymous methods, as such. However, what we can do is to create an array of objects to capture their index and then call a method on those objects which squares the index. This approach is similar to how some other object oriented languages implement closures 'under the hood'. |
||
< |
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
||
Type Closure |
Type Closure |
||
Line 832: | Line 832: | ||
Print |
Print |
||
Print "Press any key to quit" |
Print "Press any key to quit" |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 848: | Line 848: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 862: | Line 862: | ||
fmt.Println("func #0:", fs[0]()) |
fmt.Println("func #0:", fs[0]()) |
||
fmt.Println("func #3:", fs[3]()) |
fmt.Println("func #3:", fs[3]()) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 871: | Line 871: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
Solution: |
Solution: |
||
< |
<syntaxhighlight lang="groovy">def closures = (0..9).collect{ i -> { -> i*i } }</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="groovy">assert closures instanceof List |
||
assert closures.size() == 10 |
assert closures.size() == 10 |
||
closures.each { assert it instanceof Closure } |
closures.each { assert it instanceof Closure } |
||
println closures[7]()</ |
println closures[7]()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 886: | Line 886: | ||
Using <code>map</code>: |
Using <code>map</code>: |
||
< |
<syntaxhighlight lang="haskell">fs = map (\i _ -> i * i) [1 .. 10]</syntaxhighlight> |
||
Using list comprehensions: |
Using list comprehensions: |
||
< |
<syntaxhighlight lang="haskell">fs = [const $ i * i | i <- [1 .. 10]]</syntaxhighlight> |
||
Using infinite lists: |
Using infinite lists: |
||
< |
<syntaxhighlight lang="haskell">fs = take 10 coFs where coFs = [const $ i * i | i <- [1 ..]]</syntaxhighlight> |
||
Testing: |
Testing: |
||
< |
<syntaxhighlight lang="haskell">> :t fs |
||
fs :: [b -> Integer] |
fs :: [b -> Integer] |
||
> map ($ ()) fs |
> map ($ ()) fs |
||
Line 905: | Line 905: | ||
100 |
100 |
||
> fs !! 8 $ undefined |
> fs !! 8 $ undefined |
||
81</ |
81</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
This uses Unicon specific calling sequences for co-expressions. It can be made to run under Icon by modifying the calling syntax. |
This uses Unicon specific calling sequences for co-expressions. It can be made to run under Icon by modifying the calling syntax. |
||
< |
<syntaxhighlight lang="Unicon">procedure main(args) # Closure/Variable Capture |
||
every put(L := [], vcapture(1 to 10)) # build list of index closures |
every put(L := [], vcapture(1 to 10)) # build list of index closures |
||
write("Randomly selecting L[",i := ?*L,"] = ",L[i]()) # L[i]() calls the closure |
write("Randomly selecting L[",i := ?*L,"] = ",L[i]()) # L[i]() calls the closure |
||
Line 924: | Line 924: | ||
procedure makeProc(A) # the makeProc PDCO from the UniLib Utils package |
procedure makeProc(A) # the makeProc PDCO from the UniLib Utils package |
||
return (@A[1], A[1]) |
return (@A[1], A[1]) |
||
end</ |
end</syntaxhighlight> |
||
{{libheader|Unicon Code Library}} |
{{libheader|Unicon Code Library}} |
||
Line 935: | Line 935: | ||
=={{header|Io}}== |
=={{header|Io}}== |
||
<lang>blist := list(0,1,2,3,4,5,6,7,8,9) map(i,block(i,block(i*i)) call(i)) |
<syntaxhighlight lang="text">blist := list(0,1,2,3,4,5,6,7,8,9) map(i,block(i,block(i*i)) call(i)) |
||
writeln(blist at(3) call) // prints 9</ |
writeln(blist at(3) call) // prints 9</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Line 944: | Line 944: | ||
The natural way of implementing this in J is to define a function which produces a gerund of a constant function. |
The natural way of implementing this in J is to define a function which produces a gerund of a constant function. |
||
< |
<syntaxhighlight lang="j">constF=:3 :0 |
||
{.''`(y "_) |
{.''`(y "_) |
||
)</ |
)</syntaxhighlight> |
||
Thus, a list of 10 functions each producing a value in 0..9, and another with their squares: |
Thus, a list of 10 functions each producing a value in 0..9, and another with their squares: |
||
< |
<syntaxhighlight lang="j">flist=: constF"0 i.10 |
||
slist=: constF"0 *:i.10</ |
slist=: constF"0 *:i.10</syntaxhighlight> |
||
Referencing a function by its index (its position in that list): |
Referencing a function by its index (its position in that list): |
||
< |
<syntaxhighlight lang="j"> flist @.3 |
||
3"_ |
3"_ |
||
slist @.3 |
slist @.3 |
||
9"_</ |
9"_</syntaxhighlight> |
||
Using a function, given its index: |
Using a function, given its index: |
||
< |
<syntaxhighlight lang="j"> flist @.4'' |
||
4 |
4 |
||
slist @.4'' |
slist @.4'' |
||
16</ |
16</syntaxhighlight> |
||
Running a randomly picked function which is not the last one: |
Running a randomly picked function which is not the last one: |
||
< |
<syntaxhighlight lang="j"> flist@.(?9) '' |
||
7 |
7 |
||
slist@.(?9) '' |
slist@.(?9) '' |
||
25</ |
25</syntaxhighlight> |
||
===Tacit (unorthodox) version=== |
===Tacit (unorthodox) version=== |
||
In J only adverbs and conjunctions (functionals) can produce verbs (functions)... Unless they are forced to cloak as verbs; in this instance, the rank conjunction (“) cloaks as a dyadic verb. (Note that this takes advantage of a bug/feature where the interpreter does not produce a result with [http://www.jsoftware.com/help/dictionary/dictb.htm the correct shape]): |
In J only adverbs and conjunctions (functionals) can produce verbs (functions)... Unless they are forced to cloak as verbs; in this instance, the rank conjunction (“) cloaks as a dyadic verb. (Note that this takes advantage of a bug/feature where the interpreter does not produce a result with [http://www.jsoftware.com/help/dictionary/dictb.htm the correct shape]): |
||
< |
<syntaxhighlight lang="j"> ( VL=. (<@:((<'"')(0:`)(,^:)&_))"0@:(^&2)@:i. 10 ) NB. Producing a list of boxed anonymous verbs (functions) |
||
┌───┬───┬───┬───┬────┬────┬────┬────┬────┬────┐ |
┌───┬───┬───┬───┬────┬────┬────┬────┬────┬────┐ |
||
│0"_│1"_│4"_│9"_│16"_│25"_│36"_│49"_│64"_│81"_│ |
│0"_│1"_│4"_│9"_│16"_│25"_│36"_│49"_│64"_│81"_│ |
||
Line 985: | Line 985: | ||
25"_ |
25"_ |
||
{::&VL 5 '' NB. Invoking the 6th verb with a dummy argument ('') |
{::&VL 5 '' NB. Invoking the 6th verb with a dummy argument ('') |
||
25</ |
25</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|Java|8+}} |
{{works with|Java|8+}} |
||
< |
<syntaxhighlight lang="java">import java.util.function.Supplier; |
||
import java.util.ArrayList; |
import java.util.ArrayList; |
||
Line 1,003: | Line 1,003: | ||
System.out.println(foo.get()); // prints "9" |
System.out.println(foo.get()); // prints "9" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Alternative implementation that also {{works with|Java|8+}} |
Alternative implementation that also {{works with|Java|8+}} |
||
< |
<syntaxhighlight lang="java">import java.util.List; |
||
import java.util.function.IntSupplier; |
import java.util.function.IntSupplier; |
||
import java.util.stream.IntStream; |
import java.util.stream.IntStream; |
||
Line 1,022: | Line 1,022: | ||
System.out.println(closure.getAsInt()); // prints "9" |
System.out.println(closure.getAsInt()); // prints "9" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Line 1,028: | Line 1,028: | ||
===Imperative=== |
===Imperative=== |
||
< |
<syntaxhighlight lang="javascript">var funcs = []; |
||
for (var i = 0; i < 10; i++) { |
for (var i = 0; i < 10; i++) { |
||
funcs.push( (function(i) { |
funcs.push( (function(i) { |
||
Line 1,034: | Line 1,034: | ||
})(i) ); |
})(i) ); |
||
} |
} |
||
window.alert(funcs[3]()); // alerts "9"</ |
window.alert(funcs[3]()); // alerts "9"</syntaxhighlight> |
||
{{works with|JavaScript|1.7+}} (Firefox 2+) |
{{works with|JavaScript|1.7+}} (Firefox 2+) |
||
< |
<syntaxhighlight lang="javascript"><script type="application/javascript;version=1.7"> |
||
var funcs = []; |
var funcs = []; |
||
for (var i = 0; i < 10; i++) { |
for (var i = 0; i < 10; i++) { |
||
Line 1,045: | Line 1,045: | ||
} |
} |
||
window.alert(funcs[3]()); // alerts "9" |
window.alert(funcs[3]()); // alerts "9" |
||
</script></ |
</script></syntaxhighlight> |
||
{{works with|JavaScript|ES6}} |
{{works with|JavaScript|ES6}} |
||
< |
<syntaxhighlight lang="javascript">"use strict"; |
||
let funcs = []; |
let funcs = []; |
||
for (let i = 0; i < 10; ++i) { |
for (let i = 0; i < 10; ++i) { |
||
funcs.push((i => () => i*i)(i)); |
funcs.push((i => () => i*i)(i)); |
||
} |
} |
||
console.log(funcs[3]());</ |
console.log(funcs[3]());</syntaxhighlight> |
||
===Functional === |
===Functional === |
||
Line 1,059: | Line 1,059: | ||
{{works with|JavaScript|ES5}} |
{{works with|JavaScript|ES5}} |
||
< |
<syntaxhighlight lang="javascript">(function () { |
||
'use strict'; |
'use strict'; |
||
Line 1,079: | Line 1,079: | ||
return lstFns[3](); |
return lstFns[3](); |
||
})();</ |
})();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,087: | Line 1,087: | ||
{{works with|JavaScript|ES6}} |
{{works with|JavaScript|ES6}} |
||
< |
<syntaxhighlight lang="javascript">let funcs = [...Array(10).keys()].map(i => () => i*i);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,095: | Line 1,095: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
< |
<syntaxhighlight lang="julia">funcs = [ () -> i^2 for i = 1:10 ]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,103: | Line 1,103: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">// version 1.0.6 |
||
fun main(args: Array<String>) { |
fun main(args: Array<String>) { |
||
Line 1,110: | Line 1,110: | ||
// call all but the last |
// call all but the last |
||
(0 .. 8).forEach { println(funcs[it]()) } |
(0 .. 8).forEach { println(funcs[it]()) } |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,128: | Line 1,128: | ||
A translation from Javascript |
A translation from Javascript |
||
< |
<syntaxhighlight lang="scheme"> |
||
{def A |
{def A |
||
{A.new |
{A.new |
||
Line 1,139: | Line 1,139: | ||
{A.get 4 {A}} |
{A.get 4 {A}} |
||
-> 16 |
-> 16 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Latitude}}== |
=={{header|Latitude}}== |
||
Line 1,145: | Line 1,145: | ||
Latitude is particularly well suited to this challenge, as the various iteration constructs actually take method arguments and <i>call</i> them multiple times. Thus, the loop variable is in fact an argument which is already closed over and distinct at each iteration. |
Latitude is particularly well suited to this challenge, as the various iteration constructs actually take method arguments and <i>call</i> them multiple times. Thus, the loop variable is in fact an argument which is already closed over and distinct at each iteration. |
||
< |
<syntaxhighlight lang="latitude">functions := 10 times to (Array) map { |
||
takes '[i]. |
takes '[i]. |
||
proc { (i) * (i). }. |
proc { (i) * (i). }. |
||
}. |
}. |
||
functions visit { println: $1 call. }.</ |
functions visit { println: $1 call. }.</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 1,167: | Line 1,167: | ||
Input at the REPL: |
Input at the REPL: |
||
< |
<syntaxhighlight lang="lisp"> |
||
> (set funcs (list-comp ((<- m (lists:seq 1 10))) |
> (set funcs (list-comp ((<- m (lists:seq 1 10))) |
||
(lambda () (math:pow m 2)))) |
(lambda () (math:pow m 2)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
< |
<syntaxhighlight lang="lisp"> |
||
(#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464> |
(#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464> |
||
#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464> |
#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464> |
||
Line 1,179: | Line 1,179: | ||
#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464> |
#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464> |
||
#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464>) |
#Fun<lfe_eval.23.101079464> #Fun<lfe_eval.23.101079464>) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Calling the functions: |
Calling the functions: |
||
< |
<syntaxhighlight lang="lisp"> |
||
> (funcall (car funcs)) |
> (funcall (car funcs)) |
||
1.0 |
1.0 |
||
Line 1,192: | Line 1,192: | ||
64.0 |
64.0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
Line 1,198: | Line 1,198: | ||
Lingo doesn't really support closures. But with the limitations described at [https://www.rosettacode.org/wiki/Function_composition#Lingo Function composition] and based on the fact that Lingo allows to create arbitrary code at runtime, the task can be solved like this: |
Lingo doesn't really support closures. But with the limitations described at [https://www.rosettacode.org/wiki/Function_composition#Lingo Function composition] and based on the fact that Lingo allows to create arbitrary code at runtime, the task can be solved like this: |
||
< |
<syntaxhighlight lang="lingo">-- parent script "CallFunction" |
||
property _code |
property _code |
||
Line 1,221: | Line 1,221: | ||
do(me._code) |
do(me._code) |
||
return res |
return res |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="lingo">funcs = [] |
||
repeat with i = 1 to 10 |
repeat with i = 1 to 10 |
||
code = "res="&i&"*"&i |
code = "res="&i&"*"&i |
||
Line 1,230: | Line 1,230: | ||
put call(funcs[3], _movie) |
put call(funcs[3], _movie) |
||
-- 9</ |
-- 9</syntaxhighlight> |
||
Since the original task is a little trivial in terms of not depending on runtime arguments, here also a solution for an extended task: let each function[i] return the square of i plus the sum of all arguments passed to it at runtime: |
Since the original task is a little trivial in terms of not depending on runtime arguments, here also a solution for an extended task: let each function[i] return the square of i plus the sum of all arguments passed to it at runtime: |
||
< |
<syntaxhighlight lang="lingo">funcs = [] |
||
repeat with i = 1 to 10 |
repeat with i = 1 to 10 |
||
code = "" |
code = "" |
||
Line 1,248: | Line 1,248: | ||
put call(funcs[7], _movie, 4, 5, 6) |
put call(funcs[7], _movie, 4, 5, 6) |
||
-- 64</ |
-- 64</syntaxhighlight> |
||
=={{header|Logtalk}}== |
=={{header|Logtalk}}== |
||
The example that follow uses Logtalk's native support for lambda expressions. |
The example that follow uses Logtalk's native support for lambda expressions. |
||
< |
<syntaxhighlight lang="logtalk"> |
||
:- object(value_capture). |
:- object(value_capture). |
||
Line 1,268: | Line 1,268: | ||
:- end_object. |
:- end_object. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="text"> |
||
| ?- value_capture::show. |
| ?- value_capture::show. |
||
Closure 1 : 1 |
Closure 1 : 1 |
||
Line 1,283: | Line 1,283: | ||
Closure 10 : 100 |
Closure 10 : 100 |
||
yes |
yes |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="Lua"> |
||
funcs={} |
funcs={} |
||
for i=1,10 do |
for i=1,10 do |
||
Line 1,293: | Line 1,293: | ||
funcs[2]() |
funcs[2]() |
||
funcs[3]() |
funcs[3]() |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>4 |
<pre>4 |
||
Line 1,300: | Line 1,300: | ||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
< |
<syntaxhighlight lang="M2000 Interpreter"> |
||
Dim Base 0, A(10) |
Dim Base 0, A(10) |
||
For i=0 to 9 { |
For i=0 to 9 { |
||
Line 1,308: | Line 1,308: | ||
Print a(i)() |
Print a(i)() |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Print |
Print |
||
0 |
0 |
||
Line 1,322: | Line 1,322: | ||
Export list to clipboard |
Export list to clipboard |
||
< |
<syntaxhighlight lang="M2000 Interpreter"> |
||
document a$ |
document a$ |
||
For i=0 to 9 { |
For i=0 to 9 { |
||
Line 1,329: | Line 1,329: | ||
} |
} |
||
Clipboard a$ |
Clipboard a$ |
||
</syntaxhighlight> |
|||
</lang> |
|||
Using Inventory, and a stack object (reading from position, and another way, we pop functions, using Read) |
Using Inventory, and a stack object (reading from position, and another way, we pop functions, using Read) |
||
< |
<syntaxhighlight lang="M2000 Interpreter"> |
||
Inventory Alfa |
Inventory Alfa |
||
For i=0 to 9 { |
For i=0 to 9 { |
||
Line 1,362: | Line 1,362: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="Maple">> L := map( i -> (() -> i^2), [seq](1..10) ): |
||
> seq( L[i](),i=1..10); |
> seq( L[i](),i=1..10); |
||
1, 4, 9, 16, 25, 36, 49, 64, 81, 100 |
1, 4, 9, 16, 25, 36, 49, 64, 81, 100 |
||
> L[4](); |
> L[4](); |
||
16 |
16 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="Mathematica">Function[i, i^2 &] /@ Range@10 |
||
->{1^2 &, 2^2 &, 3^2 &, 4^2 &, 5^2 &, 6^2 &, 7^2 &, 8^2 &, 9^2 &, 10^2 &} |
->{1^2 &, 2^2 &, 3^2 &, 4^2 &, 5^2 &, 6^2 &, 7^2 &, 8^2 &, 9^2 &, 10^2 &} |
||
%[[2]][] |
%[[2]][] |
||
->4</ |
->4</syntaxhighlight> |
||
=={{header|Nemerle}}== |
=={{header|Nemerle}}== |
||
< |
<syntaxhighlight lang="Nemerle">using System.Console; |
||
module Closures |
module Closures |
||
Line 1,392: | Line 1,392: | ||
WriteLine($"$(funcs[2]())"); |
WriteLine($"$(funcs[2]())"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>16 |
<pre>16 |
||
Line 1,398: | Line 1,398: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">var funcs: seq[proc(): int] = @[] |
||
for i in 0..9: |
for i in 0..9: |
||
Line 1,406: | Line 1,406: | ||
for i in 0..8: |
for i in 0..8: |
||
echo "func[", i, "]: ", funcs[i]()</ |
echo "func[", i, "]: ", funcs[i]()</syntaxhighlight> |
||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang="objeck">use Collection.Generic; |
||
class Capture { |
class Capture { |
||
Line 1,425: | Line 1,425: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{output}} |
{{output}} |
||
Line 1,443: | Line 1,443: | ||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
{{works with|Cocoa|Mac OS X 10.6+}} with ARC |
{{works with|Cocoa|Mac OS X 10.6+}} with ARC |
||
< |
<syntaxhighlight lang="objc">NSMutableArray *funcs = [[NSMutableArray alloc] init]; |
||
for (int i = 0; i < 10; i++) { |
for (int i = 0; i < 10; i++) { |
||
[funcs addObject:[^ { return i * i; } copy]]; |
[funcs addObject:[^ { return i * i; } copy]]; |
||
Line 1,450: | Line 1,450: | ||
int (^foo)(void) = funcs[3]; |
int (^foo)(void) = funcs[3]; |
||
NSLog(@"%d", foo()); // logs "9" |
NSLog(@"%d", foo()); // logs "9" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 1,456: | Line 1,456: | ||
All functions in OCaml are closures. |
All functions in OCaml are closures. |
||
< |
<syntaxhighlight lang="ocaml">let () = |
||
let cls = Array.init 10 (fun i -> (function () -> i * i)) in |
let cls = Array.init 10 (fun i -> (function () -> i * i)) in |
||
Random.self_init (); |
Random.self_init (); |
||
Line 1,462: | Line 1,462: | ||
let x = Random.int 9 in |
let x = Random.int 9 in |
||
Printf.printf " fun.(%d) = %d\n" x (cls.(x) ()); |
Printf.printf " fun.(%d) = %d\n" x (cls.(x) ()); |
||
done</ |
done</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,475: | Line 1,475: | ||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
< |
<syntaxhighlight lang="Oforth">: newClosure(i) #[ i sq ] ; |
||
10 seq map(#newClosure) at(7) perform .</ |
10 seq map(#newClosure) at(7) perform .</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,485: | Line 1,485: | ||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
{{works with|PARI/GP|2.4.2 and above}} |
{{works with|PARI/GP|2.4.2 and above}} |
||
< |
<syntaxhighlight lang="parigp">vector(10,i,()->i^2)[5]()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,491: | Line 1,491: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">my @f = map(sub { $_ * $_ }, 0 .. 9); # @f is an array of subs |
||
print $f[$_](), "\n" for (0 .. 8); # call and print all but last</ |
print $f[$_](), "\n" for (0 .. 8); # call and print all but last</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,508: | Line 1,508: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Phix does not support closures, but they seem easy enough to emulate |
Phix does not support closures, but they seem easy enough to emulate |
||
<!--< |
<!--<syntaxhighlight lang="Phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #000080;font-style:italic;">-- First some generic handling stuff, handles partial_args |
<span style="color: #000080;font-style:italic;">-- First some generic handling stuff, handles partial_args |
||
Line 1,545: | Line 1,545: | ||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">call_closure</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cids</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],{}))</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">call_closure</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cids</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],{}))</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,559: | Line 1,559: | ||
A dictionary based approach may prove somewhat easier: |
A dictionary based approach may prove somewhat easier: |
||
<!--< |
<!--<syntaxhighlight lang="Phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #008080;">function</span> <span style="color: #000000;">square</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">function</span> <span style="color: #000000;">square</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">)</span> |
||
Line 1,574: | Line 1,574: | ||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">square</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tids</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">square</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tids</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
same output, for both tests |
same output, for both tests |
||
=={{header|Phixmonti}}== |
=={{header|Phixmonti}}== |
||
< |
<syntaxhighlight lang="Phixmonti">def power2 |
||
dup * |
dup * |
||
enddef |
enddef |
||
Line 1,594: | Line 1,594: | ||
var i |
var i |
||
i get i swap exec print " " print |
i get i swap exec print " " print |
||
endfor</ |
endfor</syntaxhighlight> |
||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
{{works with|PHP|5.3+}} |
{{works with|PHP|5.3+}} |
||
< |
<syntaxhighlight lang="php"><?php |
||
$funcs = array(); |
$funcs = array(); |
||
for ($i = 0; $i < 10; $i++) { |
for ($i = 0; $i < 10; $i++) { |
||
Line 1,604: | Line 1,604: | ||
} |
} |
||
echo $funcs[3](), "\n"; // prints 9 |
echo $funcs[3](), "\n"; // prints 9 |
||
?></ |
?></syntaxhighlight> |
||
{{works with|PHP|pre-5.3}} |
{{works with|PHP|pre-5.3}} |
||
This method can capture value types like numbers, strings, arrays, etc., but not objects. |
This method can capture value types like numbers, strings, arrays, etc., but not objects. |
||
< |
<syntaxhighlight lang="php"><?php |
||
$funcs = array(); |
$funcs = array(); |
||
for ($i = 0; $i < 10; $i++) { |
for ($i = 0; $i < 10; $i++) { |
||
Line 1,614: | Line 1,614: | ||
} |
} |
||
echo $funcs[3](), "\n"; // prints 9 |
echo $funcs[3](), "\n"; // prints 9 |
||
?></ |
?></syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="PicoLisp">(setq FunList |
||
(make |
(make |
||
(for @N 10 |
(for @N 10 |
||
(link (curry (@N) () (* @N @N))) ) ) )</ |
(link (curry (@N) () (* @N @N))) ) ) )</syntaxhighlight> |
||
Test: |
Test: |
||
<pre>: ((get FunList 2)) |
<pre>: ((get FunList 2)) |
||
Line 1,629: | Line 1,629: | ||
=={{header|Pike}}== |
=={{header|Pike}}== |
||
< |
<syntaxhighlight lang="Pike">array funcs = ({}); |
||
foreach(enumerate(10);; int i) |
foreach(enumerate(10);; int i) |
||
{ |
{ |
||
Line 1,641: | Line 1,641: | ||
}(i) |
}(i) |
||
}); |
}); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
I'm not sure that I understood the question/task. This task seems to be the same as the 'Accumulator Factory' task. |
I'm not sure that I understood the question/task. This task seems to be the same as the 'Accumulator Factory' task. |
||
< |
<syntaxhighlight lang="PowerShell"> |
||
function Get-Closure ([double]$Number) |
function Get-Closure ([double]$Number) |
||
{ |
{ |
||
{param([double]$Sum) return $script:Number *= $Sum}.GetNewClosure() |
{param([double]$Sum) return $script:Number *= $Sum}.GetNewClosure() |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang="PowerShell"> |
||
for ($i = 1; $i -lt 11; $i++) |
for ($i = 1; $i -lt 11; $i++) |
||
{ |
{ |
||
Line 1,661: | Line 1,661: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 1,677: | Line 1,677: | ||
10 100 |
10 100 |
||
</pre> |
</pre> |
||
< |
<syntaxhighlight lang="PowerShell"> |
||
$numbers = 1..20 | Get-Random -Count 10 |
$numbers = 1..20 | Get-Random -Count 10 |
||
Line 1,689: | Line 1,689: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 1,710: | Line 1,710: | ||
'''lambda.pl''' can be found there : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl |
'''lambda.pl''' can be found there : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl |
||
< |
<syntaxhighlight lang="Prolog">:-use_module(library(lambda)). |
||
Line 1,724: | Line 1,724: | ||
call(F, R), |
call(F, R), |
||
format('Func ~w : ~w~n', [N, R]). |
format('Func ~w : ~w~n', [N, R]). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> ?- closure. |
<pre> ?- closure. |
||
Line 1,742: | Line 1,742: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
The naive way does not work: |
The naive way does not work: |
||
< |
<syntaxhighlight lang="python">funcs = [] |
||
for i in range(10): |
for i in range(10): |
||
funcs.append(lambda: i * i) |
funcs.append(lambda: i * i) |
||
print funcs[3]() # prints 81</ |
print funcs[3]() # prints 81</syntaxhighlight> |
||
The simplest solution is to add optional parameters with default arguments at the end of the parameter list, to create a local copy of the variable, and evaluate the variable at the time the function is created. (The optional parameter is not expected to ever be passed.) Often, the optional parameter will be named the same as the variable to be closed over (leading to odd-looking code of the form <code>foo=foo</code> in the arguments), so that the code inside the function need not be changed, but this might lead to confusion. This technique does not work for functions with a variable number of arguments. |
The simplest solution is to add optional parameters with default arguments at the end of the parameter list, to create a local copy of the variable, and evaluate the variable at the time the function is created. (The optional parameter is not expected to ever be passed.) Often, the optional parameter will be named the same as the variable to be closed over (leading to odd-looking code of the form <code>foo=foo</code> in the arguments), so that the code inside the function need not be changed, but this might lead to confusion. This technique does not work for functions with a variable number of arguments. |
||
< |
<syntaxhighlight lang="python">funcs = [] |
||
for i in range(10): |
for i in range(10): |
||
funcs.append(lambda i=i: i * i) |
funcs.append(lambda i=i: i * i) |
||
print funcs[3]() # prints 9</ |
print funcs[3]() # prints 9</syntaxhighlight> |
||
or equivalently the list comprehension: |
or equivalently the list comprehension: |
||
< |
<syntaxhighlight lang="python">funcs = [lambda i=i: i * i for i in range(10)] |
||
print funcs[3]() # prints 9</ |
print funcs[3]() # prints 9</syntaxhighlight> |
||
Another solution is to wrap an immediately-executed function around our function. The wrapping function creates a new scope, and its execution forces the evaluation of the variable to be closed over. |
Another solution is to wrap an immediately-executed function around our function. The wrapping function creates a new scope, and its execution forces the evaluation of the variable to be closed over. |
||
< |
<syntaxhighlight lang="python">funcs = [] |
||
for i in range(10): |
for i in range(10): |
||
funcs.append((lambda i: lambda: i * i)(i)) |
funcs.append((lambda i: lambda: i * i)(i)) |
||
print funcs[3]() # prints 9</ |
print funcs[3]() # prints 9</syntaxhighlight> |
||
or equivalently the list comprehension: |
or equivalently the list comprehension: |
||
< |
<syntaxhighlight lang="python">funcs = [(lambda i: lambda: i)(i * i) for i in range(10)] |
||
print funcs[3]() # prints 9</ |
print funcs[3]() # prints 9</syntaxhighlight> |
||
In this case it is also possible to use <code>map()</code> since the function passed to it creates a new scope |
In this case it is also possible to use <code>map()</code> since the function passed to it creates a new scope |
||
< |
<syntaxhighlight lang="python">funcs = map(lambda i: lambda: i * i, range(10)) |
||
print funcs[3]() # prints 9</ |
print funcs[3]() # prints 9</syntaxhighlight> |
||
It is also possible to use <code>eval</code>. |
It is also possible to use <code>eval</code>. |
||
< |
<syntaxhighlight lang="python">funcs=[eval("lambda:%s"%i**2)for i in range(10)] |
||
print funcs[3]() # prints 9</ |
print funcs[3]() # prints 9</syntaxhighlight> |
||
=={{header|Quackery}}== |
=={{header|Quackery}}== |
||
Line 1,777: | Line 1,777: | ||
Strictly speaking, we could get away with <code>[ table 0 1 4 9 16 25 36 49 64 81 ] is functions ( n --> n )</code> for this task, as numbers in Quackery are functions that return their own value when executed, e.g <code>5 do</code> returns <code>5</code>, but it feels like cheating. |
Strictly speaking, we could get away with <code>[ table 0 1 4 9 16 25 36 49 64 81 ] is functions ( n --> n )</code> for this task, as numbers in Quackery are functions that return their own value when executed, e.g <code>5 do</code> returns <code>5</code>, but it feels like cheating. |
||
< |
<syntaxhighlight lang="Quackery"> [ table ] is functions ( n --> [ ) |
||
10 times |
10 times |
||
Line 1,783: | Line 1,783: | ||
' functions put ] |
' functions put ] |
||
5 functions do echo</ |
5 functions do echo</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,796: | Line 1,796: | ||
what you expect. |
what you expect. |
||
<syntaxhighlight lang="R"> |
|||
<lang R> |
|||
# assign 's' a list of ten functions |
# assign 's' a list of ten functions |
||
s <- sapply (1:10, # integers 1..10 become argument 'x' below |
s <- sapply (1:10, # integers 1..10 become argument 'x' below |
||
Line 1,806: | Line 1,806: | ||
s[[5]]() # call the fifth function in the list of returned functions |
s[[5]]() # call the fifth function in the list of returned functions |
||
[1] 25 # returns vector of length 1 with the value 25 |
[1] 25 # returns vector of length 1 with the value 25 |
||
</syntaxhighlight> |
|||
</lang> |
|||
Note that I bound the captured variable as the default argument on a unary function. |
Note that I bound the captured variable as the default argument on a unary function. |
||
Line 1,812: | Line 1,812: | ||
ignores the default argument. |
ignores the default argument. |
||
<syntaxhighlight lang="R"> |
|||
<lang R> |
|||
s[[5]](10) |
s[[5]](10) |
||
[1] 100 |
[1] 100 |
||
</syntaxhighlight> |
|||
</lang> |
|||
As a further technicality, note that you need some extra voodoo to '''modify''' the bound argument |
As a further technicality, note that you need some extra voodoo to '''modify''' the bound argument |
||
with persistence across calls. This example increments the bound variable after each call. |
with persistence across calls. This example increments the bound variable after each call. |
||
<syntaxhighlight lang="R"> |
|||
<lang R> |
|||
s <- sapply (1:10, |
s <- sapply (1:10, |
||
function (x) { |
function (x) { |
||
Line 1,839: | Line 1,839: | ||
s[[1]]() |
s[[1]]() |
||
[1] 4 # now 2^2 |
[1] 4 # now 2^2 |
||
</syntaxhighlight> |
|||
</lang> |
|||
As shown, each instance increments separately. |
As shown, each instance increments separately. |
||
Line 1,848: | Line 1,848: | ||
I think that modifying the bound variable can be done in a simpler way. |
I think that modifying the bound variable can be done in a simpler way. |
||
Instead of: |
Instead of: |
||
< |
<syntaxhighlight lang="R"> evalq (x <- x + 1, parent.env(environment()))</syntaxhighlight> |
||
substitute: |
substitute: |
||
< |
<syntaxhighlight lang="R"> x <<- x + 1</syntaxhighlight> |
||
Testing: |
Testing: |
||
<pre> |
<pre> |
||
Line 1,868: | Line 1,868: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(define functions (for/list ([i 10]) (λ() (* i i)))) |
(define functions (for/list ([i 10]) (λ() (* i i)))) |
||
(map (λ(f) (f)) functions) |
(map (λ(f) (f)) functions) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="racket"> |
||
'(0 1 4 9 16 25 36 49 64 81) |
'(0 1 4 9 16 25 36 49 64 81) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 1,882: | Line 1,882: | ||
{{Works with|Rakudo|2015.12}} |
{{Works with|Rakudo|2015.12}} |
||
All blocks are anonymous closures in Raku, and parameters are lexicals, so it's easy to generate a list of them. We'll use a <tt>gather</tt>/<tt>take</tt> generator loop, and call the closures in random order, just to keep things interesting. |
All blocks are anonymous closures in Raku, and parameters are lexicals, so it's easy to generate a list of them. We'll use a <tt>gather</tt>/<tt>take</tt> generator loop, and call the closures in random order, just to keep things interesting. |
||
<lang |
<syntaxhighlight lang="raku" line>my @c = gather for ^10 -> $i { |
||
take { $i * $i } |
take { $i * $i } |
||
} |
} |
||
.().say for @c.pick(*); # call them in random order</ |
.().say for @c.pick(*); # call them in random order</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>36 |
<pre>36 |
||
Line 1,899: | Line 1,899: | ||
49</pre> |
49</pre> |
||
Or equivalently, using a more functional notation: |
Or equivalently, using a more functional notation: |
||
<lang |
<syntaxhighlight lang="raku" line>say .() for pick *, map -> $i { -> {$i * $i} }, ^10</syntaxhighlight> |
||
=={{header|Red}}== |
=={{header|Red}}== |
||
< |
<syntaxhighlight lang="Red"> |
||
funs: collect [repeat i 10 [keep func [] reduce [i ** 2]]] |
funs: collect [repeat i 10 [keep func [] reduce [i ** 2]]] |
||
>> funs/7 |
>> funs/7 |
||
== 49 |
== 49 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 1,917: | Line 1,917: | ||
No error checking is performed on the user input(s). |
No error checking is performed on the user input(s). |
||
< |
<syntaxhighlight lang="rexx">/*REXX program has a list of ten functions, each returns its invocation (index) squared.*/ |
||
parse arg seed base $ /*obtain optional arguments from the CL*/ |
parse arg seed base $ /*obtain optional arguments from the CL*/ |
||
if datatype(seed, 'W') then call random ,,seed /*Not given? Use random start seed. */ |
if datatype(seed, 'W') then call random ,,seed /*Not given? Use random start seed. */ |
||
Line 1,941: | Line 1,941: | ||
.9: return .(9) /* ' .9 " " " " */ |
.9: return .(9) /* ' .9 " " " " */ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
.: arg #; _=wordpos(#,$); if _==0 then return 'not in the list.'; return (_-(\base))**2</ |
.: arg #; _=wordpos(#,$); if _==0 then return 'not in the list.'; return (_-(\base))**2</syntaxhighlight> |
||
{{out|output|text= when using the default input which assume a zero─based list):}} |
{{out|output|text= when using the default input which assume a zero─based list):}} |
||
<pre> |
<pre> |
||
Line 1,954: | Line 1,954: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
x = funcs(7) |
x = funcs(7) |
||
see x + nl |
see x + nl |
||
Line 1,964: | Line 1,964: | ||
next |
next |
||
return fn |
return fn |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 1,977: | Line 1,977: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">procs = Array.new(10){|i| ->{i*i} } # -> creates a lambda |
||
p procs[7].call # => 49</ |
p procs[7].call # => 49</syntaxhighlight> |
||
In Ruby, lambdas (and procs) are closures. |
In Ruby, lambdas (and procs) are closures. |
||
Line 1,986: | Line 1,986: | ||
Rust employs strong ownership rules that do not allow mutating a value that is referenced (pointed to without allowing mutation) from elsewhere. It also doesn't allow referencing a value that may be dropped before the reference is released. The proof that we really did capture the value is therefore unnecessary. Either we did or it wouldn't have compiled. |
Rust employs strong ownership rules that do not allow mutating a value that is referenced (pointed to without allowing mutation) from elsewhere. It also doesn't allow referencing a value that may be dropped before the reference is released. The proof that we really did capture the value is therefore unnecessary. Either we did or it wouldn't have compiled. |
||
< |
<syntaxhighlight lang="rust">fn main() { |
||
let fs: Vec<_> = (0..10).map(|i| {move || i*i} ).collect(); |
let fs: Vec<_> = (0..10).map(|i| {move || i*i} ).collect(); |
||
println!("7th val: {}", fs[7]()); |
println!("7th val: {}", fs[7]()); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,995: | Line 1,995: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">val closures=for(i <- 0 to 9) yield (()=>i*i) |
||
0 to 8 foreach (i=> println(closures(i)())) |
0 to 8 foreach (i=> println(closures(i)())) |
||
println("---\n"+closures(7)())</ |
println("---\n"+closures(7)())</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>0 |
<pre>0 |
||
Line 2,013: | Line 2,013: | ||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
< |
<syntaxhighlight lang="scheme">;;; Collecting lambdas in a tail-recursive function. |
||
(define (build-list-of-functions n i list) |
(define (build-list-of-functions n i list) |
||
(if (< i n) |
(if (< i n) |
||
Line 2,023: | Line 2,023: | ||
(map (lambda (f) (f)) list-of-functions) |
(map (lambda (f) (f)) list-of-functions) |
||
((list-ref list-of-functions 8))</ |
((list-ref list-of-functions 8))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="scheme">'(1 4 9 16 25 36 49 64 81) |
||
81</ |
81</syntaxhighlight> |
||
---- |
---- |
||
Using Scheme [http://srfi.schemers.org/srfi-1/srfi-1.html SRFI 1] ''iota'' procedure can be simplified to: |
Using Scheme [http://srfi.schemers.org/srfi-1/srfi-1.html SRFI 1] ''iota'' procedure can be simplified to: |
||
< |
<syntaxhighlight lang="scheme"> |
||
(define list-of-functions (map (lambda (x) (lambda () (* x x))) (iota 0 1 10))) |
(define list-of-functions (map (lambda (x) (lambda () (* x x))) (iota 0 1 10))) |
||
Line 2,039: | Line 2,039: | ||
(map (lambda (n) (n)) list-of-functions) |
(map (lambda (n) (n)) list-of-functions) |
||
(newline) |
(newline) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">var f = ( |
||
10.of {|i| func(j){i * j} } |
10.of {|i| func(j){i * j} } |
||
) |
) |
||
Line 2,048: | Line 2,048: | ||
9.times { |j| |
9.times { |j| |
||
say f[j](j) |
say f[j](j) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,063: | Line 2,063: | ||
Starting from i=1: |
Starting from i=1: |
||
< |
<syntaxhighlight lang="ruby">var f = (1..10).map { |i| |
||
func(j){i * j} |
func(j){i * j} |
||
} |
} |
||
Line 2,069: | Line 2,069: | ||
for j (1..9) { |
for j (1..9) { |
||
say f[j-1](j) |
say f[j-1](j) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,084: | Line 2,084: | ||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
< |
<syntaxhighlight lang="smalltalk">funcs := (1 to: 10) collect: [ :i | [ i * i ] ] . |
||
(funcs at: 3) value displayNl .</ |
(funcs at: 3) value displayNl .</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>9</pre> |
<pre>9</pre> |
||
Line 2,092: | Line 2,092: | ||
In Sparkling, upvalues (variables in the closure) are captured by value. |
In Sparkling, upvalues (variables in the closure) are captured by value. |
||
< |
<syntaxhighlight lang="sparkling">var fnlist = {}; |
||
for var i = 0; i < 10; i++ { |
for var i = 0; i < 10; i++ { |
||
fnlist[i] = function() { |
fnlist[i] = function() { |
||
Line 2,100: | Line 2,100: | ||
print(fnlist[3]()); // prints 9 |
print(fnlist[3]()); // prints 9 |
||
print(fnlist[5]()); // prints 25</ |
print(fnlist[5]()); // prints 25</syntaxhighlight> |
||
Alternately: |
Alternately: |
||
< |
<syntaxhighlight lang="sparkling">var fnlist = map(range(10), function(k, v) { |
||
return function() { |
return function() { |
||
return v * v; |
return v * v; |
||
Line 2,111: | Line 2,111: | ||
print(fnlist[3]()); // prints 9 |
print(fnlist[3]()); // prints 9 |
||
print(fnlist[5]()); // prints 25</ |
print(fnlist[5]()); // prints 25</syntaxhighlight> |
||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
< |
<syntaxhighlight lang="Standard ML"> |
||
List.map (fn x => x () ) ( List.tabulate (10,(fn i => (fn ()=> i*i)) ) ) ; |
List.map (fn x => x () ) ( List.tabulate (10,(fn i => (fn ()=> i*i)) ) ) ; |
||
</ |
</syntaxhighlight> Output: |
||
< |
<syntaxhighlight lang="Standard ML"> |
||
val it = [0,1,4,9,16,25,36,49,64,81] : int list |
val it = [0,1,4,9,16,25,36,49,64,81] : int list |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
By default, Swift captures variables by reference. A naive implementation like the following C-style for loop does not work: |
By default, Swift captures variables by reference. A naive implementation like the following C-style for loop does not work: |
||
< |
<syntaxhighlight lang="swift">var funcs: [() -> Int] = [] |
||
for var i = 0; i < 10; i++ { |
for var i = 0; i < 10; i++ { |
||
funcs.append({ i * i }) |
funcs.append({ i * i }) |
||
} |
} |
||
println(funcs[3]()) // prints 100</ |
println(funcs[3]()) // prints 100</syntaxhighlight> |
||
However, using a for-in loop over a range does work, since you get a new constant at every iteration: |
However, using a for-in loop over a range does work, since you get a new constant at every iteration: |
||
< |
<syntaxhighlight lang="swift">var funcs: [() -> Int] = [] |
||
for i in 0..<10 { |
for i in 0..<10 { |
||
funcs.append({ i * i }) |
funcs.append({ i * i }) |
||
} |
} |
||
println(funcs[3]()) // prints 9</ |
println(funcs[3]()) // prints 9</syntaxhighlight> |
||
The C-style for loop can also work if we explicitly capture the loop counter: |
The C-style for loop can also work if we explicitly capture the loop counter: |
||
< |
<syntaxhighlight lang="swift">var funcs: [() -> Int] = [] |
||
for var i = 0; i < 10; i++ { |
for var i = 0; i < 10; i++ { |
||
funcs.append({ [i] in i * i }) |
funcs.append({ [i] in i * i }) |
||
} |
} |
||
println(funcs[3]()) // prints 9</ |
println(funcs[3]()) // prints 9</syntaxhighlight> |
||
Alternately, we can also use <code>map()</code> to map over a range, and create the squaring closure inside the mapping closure which has the integer as a parameter: |
Alternately, we can also use <code>map()</code> to map over a range, and create the squaring closure inside the mapping closure which has the integer as a parameter: |
||
< |
<syntaxhighlight lang="swift">let funcs = [] + map(0..<10) {i in { i * i }} |
||
println(funcs[3]()) // prints 9</ |
println(funcs[3]()) // prints 9</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Tcl does not support closures (either value-capturing or variable-capturing) by default, but value-capturing closures are easy to emulate. |
Tcl does not support closures (either value-capturing or variable-capturing) by default, but value-capturing closures are easy to emulate. |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.6; # Just for tailcall command |
||
# Builds a value-capturing closure; does NOT couple variables |
# Builds a value-capturing closure; does NOT couple variables |
||
proc closure {script} { |
proc closure {script} { |
||
Line 2,184: | Line 2,184: | ||
set idx [expr {int(rand()*9)}]; # pick random int from [0..9) |
set idx [expr {int(rand()*9)}]; # pick random int from [0..9) |
||
puts $idx=>[{*}[lindex $theClosures $idx]] |
puts $idx=>[{*}[lindex $theClosures $idx]] |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,198: | Line 2,198: | ||
====Sugared==== |
====Sugared==== |
||
< |
<syntaxhighlight lang="txrlisp">(let ((funs (mapcar (ret (op * @@1 @@1)) (range 1 10)))) |
||
[mapcar call [funs 0..-1]])</ |
[mapcar call [funs 0..-1]])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="txrlisp">(1 4 9 16 25 36 49 64 81)</syntaxhighlight> |
||
====Desugared==== |
====Desugared==== |
||
Line 2,211: | Line 2,211: | ||
The explicit <code>lambda</code> structure here is much like the implicit ones in the "Sugared" example: |
The explicit <code>lambda</code> structure here is much like the implicit ones in the "Sugared" example: |
||
< |
<syntaxhighlight lang="txrlisp">;; Dropping distracting "skip last" requirement |
||
;; (not implemented in original Elisp either). |
;; (not implemented in original Elisp either). |
||
(mapcar 'call |
(mapcar 'call |
||
(mapcar (lambda () |
(mapcar (lambda () |
||
(lambda () (* x x))) '(1 2 3 4 5 6 7 8 9 10)))</ |
(lambda () (* x x))) '(1 2 3 4 5 6 7 8 9 10)))</syntaxhighlight> |
||
====Delimited Continuations==== |
====Delimited Continuations==== |
||
Line 2,255: | Line 2,255: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
< |
<syntaxhighlight lang="ecmascript">var fs = List.filled(10, null) |
||
for (i in 0...fs.count) { |
for (i in 0...fs.count) { |
||
fs[i] = Fn.new { i * i } |
fs[i] = Fn.new { i * i } |
||
} |
} |
||
for (i in 0...fs.count-1) System.print("Function #%(i): %(fs[i].call())")</ |
for (i in 0...fs.count-1) System.print("Function #%(i): %(fs[i].call())")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,276: | Line 2,276: | ||
=={{header|Yabasic}}== |
=={{header|Yabasic}}== |
||
< |
<syntaxhighlight lang="Yabasic"> |
||
dim funcs$(10) |
dim funcs$(10) |
||
Line 2,290: | Line 2,290: | ||
print execute(funcs$(i), i) |
print execute(funcs$(i), i) |
||
next |
next |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
Create a closure of the index over a square function |
Create a closure of the index over a square function |
||
< |
<syntaxhighlight lang="zkl">(0).pump(10,List,fcn(i){i*i}.fp)[8]() //-->64 |
||
list:=(0).pump(10,List,fcn(i){i*i}.fp); |
list:=(0).pump(10,List,fcn(i){i*i}.fp); |
||
foreach n in (list.len()-1) { list[n]().println() } |
foreach n in (list.len()-1) { list[n]().println() } |
||
list.run(True).println()</ |
list.run(True).println()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |