Currying: Difference between revisions

4,260 bytes added ,  2 months ago
m
(Replace println() with print(); replace output "syntaxhighlight" tag with "pre" tag)
 
(18 intermediate revisions by 13 users not shown)
Line 253:
{{Out}}
<pre>{«script», «script», 5, {7, 14, 21, 28, 35, 42, 49, 56, 63, 70}}</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">addN: function [n][
return function [x] with 'n [
return x + n
]
]
 
add2: addN 2
add3: addN 3
 
do [
print add2 7
print add3 7
]</syntaxhighlight>
 
{{out}}
 
<pre>9
10</pre>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
FreeBASIC is not a functional language and does not support either currying or nested functions/lambdas which are typically used by otherwise imperative languages to implement the former. The nearest I could get to currying using the features which the language does support is the following:
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Type CurriedAdd
As Integer i
Declare Function add(As Integer) As Integer
End Type
 
Function CurriedAdd.add(j As Integer) As Integer
Return i + j
End Function
 
Function add (i As Integer) as CurriedAdd
Return Type<CurriedAdd>(i)
End Function
 
Print "3 + 4 ="; add(3).add(4)
Print "2 + 6 ="; add(2).add(6)
Sleep</syntaxhighlight>
 
{{out}}
<pre>
3 + 4 = 7
2 + 6 = 8
</pre>
 
==={{header|Visual Basic .NET}}===
'''Compiler:''' Roslyn Visual Basic (language version >=15.3)
 
