Accumulator factory: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
|||
Line 66: | Line 66: | ||
16 |
16 |
||
</pre> |
</pre> |
||
=={{header|ABAP}}== |
=={{header|ABAP}}== |
||
ABAP, unfortunately, has no first order functions, nor does its OO paradigm implement method overloading. One potential solution to this problem is to use classes to maintain the state, with the import/export parameters being defined as type 'any', so that the resultant type is calculated dynamically. |
ABAP, unfortunately, has no first order functions, nor does its OO paradigm implement method overloading. One potential solution to this problem is to use classes to maintain the state, with the import/export parameters being defined as type 'any', so that the resultant type is calculated dynamically. |
||
Line 485: | Line 486: | ||
Output: |
Output: |
||
<pre>83/10</pre> |
<pre>83/10</pre> |
||
=={{header|Brat}}== |
=={{header|Brat}}== |
||
<lang brat>accumulator = { sum | |
<lang brat>accumulator = { sum | |
||
Line 515: | Line 517: | ||
printf ("%c\n", z(5)); /* f */ |
printf ("%c\n", z(5)); /* f */ |
||
return 0; |
return 0; |
||
}</lang> |
|||
=={{header|C sharp|C#}}== |
|||
{{works with|C sharp|4.0}} |
|||
<lang csharp>using System; |
|||
class Program |
|||
{ |
|||
static Func<dynamic, dynamic> Foo(dynamic n) |
|||
{ |
|||
return i => n += i; |
|||
} |
|||
static void Main(string[] args) |
|||
{ |
|||
var x = Foo(1); |
|||
x(5); |
|||
Foo(3); |
|||
Console.WriteLine(x(2.3)); |
|||
} |
|||
}</lang> |
}</lang> |
||
Line 686: | Line 708: | ||
} |
} |
||
</lang> |
</lang> |
||
=={{header|C sharp|C#}}== |
|||
{{works with|C sharp|4.0}} |
|||
<lang csharp>using System; |
|||
class Program |
|||
{ |
|||
static Func<dynamic, dynamic> Foo(dynamic n) |
|||
{ |
|||
return i => n += i; |
|||
} |
|||
static void Main(string[] args) |
|||
{ |
|||
var x = Foo(1); |
|||
x(5); |
|||
Foo(3); |
|||
Console.WriteLine(x(2.3)); |
|||
} |
|||
}</lang> |
|||
=={{header|Ceylon}}== |
=={{header|Ceylon}}== |
||
Line 795: | Line 797: | ||
8.3 |
8.3 |
||
</pre> |
</pre> |
||
=={{header|Crystal}}== |
=={{header|Crystal}}== |
||
<lang crystal> |
<lang crystal> |
||
Line 810: | Line 813: | ||
puts x.call(2.4) #=> 22.4 |
puts x.call(2.4) #=> 22.4 |
||
</lang> |
</lang> |
||
=={{header|D}}== |
=={{header|D}}== |
||
Line 978: | Line 982: | ||
-11.7 10.3 |
-11.7 10.3 |
||
</pre> |
</pre> |
||
=={{header|F Sharp|F#}}== |
|||
A statically typed version is not possible, but it is quite easy to write dynamically typed functions in F#: |
|||
<lang fsharp>// dynamically typed add |
|||
let add (x: obj) (y: obj) = |
|||
match x, y with |
|||
| (:? int as m), (:? int as n) -> box(m+n) |
|||
| (:? int as n), (:? float as x) |
|||
| (:? float as x), (:? int as n) -> box(x + float n) |
|||
| (:? float as x), (:? float as y) -> box(x + y) |
|||
| _ -> failwith "Run-time type error" |
|||
let acc init = |
|||
let state = ref (box init) |
|||
fun y -> |
|||
state := add !state (box y) |
|||
!state |
|||
do |
|||
let x : obj -> obj = acc 1 |
|||
printfn "%A" (x 5) // prints "6" |
|||
acc 3 |> ignore |
|||
printfn "%A" (x 2.3) // prints "8.3"</lang> |
|||
Actually, it is possible to create a statically typed version by using an inline accumulator creation function. |
|||
<lang fsharp>let inline makeAccumulator init = |
|||
let acc = ref init |
|||
fun i -> |
|||
acc := !acc + i |
|||
!acc |
|||
do |
|||
let acc = makeAccumulator 1.0 // create a float accumulator |
|||
acc 5.0 |> ignore |
|||
let _ = makeAccumulator 3 // create an unused integer accumulator |
|||
printfn "%A" (acc 2.3)</lang> |
|||
{{out}} |
|||
<pre>8.3</pre> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
Line 1,066: | Line 1,109: | ||
2.3e x f. |
2.3e x f. |
||
</lang> |
</lang> |
||
=={{header|F Sharp|F#}}== |
|||
A statically typed version is not possible, but it is quite easy to write dynamically typed functions in F#: |
|||
<lang fsharp>// dynamically typed add |
|||
let add (x: obj) (y: obj) = |
|||
match x, y with |
|||
| (:? int as m), (:? int as n) -> box(m+n) |
|||
| (:? int as n), (:? float as x) |
|||
| (:? float as x), (:? int as n) -> box(x + float n) |
|||
| (:? float as x), (:? float as y) -> box(x + y) |
|||
| _ -> failwith "Run-time type error" |
|||
let acc init = |
|||
let state = ref (box init) |
|||
fun y -> |
|||
state := add !state (box y) |
|||
!state |
|||
do |
|||
let x : obj -> obj = acc 1 |
|||
printfn "%A" (x 5) // prints "6" |
|||
acc 3 |> ignore |
|||
printfn "%A" (x 2.3) // prints "8.3"</lang> |
|||
Actually, it is possible to create a statically typed version by using an inline accumulator creation function. |
|||
<lang fsharp>let inline makeAccumulator init = |
|||
let acc = ref init |
|||
fun i -> |
|||
acc := !acc + i |
|||
!acc |
|||
do |
|||
let acc = makeAccumulator 1.0 // create a float accumulator |
|||
acc 5.0 |> ignore |
|||
let _ = makeAccumulator 3 // create an unused integer accumulator |
|||
printfn "%A" (acc 2.3)</lang> |
|||
{{out}} |
|||
<pre>8.3</pre> |
|||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
Line 2,338: | Line 2,341: | ||
del af : del a : del b : del c |
del af : del a : del b : del c |
||
</pre> |
</pre> |
||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Line 2,405: | Line 2,407: | ||
{{out}} |
{{out}} |
||
<pre>8.3</pre> |
<pre>8.3</pre> |
||
=={{header|Perl 6}}== |
|||
{{works with|Rakudo|2018.03}} |
|||
<lang perl6>sub accum ($n is copy) { sub { $n += $^x } } |
|||
#Example use: |
|||
my $a = accum 5; |
|||
$a(4.5); |
|||
say $a(.5); # Prints "10". |
|||
# You can also use the "&" sigil to create a function that behaves syntactically |
|||
# like any other function (i.e. no sigil nor parentheses needed to call it): |
|||
my &b = accum 5; |
|||
say b 3; # Prints "8".</lang> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 2,699: | Line 2,686: | ||
n) |
n) |
||
</lang> |
</lang> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{works with|Rakudo|2018.03}} |
|||
<lang perl6>sub accum ($n is copy) { sub { $n += $^x } } |
|||
#Example use: |
|||
my $a = accum 5; |
|||
$a(4.5); |
|||
say $a(.5); # Prints "10". |
|||
# You can also use the "&" sigil to create a function that behaves syntactically |
|||
# like any other function (i.e. no sigil nor parentheses needed to call it): |
|||
my &b = accum 5; |
|||
say b 3; # Prints "8".</lang> |
|||
=={{header|REBOL}}== |
=={{header|REBOL}}== |
||
Line 2,933: | Line 2,936: | ||
Accumulator(3); |
Accumulator(3); |
||
say x(2.3); # prints: 8.3</lang> |
say x(2.3); # prints: 8.3</lang> |
||
=={{header|Simula}}== |
=={{header|Simula}}== |
||
<lang simula>BEGIN |
<lang simula>BEGIN |
||
Line 3,127: | Line 3,131: | ||
% puts ">>[$x 2.3]<<" |
% puts ">>[$x 2.3]<<" |
||
>>8.3<<</lang> |
>>8.3<<</lang> |
||
=={{header|Unicon}}== |
|||
Strictly speaking, <tt>genAcc(n)</tt> returns a <i>co-expression</i>, not a function. However, the invocation syntax here is indistinguishable from calling a function. |
|||
<lang Unicon>procedure main() |
|||
a := genAcc(3) |
|||
b := genAcc(5) |
|||
write(" " ,center("a",5), " ", center("b", 5)) |
|||
write("genAcc: ", right(a(4),5), " ", right(b(4), 5)) |
|||
write("genAcc: ", right(a(2),5), " ", right(b(3),5)) |
|||
write("genAcc: ", right(a(4.5),5)," ", right(b(1.3),5)) |
|||
end |
|||
procedure genAcc(n) # The generator factory |
|||
return makeProc { while i := (n@&source)[1] do n +:= i } |
|||
end |
|||
procedure makeProc(A) # A Programmer-Defined Control Operation |
|||
return (@A[1],A[1]) |
|||
end</lang> |
|||
Note: The co-expression calling sequence used is Unicon specific. |
|||
{{out}} |
|||
<pre> |
|||
a b |
|||
genAcc: 7 9 |
|||
genAcc: 9 12 |
|||
genAcc: 13.5 13.3 |
|||
</pre> |
|||
=={{header|TXR}}== |
=={{header|TXR}}== |
||
Line 3,231: | Line 3,207: | ||
(let ((f (new (accum 0)))) |
(let ((f (new (accum 0)))) |
||
(mapdo (do put-line `@1 -> @[f @1]`) (gun (iread : : nil))))</lang> |
(mapdo (do put-line `@1 -> @[f @1]`) (gun (iread : : nil))))</lang> |
||
=={{header|Unicon}}== |
|||
Strictly speaking, <tt>genAcc(n)</tt> returns a <i>co-expression</i>, not a function. However, the invocation syntax here is indistinguishable from calling a function. |
|||
<lang Unicon>procedure main() |
|||
a := genAcc(3) |
|||
b := genAcc(5) |
|||
write(" " ,center("a",5), " ", center("b", 5)) |
|||
write("genAcc: ", right(a(4),5), " ", right(b(4), 5)) |
|||
write("genAcc: ", right(a(2),5), " ", right(b(3),5)) |
|||
write("genAcc: ", right(a(4.5),5)," ", right(b(1.3),5)) |
|||
end |
|||
procedure genAcc(n) # The generator factory |
|||
return makeProc { while i := (n@&source)[1] do n +:= i } |
|||
end |
|||
procedure makeProc(A) # A Programmer-Defined Control Operation |
|||
return (@A[1],A[1]) |
|||
end</lang> |
|||
Note: The co-expression calling sequence used is Unicon specific. |
|||
{{out}} |
|||
<pre> |
|||
a b |
|||
genAcc: 7 9 |
|||
genAcc: 9 12 |
|||
genAcc: 13.5 13.3 |
|||
</pre> |
|||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
Line 3,301: | Line 3,305: | ||
8.3 |
8.3 |
||
</pre> |
</pre> |
||
=={{header|Wart}}== |
|||
<lang python>def (accumulator n) |
|||
(fn() ++n)</lang> |
|||
Example usage: |
|||
<pre>a <- (accumulator 3) |
|||
(a) |
|||
=> 4 |
|||
(a) |
|||
=> 5 |
|||
b <- (accumulator 23) |
|||
(b) |
|||
=> 24 |
|||
(a) |
|||
=> 6</pre> |
|||
=={{header|XLISP}}== |
=={{header|XLISP}}== |
||
Line 3,324: | Line 3,344: | ||
15</pre> |
15</pre> |
||
=={{header|Wart}}== |
|||
<lang python>def (accumulator n) |
|||
(fn() ++n)</lang> |
|||
Example usage: |
|||
<pre>a <- (accumulator 3) |
|||
(a) |
|||
=> 4 |
|||
(a) |
|||
=> 5 |
|||
b <- (accumulator 23) |
|||
(b) |
|||
=> 24 |
|||
(a) |
|||
=> 6</pre> |
|||
=={{header|Yabasic}}== |
=={{header|Yabasic}}== |