Closures With Mutable Captured Variables: Javascript
Closures With Mutable Captured Variables: Javascript
JavaScript
a = 5;
f = function(x) { return x+a };
console.log(f(10)); // 15
a = 100
console.log(f(10)); // 110
CoffeeScript
a = 5
f = (x)->x+a
console.log f(10) #
1 5
a = 100
console.log f(10) # 1 10
Dart
void main() {
var a = 5;
var f = (x) => x +
a;
print(f(10)); // 1 5
a = 100;
print(f(10)); // 1 10
}
Ruby
a = 5
f = ->(x){x+a}
puts f(10) # => 1
5
a = 100
puts f(10) # => 1 10
Python
a = 5
f = lambda x: x+a
print(f(10)) # 15
a = 100
print(f(10)) # 110
Julia
a = 5
f = (x) -> x+a
print(f(10)) # 1 5
a = 100
print(f(10)) # 1 10
Swift
var a = 5
let f = { (x: Int) -> Int in x+a }
println(f(10)) // 15
a = 100
println(f(10)) // 110
C#
using System;
public class Test
{
delegate int f_type(int x);
public static void Main()
{
int a = 5;
f_type f = (x) => x+a;
System.Console.WriteLine(f(10)); / / 1 5
a = 100;
System.Console.WriteLine(f(10)); / / 1 10
}
}
Go
package main
import "fmt"
func main(){
a := 5
f := func(x int) int { return x+a }
fmt.Println(f(10)) // 15
a = 100
fmt.Println(f(10)) // 110
}
Groovy
def a = 5
def f = { x -> x +
a }
println (10) // 1
f 5
a = 100
println f(10) // 110
R
a <- 5
f <- function(x)x+a
cat("%d", f(10)) # 15
a <- 100
cat("%d",f(10)) # 110
Perl 5
my $a = 5;
my $f = sub { my $x = s
hift; return $x+$a };
print $f->(10), "\n"; # 15
$a = 100;
print $f->(10), "\n"; # 110
Perl 6
my $a = 5;
my $f = -> $x {
$x+$a } ;
print $f(10), " \n"; # 1 5
$a = 100;
print $f(10), " \n"; # 1 10
Lua
a = 5
f = function(x,y) return x+a end
print(f(10)) -- 15
a = 100
print(f(10)) -- 110
Lisp (Scheme) [BiwaScheme, guile]
(define a 5)
(define f (lambda (x) (+ x a )))
(write (f 10)) (newline) ; 1 5
(define a 100)
(write (f 10)) (newline) ; 1 10
Clojure
(def a 5)
(def f (fn [x] (+ x a)))
(println (f 10)) ; 15
(def a 100)
(println (f 10)) ; 110
Smalltalk
a := 5.
f := [ :x |
x +
a ].
(f value: 1 0) p rintNl.
a := 100.
(f value: 1 0) p rintNl !
Scala
object Main extends App {
var a = 5
val f = (x: Integer) => x+a
println(f(10)) // 15
a = 100
println(f(10)) // 110
}
Mathematica
a = 5
f = Function[x, x +
a]
Print[f[10]] (* 1 5 *)
a = 100
Print[f[10]] (* 1 10 *)
C++11 [&]
#include <iostream>
int main() {
int a = 5;
auto f = [&] (int x) { return x + a; }; // or [&a] ...
std::cout << f(10) << std::endl; // 15
a = 100;
std::cout << f(10) << std::endl; // 110
return 0;
}
PHP (>=5.3)
$a = 5;
$f = function($x) use(&$a) { return $x + $a; };
echo $f(10); // 15
echo "\n";
$a = 100;
echo $f(10); // 110
echo "\n";
GCC nested functions & statement expressions (C)
#include <stdio.h>
int main() {
int a = 5;
int (*f)(int x) = ({ int f_(int x) { return x+a; } &f_; });
printf("%d\n", (*f)(10)); /* 15
a = 100;
printf("%d\n", (*f)(10)); /* 110 */
return 0;
}
Maxima
a: 5;
f: lambda([x],x+a);
print(f(10)); /* 15 */
a: 100;
print(f(10)); /* 110 */
RPL
\<< 5 \-> A
\<< \<< A + \>> \-> F
\<< 10 F EVAL 100 @ 15
'A' STO
10 F EVAL \>> @ 110
\>>
\>>
@ Using a 'compiled' variable
\<< 5 \<< \<-A + \>> \-> \<-A F
\<< 10 F EVAL 100 @ 15
'\<-A' STO
10 F EVAL \>> @ 110
\>>
\>>
Factor
USING: kernel locals formatting math ;
IN: test_closures
:: test-closures ( -- )
5 :> a!
[ a + ] :> f
10 f call "%d\n" printf ! 15
100 a!
10 f call "%d\n" printf ! 110
;
note: local variables must be explicitly declared m
utable with !
Erlang
% (cannot modify captured variable)
-module(prog).
-export([main/0]).
main () ->
A = 5,
F = fun(X) -> X+A end,
io:fwrite(io_lib:format("F(10): ~p", [F(10)])). % F(10): 15
Elixir
# cand rebind variable, but no actual state change
a = 5
f = fn(x) -> x + a end
IO.puts f.(10) # 5
1
a = 100
IO.puts f.(10) # 15
Haskell
odify captured variable)
(cannot m
module Main where
a = 5
f = \x -> x+a
main = print (f 10) -- 15
OCaml
let a = 5;;
let f x = x+a;;
print_int(f 10);; (* 1
5 * )
print_string("\n");;
a = 100;;
print_int(f 10);; (* 1 5 * )
print_string("\n");;
Java 8
// local variables referenced from a lambda expression must be f inal or effectively final
public class Test
{
interface Ftype { public Integer call(Integer x); }
public static void main(String[] args)
{
Integer a = 5;
Ftype f = (x) -> x+a;
System.out.print(f.call(10)); // 15
// a = 100; <-- this would provoke a compilation e rror
// System.out.print(f.call(10));
}
}
Java
// using anonymous inner class; same situation as with Java 8 lambdas: a must be e
ffectively final
local variables referenced from a lambda expression must be final or effectively f inal
public class Test
{
interface Ftype { public Integer call(Integer x); }
p ublic static void main(String[] args)
{
final Integer a = 5; // in Java 7 this has to be declared f inal in 8 it i s not necessary
Ftype f = new Ftype() {
public Integer call(Integer x) { return a+x; };
};
System.out.println(f.call(10)); // 15
// a = 100; <-- this would provoke a compilation error e ven if a was n ot explicitly final
// System.out.println(f.call(10));
}
}
C++11 [=]
#include <iostream>
int main() {
int a = 5;
auto f = [=] (int x) { return x + a; }; // or [a] ...
std::cout << f(10) << std::endl; // 15
a = 100;
std::cout << f(10) << std::endl; // 15
return 0;
}
GNU Octave
a = 5
f = @(x)x+a
disp(f(10)) # 1 5
a = 100
disp(f(10)) # 1 5
Factor (curry)
USING: kernel locals formatting math ;
IN: test_closures
:: test-closures ( -- )
5 :> a!
a [ + ] curry :> f
10 f call "%d\n" printf ! 15
100 a!
10 f call "%d\n" printf ! 15
;
JavasScript
a = 5;
f = function(a) {
return function(x) { return x+a };
}(a);
console.log(f(10)); // 15
a = 100
console.log(f(10)); // 15
ame limitations as with CoffeeScript
# s
[
a = [5]]
f = w ith_local { |a| ->(x){ x + a[0][0] } }
puts f[10] # 15
a[0][0] = 100
puts f[10] # 110
Ruby
for Ruby < 1.9.2 wed have add another identifier; note that for Ruby < 1.9 the inner a should be
renamed
def with_local(*args)
yield *args.map(&:dup)
end
a = 5
f = with_local(a) { |a| ->(x){ x + a } }
puts f[10] # 15
a = 100
puts f[10] # 15
Mathematica
a = 5
f = With[{a = a
}, F
unction[{x}, x + a]] (* Module could also be used *)
Print[f[10]] (* 1 5 *)
a = 100
Print[f[10]] (* 1 5 *)
Java 8
hat Java protection against u
Note t sing non-(effectively)-final v ariables in lambdas is not deep, so
that t he mutable behaviour can be a chieved just by wrapping the v ariables:
Java
hat Java protection against u
Note t sing non-(effectively)-final v ariables in lambdas is not deep, so
that t he mutable behaviour can be a chieved just by wrapping the v ariables:
C++11
Note an a rray captured by value is immutable:
#include <iostream>
int main() {
int a[1] = {5};
auto f = [=] (int x) { return x + a[0]; }; // or [a] ...
std::cout << f(10) << std::endl; // 15
a[0] = 100;
std::cout << f(10) << std::endl; // 15
return 0;
}
But using pointers will of course defeat the mutability protection:
#include <iostream>
int main() {
int *a = new int;
*a = 5;
auto f = [=] (int x) { return x + *a; }; // or [a] ...
std::cout << f(10) << std::endl; // 15
*a = 100;
std::cout << f(10) << std::endl; // 110
return 0;
}
Resources:
http://ideone.com/
http://www.compilejava.net/
http://repl.it/
http://perlcabal.org/~fglock/perlito5.html
http://octave-online.net/
http://sandbox.onlinephpfunctions.com/
https://try.dartlang.org/
http://maxima-online.org/
http://www.tutorialspoint.com/
Visual Basic.NET
Imports System
Public Class Test
Public Shared Sub Main()
Dim a = 5
Dim f = Function(x) x+a
Console.WriteLine(f(10)) ' 15
a = 100
Console.WriteLine(f(100)) ' ?
End Sub
End Class