Closures/Value capture: Difference between revisions
Content added Content deleted
m (→{{header|Swift}}: + standard ML) |
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
||
Line 341: | Line 341: | ||
1 |
1 |
||
0 |
0 |
||
</pre> |
|||
=={{header|C++}}== |
|||
{{works with|C++11}} |
|||
<lang cpp>#include <iostream> |
|||
#include <functional> |
|||
#include <vector> |
|||
int main() { |
|||
std::vector<std::function<int()> > funcs; |
|||
for (int i = 0; i < 10; i++) |
|||
funcs.push_back([=]() { return i * i; }); |
|||
for ( std::function<int( )> f : funcs ) |
|||
std::cout << f( ) << std::endl ; |
|||
return 0; |
|||
}</lang> |
|||
{{out}} |
|||
<pre>0 |
|||
1 |
|||
4 |
|||
9 |
|||
16 |
|||
25 |
|||
36 |
|||
49 |
|||
64 |
|||
81 |
|||
</pre> |
</pre> |
||
Line 434: | Line 407: | ||
49 |
49 |
||
64</lang> |
64</lang> |
||
=={{header|C++}}== |
|||
{{works with|C++11}} |
|||
<lang cpp>#include <iostream> |
|||
#include <functional> |
|||
#include <vector> |
|||
int main() { |
|||
std::vector<std::function<int()> > funcs; |
|||
for (int i = 0; i < 10; i++) |
|||
funcs.push_back([=]() { return i * i; }); |
|||
for ( std::function<int( )> f : funcs ) |
|||
std::cout << f( ) << std::endl ; |
|||
return 0; |
|||
}</lang> |
|||
{{out}} |
|||
<pre>0 |
|||
1 |
|||
4 |
|||
9 |
|||
16 |
|||
25 |
|||
36 |
|||
49 |
|||
64 |
|||
81 |
|||
</pre> |
|||
=={{header|Ceylon}}== |
=={{header|Ceylon}}== |
||
Line 540: | Line 540: | ||
81 |
81 |
||
</pre> |
</pre> |
||
=={{header|EchoLisp}}== |
|||
<lang scheme> |
|||
(define (fgen i) (lambda () (* i i))) |
|||
(define fs (for/vector ((i 10)) (fgen i))) ;; vector of 10 anonymous functions |
|||
((vector-ref fs 5)) ;; calls fs[5] |
|||
→ 25 |
|||
</lang> |
|||
=={{header|Dyalect}}== |
=={{header|Dyalect}}== |
||
Line 577: | Line 569: | ||
This is similar to a JavaScript (ES6) solution. |
This is similar to a JavaScript (ES6) solution. |
||
=={{header|EchoLisp}}== |
|||
<lang scheme> |
|||
(define (fgen i) (lambda () (* i i))) |
|||
(define fs (for/vector ((i 10)) (fgen i))) ;; vector of 10 anonymous functions |
|||
((vector-ref fs 5)) ;; calls fs[5] |
|||
→ 25 |
|||
</lang> |
|||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
Line 660: | Line 660: | ||
100 |
100 |
||
ok |
ok |
||
</pre> |
|||
=={{header|FreeBASIC}}== |
|||
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'. |
|||
<lang freebasic>' FB 1.05.0 Win64 |
|||
Type Closure |
|||
Private: |
|||
index As Integer |
|||
Public: |
|||
Declare Constructor(index As Integer = 0) |
|||
Declare Function Square As Integer |
|||
End Type |
|||
Constructor Closure(index As Integer = 0) |
|||
This.index = index |
|||
End Constructor |
|||
Function Closure.Square As Integer |
|||
Return index * index |
|||
End Function |
|||
Dim a(1 To 10) As Closure |
|||
' create Closure objects which capture their index |
|||
For i As Integer = 1 To 10 |
|||
a(i) = Closure(i) |
|||
Next |
|||
' call the Square method on all but the last object |
|||
For i As Integer = 1 to 9 |
|||
Print a(i).Square |
|||
Next |
|||
Print |
|||
Print "Press any key to quit" |
|||
Sleep</lang> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
4 |
|||
9 |
|||
16 |
|||
25 |
|||
36 |
|||
49 |
|||
64 |
|||
81 |
|||
</pre> |
</pre> |
||
Line 835: | Line 784: | ||
<lang forth>25</lang> |
<lang forth>25</lang> |
||
=={{header|FreeBASIC}}== |
|||
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'. |
|||
<lang freebasic>' FB 1.05.0 Win64 |
|||
Type Closure |
|||
Private: |
|||
index As Integer |
|||
Public: |
|||
Declare Constructor(index As Integer = 0) |
|||
Declare Function Square As Integer |
|||
End Type |
|||
Constructor Closure(index As Integer = 0) |
|||
This.index = index |
|||
End Constructor |
|||
Function Closure.Square As Integer |
|||
Return index * index |
|||
End Function |
|||
Dim a(1 To 10) As Closure |
|||
' create Closure objects which capture their index |
|||
For i As Integer = 1 To 10 |
|||
a(i) = Closure(i) |
|||
Next |
|||
' call the Square method on all but the last object |
|||
For i As Integer = 1 to 9 |
|||
Print a(i).Square |
|||
Next |
|||
Print |
|||
Print "Press any key to quit" |
|||
Sleep</lang> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
4 |
|||
9 |
|||
16 |
|||
25 |
|||
36 |
|||
49 |
|||
64 |
|||
81 |
|||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 1,455: | Line 1,455: | ||
64 |
64 |
||
</pre> |
</pre> |
||
=={{header|Perl 6}}== |
|||
{{Works with|Rakudo|2015.12}} |
|||
All blocks are anonymous closures in Perl 6, 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 perl6>my @c = gather for ^10 -> $i { |
|||
take { $i * $i } |
|||
} |
|||
.().say for @c.pick(*); # call them in random order</lang> |
|||
{{out}} |
|||
<pre>36 |
|||
64 |
|||
25 |
|||
1 |
|||
16 |
|||
0 |
|||
4 |
|||
9 |
|||
81 |
|||
49</pre> |
|||
Or equivalently, using a more functional notation: |
|||
<lang perl6>say .() for pick *, map -> $i { -> {$i * $i} }, ^10</lang> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 1,827: | Line 1,805: | ||
'(0 1 4 9 16 25 36 49 64 81) |
'(0 1 4 9 16 25 36 49 64 81) |
||
</lang> |
</lang> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{Works with|Rakudo|2015.12}} |
|||
All blocks are anonymous closures in Perl 6, 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 perl6>my @c = gather for ^10 -> $i { |
|||
take { $i * $i } |
|||
} |
|||
.().say for @c.pick(*); # call them in random order</lang> |
|||
{{out}} |
|||
<pre>36 |
|||
64 |
|||
25 |
|||
1 |
|||
16 |
|||
0 |
|||
4 |
|||
9 |
|||
81 |
|||
49</pre> |
|||
Or equivalently, using a more functional notation: |
|||
<lang perl6>say .() for pick *, map -> $i { -> {$i * $i} }, ^10</lang> |
|||
=={{header|Red}}== |
=={{header|Red}}== |
||
Line 1,920: | Line 1,921: | ||
{{out}} |
{{out}} |
||
<pre>7th val: 49</pre> |
<pre>7th val: 49</pre> |
||
=={{header|Scala}}== |
|||
<lang scala>val closures=for(i <- 0 to 9) yield (()=>i*i) |
|||
0 to 8 foreach (i=> println(closures(i)())) |
|||
println("---\n"+closures(7)())</lang> |
|||
{{out}} |
|||
<pre>0 |
|||
1 |
|||
4 |
|||
9 |
|||
16 |
|||
25 |
|||
36 |
|||
49 |
|||
64 |
|||
--- |
|||
49</pre> |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
Line 1,950: | Line 1,968: | ||
(newline) |
(newline) |
||
</lang> |
</lang> |
||
=={{header|Scala}}== |
|||
<lang scala>val closures=for(i <- 0 to 9) yield (()=>i*i) |
|||
0 to 8 foreach (i=> println(closures(i)())) |
|||
println("---\n"+closures(7)())</lang> |
|||
{{out}} |
|||
<pre>0 |
|||
1 |
|||
4 |
|||
9 |
|||
16 |
|||
25 |
|||
36 |
|||
49 |
|||
64 |
|||
--- |
|||
49</pre> |
|||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
Line 2,047: | Line 2,048: | ||
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 |
||
</lang> |
</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: |