Functions are not curried in VB.NET, so this entry details functions that take a function and return functions that act as if the original function were curried (i.e. each takes one parameter and returns another function that takes one parameter, with the function for which all parameters of the original function are supplied calling the original function with those arguments.
 
====Fixed-arity approach====
Uses generics and lambdas returning lambdas.
<syntaxhighlight lang="vbnet">Option Explicit On
Option Infer On
Option Strict On
 
Module Currying
' The trivial curry.
Function Curry(Of T1, TResult)(func As Func(Of T1, TResult)) As Func(Of T1, TResult)
' At least satisfy the implicit contract that the result isn't reference-equal to the original function.
Return Function(a) func(a)
End Function
 
Function Curry(Of T1, T2, TResult)(func As Func(Of T1, T2, TResult)) As Func(Of T1, Func(Of T2, TResult))
Return Function(a) Function(b) func(a, b)
End Function
 
Function Curry(Of T1, T2, T3, TResult)(func As Func(Of T1, T2, T3, TResult)) As Func(Of T1, Func(Of T2, Func(Of T3, TResult)))
Return Function(a) Function(b) Function(c) func(a, b, c)
End Function
 
' And so on.
End Module</syntaxhighlight>
 
Test code:
<syntaxhighlight lang="vbnet">Module Main
' An example binary function.
Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
 
Sub Main()
Dim curriedAdd = Curry(Of Integer, Integer, Integer)(AddressOf Add)
Dim add2To = curriedAdd(2)
 
Console.WriteLine(Add(2, 3))
Console.WriteLine(add2To(3))
Console.WriteLine(curriedAdd(2)(3))
 
' An example ternary function.
Dim substring = Function(s As String, startIndex As Integer, length As Integer) s.Substring(startIndex, length)
Dim curriedSubstring = Curry(substring)
 
Console.WriteLine(substring("abcdefg", 2, 3))
Console.WriteLine(curriedSubstring("abcdefg")(2)(3))
 
' The above is just syntax sugar for this (a call to the Invoke() method of System.Delegate):
Console.WriteLine(curriedSubstring.Invoke("abcdefg").Invoke(2).Invoke(3))
 
Dim substringStartingAt1 = curriedSubstring("abcdefg")(1)
Console.WriteLine(substringStartingAt1(2))
Console.WriteLine(substringStartingAt1(4))
End Sub
End Module</syntaxhighlight>
 
====Late-binding approach====
 
{{libheader|.NET Core|2=>=1.0}}
or both
{{libheader|.NET Framework|2=>=4.5}}
and
{{libheader|System.Collections.Immutable|1.5.0}}
 
Due to VB's syntax, with indexers using parentheses, late-bound invocation expressions are compiled as invocations of the default property of the receiver. Thus, it is not possible to perform a late-bound delegate invocation. This limitation can, however, be circumvented, by declaring a type that wraps a delegate and defines a default property that invokes the delegate. Furthermore, by making this type what is essentially a discriminated union of a delegate and a result and guaranteeing that all invocations return another instance of this type, it is possible for the entire system to work with Option Strict on.
 
<syntaxhighlight lang="vbnet">Option Explicit On
Option Infer On
Option Strict On
 
Module CurryingDynamic
' Cheat visual basic's syntax by defining a type that can be the receiver of what appears to be a method call.
' Needless to say, this is not idiomatic VB.
Class CurryDelegate
ReadOnly Property Value As Object
ReadOnly Property Target As [Delegate]
 
Sub New(value As Object)
Dim curry = TryCast(value, CurryDelegate)
If curry IsNot Nothing Then
Me.Value = curry.Value
Me.Target = curry.Target
ElseIf TypeOf value Is [Delegate] Then
Me.Target = DirectCast(value, [Delegate])
Else
Me.Value = value
End If
End Sub
 
' CurryDelegate could also work as a dynamic n-ary function delegate, if an additional ParamArray argument were to be added.
Default ReadOnly Property Invoke(arg As Object) As CurryDelegate
Get
If Me.Target Is Nothing Then Throw New InvalidOperationException("All curried parameters have already been supplied")
 
Return New CurryDelegate(Me.Target.DynamicInvoke({arg}))
End Get
End Property
 
' A syntactically natural way to assert that the currying is complete and that the result is of the specified type.
Function Unwrap(Of T)() As T
If Me.Target IsNot Nothing Then Throw New InvalidOperationException("Some curried parameters have not yet been supplied.")
Return DirectCast(Me.Value, T)
End Function
End Class
 
Function DynamicCurry(func As [Delegate]) As CurryDelegate
Return DynamicCurry(func, ImmutableList(Of Object).Empty)
End Function
 
' Use ImmutableList to create a new list every time any curried subfunction is called avoiding multiple or repeated
' calls interfering with each other.
Private Function DynamicCurry(func As [Delegate], collectedArgs As ImmutableList(Of Object)) As CurryDelegate
Return If(collectedArgs.Count = func.Method.GetParameters().Length,
New CurryDelegate(func.DynamicInvoke(collectedArgs.ToArray())),
New CurryDelegate(Function(arg As Object) DynamicCurry(func, collectedArgs.Add(arg))))
End Function
End Module</syntaxhighlight>
 
Test code:
<syntaxhighlight lang="vbnet">Module Program
Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
 
Sub Main()
' A delegate for the function must be created in order to eagerly perform overload resolution.
Dim curriedAdd = DynamicCurry(New Func(Of Integer, Integer, Integer)(AddressOf Add))
Dim add2To = curriedAdd(2)
 
Console.WriteLine(add2To(3).Unwrap(Of Integer))
Console.WriteLine(curriedAdd(2)(3).Unwrap(Of Integer))
 
Dim substring = Function(s As String, i1 As Integer, i2 As Integer) s.Substring(i1, i2)
Dim curriedSubstring = DynamicCurry(substring)
 
Console.WriteLine(substring("abcdefg", 2, 3))
Console.WriteLine(curriedSubstring("abcdefg")(2)(3).Unwrap(Of String))
 
' The trickery of using a parameterized default property also makes it appear that the "delegate" has an Invoke() method.
Console.WriteLine(curriedSubstring.Invoke("abcdefg").Invoke(2).Invoke(3).Unwrap(Of String))
 
Dim substringStartingAt1 = curriedSubstring("abcdefg")(1)
Console.WriteLine(substringStartingAt1(2).Unwrap(Of String))
Console.WriteLine(substringStartingAt1(4).Unwrap(Of String))
End Sub
End Module
</syntaxhighlight>
 
{{out|note=for both versions}}
<pre>5
5
5
cde
cde
cde
bc
bcde</pre>
 
=={{header|Binary Lambda Calculus}}==
 
In BLC, all multi argument functions are necessarily achieved by currying, since lambda calculus functions (lambdas) are single argument. A good example is the Church numeral 2, which given a function f and an argument x, applies f twice on x: C2 = \f. (\x. f (f x)). This is written in BLC as
 
<pre>00 00 01 110 01 110 01</pre>
 
where 00 denotes lambda, 01 denotes application, and 1^n0 denotes the variable bound by the n'th enclosing lambda. Which is all there is to BCL!
 
=={{header|BQN}}==
Line 265 ⟶ 484:
<syntaxhighlight lang="text">4
4</syntaxhighlight>
 
 
 
=={{header|C}}==
Line 428 ⟶ 645:
 
=={{header|EchoLisp}}==
[[EchoLisp]] has native support for curry, which is implemented thru closures, as shown in [[CommonLisp#Common_Lisp|Common Lisp]] .
<syntaxhighlight lang="text">
;;
Line 453 ⟶ 670:
=={{header|Ecstasy}}==
<syntaxhighlight lang="java">
module CurryPower {
{
@Inject Console console;
void run() {
function Int(Int, Int) divide = (x,y) -> x / y;
{
function Int(Int, Int) divide = (x,y) -> x /half y = divide(_, 2);
function Int(Int) partsOf120 = divide(120, _);
 
function Int(Int) half = divide(_, 2);
function Int(Int) partsOf120 = divide(120, _);
 
console.print($|half of a dozen is {half(12)}
Line 468 ⟶ 682:
|and a quarter is {partsOf120(4)}
);
}
}
}
</syntaxhighlight>
 
Line 523 ⟶ 737:
 
where FUNCTION [ANY, TUPLE [Y], Z] denotes the type ''Y'' → ''Z'' (agents taking as argument a tuple with a single argument of type Y and returning a result of type Z), which is indeed the type of the agent expression used on the next-to-last line to define the "Result" of g.
 
=={{header|Elixir}}==
 
<pre>
iex(1)> plus = fn x, y -> x + y end
#Function<41.125776118/2 in :erl_eval.expr/6>
iex(2)> plus.(3, 5)
8
iex(3)> plus5 = &plus.(5, &1)
#Function<42.125776118/1 in :erl_eval.expr/6>
iex(4)> plus5.(3)
8
</pre>
 
=={{header|EMal}}==
{{trans|C#}}
<syntaxhighlight lang="emal">
fun plus = fun by int y
return int by int x do return x + y end
end
int sum0 = plus(3)(4)
int sum1 = plus(2)(plus(3)(4))
writeLine(sum0)
writeLine(sum1)
</syntaxhighlight>
{{out}}
<pre>
7
9
</pre>
 
=={{header|Erlang}}==
Line 693 ⟶ 937:
<pre>10 12</pre>
 
=={{header|FreeBASIC}}==
FreeBASIC is not a functional language and does not support either currying or nested functions/lambdas which are typically used by otherwise imperative languages to implement the former. The nearest I could get to currying using the features which the language does support is the following:
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
=={{header|Fōrmulæ}}==
Type CurriedAdd
As Integer i
Declare Function add(As Integer) As Integer
End Type
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Currying}}
Function CurriedAdd.add(j As Integer) As Integer
Return i + j
End Function
 
'''Solution'''
Function add (i As Integer) as CurriedAdd
Return Type<CurriedAdd>(i)
End Function
 
In Fōrmulæ, a function is just a named lambda expression, and a function call is just a lambda application.
Print "3 + 4 ="; add(3).add(4)
Print "2 + 6 ="; add(2).add(6)
Sleep</syntaxhighlight>
 
The following is a simple definition of a lambda expression:
{{out}}
<pre>
3 + 4 = 7
2 + 6 = 8
</pre>
 
=={{header|[[File:Fōrmulæ}}== - Currying 01.png]]
 
When a lambda application is called with the same number of arguments, the result is the habitual:
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
[[File:Fōrmulæ - Currying 02.png]]
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - Currying 03.png]]
In '''[https://formulae.org/?example=Currying this]''' page you can see the program(s) related to this task and their results.
 
However, if a less number of parameters is applied, currying is performed. Notice that the result is another lambda expression.
 
[[File:Fōrmulæ - Currying 04.png]]
 
[[File:Fōrmulæ - Currying 05.png]]
 
Because the result is a lambda expression, it can be used in a lambda application, so we must get the same result:
 
[[File:Fōrmulæ - Currying 06.png]]
 
[[File:Fōrmulæ - Currying 03.png]]
 
Using functions:
 
[[File:Fōrmulæ - Currying 07.png]]
 
[[File:Fōrmulæ - Currying 08.png]]
 
=={{header|GDScript}}==
{{trans|Python}}
 
Uses Godot 4's lambdas. This runs as a script attached to a node.
<syntaxhighlight lang="gdscript">
extends Node
 
func addN(n: int) -> Callable:
return func(x):
return n + x
 
func _ready():
# Test currying
var add2 := addN(2)
print(add2.call(7))
 
get_tree().quit() # Exit
</syntaxhighlight>
 
=={{header|Go}}==
Line 1,210 ⟶ 1,475:
 
</pre>
 
A shorter form of the above function, also without type specification:
<syntaxhighlight lang="julia">
addN(n) = x -> n + x
</syntaxhighlight>
 
=={{header|Kotlin}}==
Line 1,357 ⟶ 1,627:
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module LikeCppLikeGroovy {
divide=lambda (x, y)->x/y
partsof120=lambda divide ->divide(120, ![], 120)
Print "half of 120 is ";partsof120(2)
Print "a third is ";partsof120(3)
Print "and a quarter is ";partsof120(4)
}
LikeGroovy
LikeCpp
 
Module Joke {
Line 1,451 ⟶ 1,721:
Out[5]:= 5
</pre>
 
=={{header|MiniScript}}==
{{trans|Rust}}
<syntaxhighlight lang="miniscript">addN = function(n)
f = function(x)
return n + x
end function
return @f
end function
 
adder = addN(40)
print "The answer to life is " + adder(2) + "."</syntaxhighlight>
 
{{out}}
<pre>The answer to life is 42.</pre>
 
=={{header|Nemerle}}==
Line 1,959 ⟶ 2,244:
add2: procedure; return add( arg(1), 2)</syntaxhighlight>
{{out|output|text=&nbsp; is identical to the 1<sup>st</sup> REXX version.}} <br><br>
 
=={{header|RPL}}==
RPL has not been designed as a functional programming language, but appropriate words can be created so that it becomes almost one.
For RPL, all programs are functions that can take arguments (or not) from the stack. Programs can easily be converted into strings: it is then possible to have a program rewrite another one, in order to insert the desired argument in the code, thus avoiding to pick it in the stack.
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ 2 OVER SIZE 1 - SUB
≫ ''''SHAVE'''' STO
→STR '''SHAVE'''
"≪" ROT →STR
IF LAST TYPE 6 == THEN '''SHAVE''' END +
" SWAP " + SWAP + STR→
≫ ''''CURRX'''' STO
→STR '''SHAVE'''
"≪" ROT →STR
IF LAST TYPE 6 == THEN '''SHAVE''' END +
SWAP + STR→
≫ ''''CURRY'''' STO
|
'''SHAVE''' ''( "abcde" -- "bcd" )''
'''CURRX''' ''( a ≪( x y -- z )≫ -- ≪( a y -- z )≫ )''
convert function to string and remove delimiters
rewrite the program beginning
if a is an object name, remove its delimiters
add a SWAP instruction to put a at stack level 2
'''CURRY''' ''( a ≪( x y -- z )≫ -- ≪( x a -- z )≫ )''
convert function to string and remove delimiters
rewrite the program beginning
if a is an object name, remove its delimiters
put the call to a at level 1
|}
Let's demonstrate the curryfication on the following function :
≪ SQ SWAP SQ SWAP - ≫
which calculates <code>x² - y²</code> on x and y passed as arguments resp. in levels 2 and 1 of the stack. The following sequence of instructions:
5 ≪ SQ SWAP SQ SWAP - ≫ '''CURRX''' 'D2SQY' STO
returns a curryfied program stored as the word <code>D2SQY</code>. We can then check it works as planned:
'Y' D2SQY
will return
1: '25-SQ(Y)'
Similarly:
5 ≪ SQ SWAP SQ SWAP - ≫ '''CURRY''' 'D2SQX' STO
will return a new program named <code>D2SQX</code>, which effect on the 'X' argument at stack level 1 will be:
1: 'SQ(X)-25'
It is also possible to pass the reference to the function to be curryfied, rather than the function itself. if <code>≪ SQ SWAP SQ SWAP - ≫</code> is stored as <code>D2SQ</code>, the following command line will have the same effect as above:
5 'D2SQ' '''CURRY''' 'D2SQX' STO
 
=={{header|Ruby}}==
Line 2,110 ⟶ 2,453:
9
</pre>
 
=={{header|Visual Basic .NET}}==
'''Compiler:''' Roslyn Visual Basic (language version >=15.3)
 
Functions are not curried in VB.NET, so this entry details functions that take a function and return functions that act as if the original function were curried (i.e. each takes one parameter and returns another function that takes one parameter, with the function for which all parameters of the original function are supplied calling the original function with those arguments.
 
===Fixed-arity approach===
 
Uses generics and lambdas returning lambdas.
 
<syntaxhighlight lang="vbnet">Option Explicit On
Option Infer On
Option Strict On
 
Module Currying
' The trivial curry.
Function Curry(Of T1, TResult)(func As Func(Of T1, TResult)) As Func(Of T1, TResult)
' At least satisfy the implicit contract that the result isn't reference-equal to the original function.
Return Function(a) func(a)
End Function
 
Function Curry(Of T1, T2, TResult)(func As Func(Of T1, T2, TResult)) As Func(Of T1, Func(Of T2, TResult))
Return Function(a) Function(b) func(a, b)
End Function
 
Function Curry(Of T1, T2, T3, TResult)(func As Func(Of T1, T2, T3, TResult)) As Func(Of T1, Func(Of T2, Func(Of T3, TResult)))
Return Function(a) Function(b) Function(c) func(a, b, c)
End Function
 
' And so on.
End Module</syntaxhighlight>
 
Test code:
<syntaxhighlight lang="vbnet">Module Main
' An example binary function.
Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
 
Sub Main()
Dim curriedAdd = Curry(Of Integer, Integer, Integer)(AddressOf Add)
Dim add2To = curriedAdd(2)
 
Console.WriteLine(Add(2, 3))
Console.WriteLine(add2To(3))
Console.WriteLine(curriedAdd(2)(3))
 
' An example ternary function.
Dim substring = Function(s As String, startIndex As Integer, length As Integer) s.Substring(startIndex, length)
Dim curriedSubstring = Curry(substring)
 
Console.WriteLine(substring("abcdefg", 2, 3))
Console.WriteLine(curriedSubstring("abcdefg")(2)(3))
 
' The above is just syntax sugar for this (a call to the Invoke() method of System.Delegate):
Console.WriteLine(curriedSubstring.Invoke("abcdefg").Invoke(2).Invoke(3))
 
Dim substringStartingAt1 = curriedSubstring("abcdefg")(1)
Console.WriteLine(substringStartingAt1(2))
Console.WriteLine(substringStartingAt1(4))
End Sub
End Module</syntaxhighlight>
 
===Late-binding approach===
 
{{libheader|.NET Core|2=>=1.0}}
or both
{{libheader|.NET Framework|2=>=4.5}}
and
{{libheader|System.Collections.Immutable|1.5.0}}
 
Due to VB's syntax, with indexers using parentheses, late-bound invocation expressions are compiled as invocations of the default property of the receiver. Thus, it is not possible to perform a late-bound delegate invocation. This limitation can, however, be circumvented, by declaring a type that wraps a delegate and defines a default property that invokes the delegate. Furthermore, by making this type what is essentially a discriminated union of a delegate and a result and guaranteeing that all invocations return another instance of this type, it is possible for the entire system to work with Option Strict on.
 
<syntaxhighlight lang="vbnet">Option Explicit On
Option Infer On
Option Strict On
 
Module CurryingDynamic
' Cheat visual basic's syntax by defining a type that can be the receiver of what appears to be a method call.
' Needless to say, this is not idiomatic VB.
Class CurryDelegate
ReadOnly Property Value As Object
ReadOnly Property Target As [Delegate]
 
Sub New(value As Object)
Dim curry = TryCast(value, CurryDelegate)
If curry IsNot Nothing Then
Me.Value = curry.Value
Me.Target = curry.Target
ElseIf TypeOf value Is [Delegate] Then
Me.Target = DirectCast(value, [Delegate])
Else
Me.Value = value
End If
End Sub
 
' CurryDelegate could also work as a dynamic n-ary function delegate, if an additional ParamArray argument were to be added.
Default ReadOnly Property Invoke(arg As Object) As CurryDelegate
Get
If Me.Target Is Nothing Then Throw New InvalidOperationException("All curried parameters have already been supplied")
 
Return New CurryDelegate(Me.Target.DynamicInvoke({arg}))
End Get
End Property
 
' A syntactically natural way to assert that the currying is complete and that the result is of the specified type.
Function Unwrap(Of T)() As T
If Me.Target IsNot Nothing Then Throw New InvalidOperationException("Some curried parameters have not yet been supplied.")
Return DirectCast(Me.Value, T)
End Function
End Class
 
Function DynamicCurry(func As [Delegate]) As CurryDelegate
Return DynamicCurry(func, ImmutableList(Of Object).Empty)
End Function
 
' Use ImmutableList to create a new list every time any curried subfunction is called avoiding multiple or repeated
' calls interfering with each other.
Private Function DynamicCurry(func As [Delegate], collectedArgs As ImmutableList(Of Object)) As CurryDelegate
Return If(collectedArgs.Count = func.Method.GetParameters().Length,
New CurryDelegate(func.DynamicInvoke(collectedArgs.ToArray())),
New CurryDelegate(Function(arg As Object) DynamicCurry(func, collectedArgs.Add(arg))))
End Function
End Module</syntaxhighlight>
 
Test code:
<syntaxhighlight lang="vbnet">Module Program
Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
 
Sub Main()
' A delegate for the function must be created in order to eagerly perform overload resolution.
Dim curriedAdd = DynamicCurry(New Func(Of Integer, Integer, Integer)(AddressOf Add))
Dim add2To = curriedAdd(2)
 
Console.WriteLine(add2To(3).Unwrap(Of Integer))
Console.WriteLine(curriedAdd(2)(3).Unwrap(Of Integer))
 
Dim substring = Function(s As String, i1 As Integer, i2 As Integer) s.Substring(i1, i2)
Dim curriedSubstring = DynamicCurry(substring)
 
Console.WriteLine(substring("abcdefg", 2, 3))
Console.WriteLine(curriedSubstring("abcdefg")(2)(3).Unwrap(Of String))
 
' The trickery of using a parameterized default property also makes it appear that the "delegate" has an Invoke() method.
Console.WriteLine(curriedSubstring.Invoke("abcdefg").Invoke(2).Invoke(3).Unwrap(Of String))
 
Dim substringStartingAt1 = curriedSubstring("abcdefg")(1)
Console.WriteLine(substringStartingAt1(2).Unwrap(Of String))
Console.WriteLine(substringStartingAt1(4).Unwrap(Of String))
End Sub
End Module
</syntaxhighlight>
 
{{out|note=for both versions}}
<pre>5
5
5
cde
cde
cde
bc
bcde</pre>
 
=={{header|Wortel}}==
Line 2,300 ⟶ 2,479:
=={{header|Wren}}==
{{trans|Rust}}
<syntaxhighlight lang="ecmascriptwren">var addN = Fn.new { |n| Fn.new { |x| n + x } }
 
var adder = addN.call(40)
56

edits