Accumulator factory: Difference between revisions

Content added Content deleted
(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}}==