Accumulator factory: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
Line 16: Line 16:
:# Doesn't store the accumulated value or the returned functions in a way that could cause them to be inadvertently modified by other code. <small>''(No global variables or other such things.)''</small>
:# Doesn't store the accumulated value or the returned functions in a way that could cause them to be inadvertently modified by other code. <small>''(No global variables or other such things.)''</small>
: E.g. if after the example, you added the following code (in a made-up language) <small>''where the factory function is called foo''</small>:
: E.g. if after the example, you added the following code (in a made-up language) <small>''where the factory function is called foo''</small>:
:: <syntaxhighlight lang=pseudocode>x = foo(1);
:: <syntaxhighlight lang="pseudocode">x = foo(1);
x(5);
x(5);
foo(3);
foo(3);
Line 33: Line 33:


=={{header|11l}}==
=={{header|11l}}==
<syntaxhighlight lang=11l>F accumulator(n)
<syntaxhighlight lang="11l">F accumulator(n)
T Accumulator
T Accumulator
Float s
Float s
Line 62: Line 62:


=={{header|8th}}==
=={{header|8th}}==
<syntaxhighlight lang=Forth>
<syntaxhighlight lang="forth">
\ RossetaCode 'accumulator factory'
\ RossetaCode 'accumulator factory'


Line 101: Line 101:
Another possible solution would be to use the languages in-built JavaScript processing capabilities to dynamically construct a JS source at run-time, which implements the JS Accumulator factory.
Another possible solution would be to use the languages in-built JavaScript processing capabilities to dynamically construct a JS source at run-time, which implements the JS Accumulator factory.
=== Object Oriented Solution ===
=== Object Oriented Solution ===
<syntaxhighlight lang=ABAP>report z_accumulator
<syntaxhighlight lang="abap">report z_accumulator
class acc definition.
class acc definition.
public section.
public section.
Line 134: Line 134:
</pre>
</pre>
=== JavaScript Solution ===
=== JavaScript Solution ===
<syntaxhighlight lang=ABAP>data: lv_source type string,
<syntaxhighlight lang="abap">data: lv_source type string,
cl_processor type ref to cl_java_script,
cl_processor type ref to cl_java_script,
lv_ret type string.
lv_ret type string.
Line 164: Line 164:
Closures work the same in ActionScript as in JavaScript. ActionScript will transparently convert integers to reals if the function is given a real argument, but the typeof operator must be used to ensure the function isn't sent invalid arguments, such as strings (which would silently convert the accumulated number to a string without throwing an error).
Closures work the same in ActionScript as in JavaScript. ActionScript will transparently convert integers to reals if the function is given a real argument, but the typeof operator must be used to ensure the function isn't sent invalid arguments, such as strings (which would silently convert the accumulated number to a string without throwing an error).
{{trans|Javascript}}
{{trans|Javascript}}
<syntaxhighlight lang=ActionScript>//Throw an error if a non-number argument is used. (typeof evaluates to
<syntaxhighlight lang="actionscript">//Throw an error if a non-number argument is used. (typeof evaluates to
// "number" for both integers and reals)
// "number" for both integers and reals)
function checkType(obj:Object):void {
function checkType(obj:Object):void {
Line 180: Line 180:


=={{header|Ada}}==
=={{header|Ada}}==
<syntaxhighlight lang=Ada>with Accumulator;
<syntaxhighlight lang="ada">with Accumulator;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Text_IO; use Ada.Text_IO;


Line 192: Line 192:
end;</syntaxhighlight>
end;</syntaxhighlight>


<syntaxhighlight lang=Ada>generic package Accumulator is
<syntaxhighlight lang="ada">generic package Accumulator is


-- This Ada generic package represents an accumulator factory.
-- This Ada generic package represents an accumulator factory.
Line 204: Line 204:
end;</syntaxhighlight>
end;</syntaxhighlight>


<syntaxhighlight lang=Ada>package body Accumulator is
<syntaxhighlight lang="ada">package body Accumulator is


-- The accumulator lives through three states. It is in Virgin_State
-- The accumulator lives through three states. It is in Virgin_State
Line 271: Line 271:
=={{header|Aikido}}==
=={{header|Aikido}}==
{{trans|Javascript}}
{{trans|Javascript}}
<syntaxhighlight lang=aikido>function accumulator (sum:real) {
<syntaxhighlight lang="aikido">function accumulator (sum:real) {
return function(n:real) { return sum += n }
return function(n:real) { return sum += n }
}
}
Line 284: Line 284:


=={{header|Aime}}==
=={{header|Aime}}==
<syntaxhighlight lang=aime>af(list l, object o)
<syntaxhighlight lang="aime">af(list l, object o)
{
{
l[0] = l[0] + o;
l[0] = l[0] + o;
Line 304: Line 304:
<pre>8.3</pre>
<pre>8.3</pre>
The type is properly preserved over summing:
The type is properly preserved over summing:
<syntaxhighlight lang=aime> f = af.apply(list(5));
<syntaxhighlight lang="aime"> f = af.apply(list(5));


f(-6);
f(-6);
Line 324: Line 324:
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
Note: Standard ALGOL 68's scoping rules forbids exporting a '''procedure''' (or '''format''') out of it's scope (closure). Hence this specimen will run on [[ELLA ALGOL 68]], but is non-standard. For a discussion of first-class functions in ALGOL 68 consult [http://www.cs.ru.nl/~kees/home/papers/psi96.pdf "The Making of Algol 68"] - [[wp:Cornelis_H.A._Koster|C.H.A. Koster]] (1993). <!-- Retrieved April 28, 2007 -->
Note: Standard ALGOL 68's scoping rules forbids exporting a '''procedure''' (or '''format''') out of it's scope (closure). Hence this specimen will run on [[ELLA ALGOL 68]], but is non-standard. For a discussion of first-class functions in ALGOL 68 consult [http://www.cs.ru.nl/~kees/home/papers/psi96.pdf "The Making of Algol 68"] - [[wp:Cornelis_H.A._Koster|C.H.A. Koster]] (1993). <!-- Retrieved April 28, 2007 -->
<syntaxhighlight lang=algol68>MODE NUMBER = UNION(INT,REAL,COMPL);
<syntaxhighlight lang="algol68">MODE NUMBER = UNION(INT,REAL,COMPL);


PROC plus = (NUMBER in a, in b)NUMBER: (
PROC plus = (NUMBER in a, in b)NUMBER: (
Line 367: Line 367:
This has one deviation. AppleScript needs a script object for the closure on the sum <code>n</code>. So this factory returns a script object, not a handler by itself. One must call the handler through its script object, as in <code>x's call(1)</code>.
This has one deviation. AppleScript needs a script object for the closure on the sum <code>n</code>. So this factory returns a script object, not a handler by itself. One must call the handler through its script object, as in <code>x's call(1)</code>.


<syntaxhighlight lang=applescript>on accumulator(n)
<syntaxhighlight lang="applescript">on accumulator(n)
-- Returns a new script object
-- Returns a new script object
-- containing a handler.
-- containing a handler.
Line 387: Line 387:
Or, to match the task spec and output a little more closely:
Or, to match the task spec and output a little more closely:


<syntaxhighlight lang=AppleScript>on run
<syntaxhighlight lang="applescript">on run
set x to foo(1)
set x to foo(1)
Line 410: Line 410:
=={{header|Argile}}==
=={{header|Argile}}==
{{works with|Argile|1.1.1}}
{{works with|Argile|1.1.1}}
<syntaxhighlight lang=Argile>use std, array
<syntaxhighlight lang="argile">use std, array


let A = accumulator 42
let A = accumulator 42
Line 464: Line 464:
autocast accumulator<->Accumulator</syntaxhighlight>
autocast accumulator<->Accumulator</syntaxhighlight>


{{omit from|ARM Assembly}}

=={{header|Astro}}==
=={{header|Astro}}==
<syntaxhighlight lang=python>fun accumulator(var sum): :: Real -> _
<syntaxhighlight lang="python">fun accumulator(var sum): :: Real -> _
n => sum += n
n => sum += n


Line 478: Line 477:
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
This code works by copying the function FNdummy() onto the heap and returning a pointer to it.
This code works by copying the function FNdummy() onto the heap and returning a pointer to it.
<syntaxhighlight lang=bbcbasic> x = FNaccumulator(1)
<syntaxhighlight lang="bbcbasic"> x = FNaccumulator(1)
dummy = FN(x)(5)
dummy = FN(x)(5)
dummy = FNaccumulator(3)
dummy = FNaccumulator(3)
Line 498: Line 497:
=={{header|Bracmat}}==
=={{header|Bracmat}}==
Notice that Bracmat has no floating point numbers, only rational numbers.
Notice that Bracmat has no floating point numbers, only rational numbers.
<syntaxhighlight lang=bracmat>( ( accumulator
<syntaxhighlight lang="bracmat">( ( accumulator
=
=
.
.
Line 517: Line 516:


=={{header|Brat}}==
=={{header|Brat}}==
<syntaxhighlight lang=brat>accumulator = { sum |
<syntaxhighlight lang="brat">accumulator = { sum |
{ n | sum = sum + n }
{ n | sum = sum + n }
}
}
Line 530: Line 529:
Ported from [[Ruby]].
Ported from [[Ruby]].


<syntaxhighlight lang=bqn>Acc ← {
<syntaxhighlight lang="bqn">Acc ← {
𝕊 sum:
𝕊 sum:
{sum+↩𝕩}
{sum+↩𝕩}
Line 544: Line 543:
Deviation: Not in standard C, but several compilers include the typeof operator as an extension which can be used like a typedef. Functions must be defined outside of the main program body and they retain the same type throughout their life. C11 is supposed to give us some Type-generic macro expressions.
Deviation: Not in standard C, but several compilers include the typeof operator as an extension which can be used like a typedef. Functions must be defined outside of the main program body and they retain the same type throughout their life. C11 is supposed to give us some Type-generic macro expressions.


<syntaxhighlight lang=C>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
//~ Take a number n and return a function that takes a number i
//~ Take a number n and return a function that takes a number i
#define ACCUMULATOR(name,n) __typeof__(n) name (__typeof__(n) i) { \
#define ACCUMULATOR(name,n) __typeof__(n) name (__typeof__(n) i) { \
Line 565: Line 564:
=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
{{works with|C sharp|4.0}}
{{works with|C sharp|4.0}}
<syntaxhighlight lang=csharp>using System;
<syntaxhighlight lang="csharp">using System;


class Program
class Program
Line 586: Line 585:
First solution has a deviation: The return type is wrong when the accumulator is called with an integer argument after is has been called with a float argument. Later it is explained how to correct this.
First solution has a deviation: The return type is wrong when the accumulator is called with an integer argument after is has been called with a float argument. Later it is explained how to correct this.


<syntaxhighlight lang=cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>


class Acc
class Acc
Line 647: Line 646:


It suffers from the same deviation as the former, where the return type is wrong when the accumulator is called with a float argument after is has been called with an integer argument.
It suffers from the same deviation as the former, where the return type is wrong when the accumulator is called with a float argument after is has been called with an integer argument.
<syntaxhighlight lang=cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <functional>
#include <functional>


Line 666: Line 665:


The deviation stems from two sources. First, a C++ object (such as the accumulator) has an immutable type. To correct this, we must separate the accumulator from the cumulant value it holds. For example:
The deviation stems from two sources. First, a C++ object (such as the accumulator) has an immutable type. To correct this, we must separate the accumulator from the cumulant value it holds. For example:
<syntaxhighlight lang=cpp>struct CumulantBase_
<syntaxhighlight lang="cpp">struct CumulantBase_
{
{
virtual ~CumulantBase_();
virtual ~CumulantBase_();
Line 691: Line 690:


The second issue is that the built-in operator + is a multimethod, implementing a compile-time dispatch and promotion which we must manually reproduce.
The second issue is that the built-in operator + is a multimethod, implementing a compile-time dispatch and promotion which we must manually reproduce.
<syntaxhighlight lang=cpp>// still inside struct Accumulator_
<syntaxhighlight lang="cpp">// still inside struct Accumulator_
// various operator() implementations provide a de facto multimethod
// various operator() implementations provide a de facto multimethod
Accumulator_& operator()(int more)
Accumulator_& operator()(int more)
Line 723: Line 722:


These rely on coercion functions which switch on the so-far-accumulated type:
These rely on coercion functions which switch on the so-far-accumulated type:
<syntaxhighlight lang=cpp>// recognize cumulants by type
<syntaxhighlight lang="cpp">// recognize cumulants by type
boost::optional<int> CoerceInt(const CumulantBase_& c)
boost::optional<int> CoerceInt(const CumulantBase_& c)
{
{
Line 747: Line 746:


All that remains is to write to the stream:
All that remains is to write to the stream:
<syntaxhighlight lang=cpp>std::ostream& operator<<(std::ostream& dst, const Accumulator_& acc)
<syntaxhighlight lang="cpp">std::ostream& operator<<(std::ostream& dst, const Accumulator_& acc)
{
{
return acc.val_->Write(dst);
return acc.val_->Write(dst);
Line 754: Line 753:


=={{header|Ceylon}}==
=={{header|Ceylon}}==
<syntaxhighlight lang=Ceylon>shared void run() {
<syntaxhighlight lang="ceylon">shared void run() {
Integer|Float accumulator
Integer|Float accumulator
(variable Integer|Float n)
(variable Integer|Float n)
Line 781: Line 780:
=={{header|Clay}}==
=={{header|Clay}}==
To my knowledge Clay does not admit of an elegant solution to this problem, although it should be stated that I am still exploring the language. But a clean solution mirroring that for other static languages is quite simple (one in which the operative numeric type is constrained by the original call to acc):
To my knowledge Clay does not admit of an elegant solution to this problem, although it should be stated that I am still exploring the language. But a clean solution mirroring that for other static languages is quite simple (one in which the operative numeric type is constrained by the original call to acc):
<syntaxhighlight lang=Clay>acc(n) {
<syntaxhighlight lang="clay">acc(n) {
return (m) => {
return (m) => {
n = n + m;
n = n + m;
Line 795: Line 794:
}</syntaxhighlight>
}</syntaxhighlight>
Although statically typed, due to Clay’s everywhere-genericity this has the advantage of working out of the box for any type that defines addition:
Although statically typed, due to Clay’s everywhere-genericity this has the advantage of working out of the box for any type that defines addition:
<syntaxhighlight lang=Clay> var y = acc(Vector[Char]("Hello"));
<syntaxhighlight lang="clay"> var y = acc(Vector[Char]("Hello"));
println(y(" World!")); // Prints "Hello World!”.</syntaxhighlight>
println(y(" World!")); // Prints "Hello World!”.</syntaxhighlight>
But you could constrain the function to numeric types were you so inclined:
But you could constrain the function to numeric types were you so inclined:
<syntaxhighlight lang=Clay>[N | Numeric?(N)] acc(n: N) {
<syntaxhighlight lang="clay">[N | Numeric?(N)] acc(n: N) {
return (m) => {
return (m) => {
n = n + m;
n = n + m;
Line 808: Line 807:
=={{header|Clojure}}==
=={{header|Clojure}}==
The ''atom'' function creates an atomically updatable identity holding a value. The ''swap!'' function atomically updates the atom's value, returning the new value. The function returned from an ''accum'' call satisfies all the requirements.
The ''atom'' function creates an atomically updatable identity holding a value. The ''swap!'' function atomically updates the atom's value, returning the new value. The function returned from an ''accum'' call satisfies all the requirements.
<syntaxhighlight lang=clojure>(defn accum [n]
<syntaxhighlight lang="clojure">(defn accum [n]
(let [acc (atom n)]
(let [acc (atom n)]
(fn [m] (swap! acc + m))))</syntaxhighlight>
(fn [m] (swap! acc + m))))</syntaxhighlight>
Similarly, a ''ref'' could be used.
Similarly, a ''ref'' could be used.
<syntaxhighlight lang=clojure>(defn accum [n]
<syntaxhighlight lang="clojure">(defn accum [n]
(let [acc (ref n)]
(let [acc (ref n)]
#(dosync (alter acc + %))))</syntaxhighlight>
#(dosync (alter acc + %))))</syntaxhighlight>


=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
<syntaxhighlight lang=coffeescript>accumulator = (sum) ->
<syntaxhighlight lang="coffeescript">accumulator = (sum) ->
(n) -> sum += n
(n) -> sum += n
Line 826: Line 825:
=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
{{trans|TXR}}
{{trans|TXR}}
<syntaxhighlight lang=lisp>(defun accumulator (sum)
<syntaxhighlight lang="lisp">(defun accumulator (sum)
(lambda (n)
(lambda (n)
(incf sum n)))</syntaxhighlight>
(incf sum n)))</syntaxhighlight>
Example usage:
Example usage:
<syntaxhighlight lang=lisp>(defvar x (accumulator 1))
<syntaxhighlight lang="lisp">(defvar x (accumulator 1))
(funcall x 5)
(funcall x 5)
(accumulator 3)
(accumulator 3)
Line 843: Line 842:


=={{header|Crystal}}==
=={{header|Crystal}}==
<syntaxhighlight lang=crystal>
<syntaxhighlight lang="crystal">
# Make types a bit easier with an alias
# Make types a bit easier with an alias
alias Num = Int32 | Int64 | Float32 | Float64
alias Num = Int32 | Int64 | Float32 | Float64
Line 860: Line 859:
=={{header|D}}==
=={{header|D}}==


<syntaxhighlight lang=d>import std.stdio;
<syntaxhighlight lang="d">import std.stdio;


void main() {
void main() {
Line 881: Line 880:


Implementation with dynamic typing:
Implementation with dynamic typing:
<syntaxhighlight lang=dart>makeAccumulator(s) => (n) => s += n;</syntaxhighlight>
<syntaxhighlight lang="dart">makeAccumulator(s) => (n) => s += n;</syntaxhighlight>


Implementation with static typing (preferred in Dart 2):
Implementation with static typing (preferred in Dart 2):
<syntaxhighlight lang=dart>typedef Accumulator = num Function(num);
<syntaxhighlight lang="dart">typedef Accumulator = num Function(num);


Accumulator makeAccumulator(num s) => (num n) => s += n;</syntaxhighlight>
Accumulator makeAccumulator(num s) => (num n) => s += n;</syntaxhighlight>


Verbose version:
Verbose version:
<syntaxhighlight lang=dart>typedef Accumulator = num Function(num);
<syntaxhighlight lang="dart">typedef Accumulator = num Function(num);


Accumulator makeAccumulator(num initial) {
Accumulator makeAccumulator(num initial) {
Line 901: Line 900:


Usage example for any of above:
Usage example for any of above:
<syntaxhighlight lang=dart>void main() {
<syntaxhighlight lang="dart">void main() {
var x = makeAccumulator(1);
var x = makeAccumulator(1);
x(5);
x(5);
Line 912: Line 911:


Type checking:
Type checking:
<syntaxhighlight lang=dart>void main() {
<syntaxhighlight lang="dart">void main() {
var x = makeAccumulator(1);
var x = makeAccumulator(1);
print(x(5).runtimeType); // int
print(x(5).runtimeType); // int
Line 920: Line 919:


=={{header|Déjà Vu}}==
=={{header|Déjà Vu}}==
<syntaxhighlight lang=dejavu>accum n:
<syntaxhighlight lang="dejavu">accum n:
labda i:
labda i:
set :n + n i
set :n + n i
Line 932: Line 931:
{{libheader| System.SysUtils}}
{{libheader| System.SysUtils}}
{{libheader| System.Variants}}
{{libheader| System.Variants}}
<syntaxhighlight lang=Delphi>
<syntaxhighlight lang="delphi">
program Accumulator_factory;
program Accumulator_factory;


Line 962: Line 961:
end.</syntaxhighlight>
end.</syntaxhighlight>
=={{header|E}}==
=={{header|E}}==
<syntaxhighlight lang=e>def foo(var x) {
<syntaxhighlight lang="e">def foo(var x) {
return fn y { x += y }
return fn y { x += y }
}</syntaxhighlight>
}</syntaxhighlight>


=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
<syntaxhighlight lang=lisp>
<syntaxhighlight lang="lisp">
(define-syntax-rule (inc x v) (set! x (+ x v)))
(define-syntax-rule (inc x v) (set! x (+ x v)))
(define (accumulator (sum 0)) (lambda(x) (inc sum x) sum))
(define (accumulator (sum 0)) (lambda(x) (inc sum x) sum))
Line 982: Line 981:
=={{header|Elena}}==
=={{header|Elena}}==
ELENA 4.x :
ELENA 4.x :
<syntaxhighlight lang=elena>function(acc)
<syntaxhighlight lang="elena">function(acc)
= (n => acc.append:n);
= (n => acc.append:n);


Line 1,005: Line 1,004:
=={{header|Elixir}}==
=={{header|Elixir}}==
Elixir provides Agents to simplify creating a process to maintain state where mutable variables aren't allowed.
Elixir provides Agents to simplify creating a process to maintain state where mutable variables aren't allowed.
<syntaxhighlight lang=elixir>defmodule AccumulatorFactory do
<syntaxhighlight lang="elixir">defmodule AccumulatorFactory do
def new(initial) do
def new(initial) do
{:ok, pid} = Agent.start_link(fn() -> initial end)
{:ok, pid} = Agent.start_link(fn() -> initial end)
Line 1,014: Line 1,013:
end</syntaxhighlight>
end</syntaxhighlight>
The passing test to exercise the Accumulator and show usage:
The passing test to exercise the Accumulator and show usage:
<syntaxhighlight lang=elixir>ExUnit.start
<syntaxhighlight lang="elixir">ExUnit.start


defmodule AccumulatorFactoryTest do
defmodule AccumulatorFactoryTest do
Line 1,040: Line 1,039:
=={{header|Erlang}}==
=={{header|Erlang}}==
Erlang doesn't allow for mutable variables, but does have variable capture in closures. By spawning a process which loops endlessly, incrementing the sum and returning it to the caller, this mutable state can be imitated.
Erlang doesn't allow for mutable variables, but does have variable capture in closures. By spawning a process which loops endlessly, incrementing the sum and returning it to the caller, this mutable state can be imitated.
<syntaxhighlight lang=erlang>
<syntaxhighlight lang="erlang">
-module(acc_factory).
-module(acc_factory).
-export([loop/1,new/1]).
-export([loop/1,new/1]).
Line 1,061: Line 1,060:


=={{header|ERRE}}==
=={{header|ERRE}}==
<syntaxhighlight lang=ERRE>PROGRAM ACCUMULATOR
<syntaxhighlight lang="erre">PROGRAM ACCUMULATOR


PROCEDURE ACCUMULATOR(SUM,N,A->SUM)
PROCEDURE ACCUMULATOR(SUM,N,A->SUM)
Line 1,085: Line 1,084:
=={{header|F Sharp|F#}}==
=={{header|F Sharp|F#}}==
A statically typed version is not possible, but it is quite easy to write dynamically typed functions in F#:
A statically typed version is not possible, but it is quite easy to write dynamically typed functions in F#:
<syntaxhighlight lang=fsharp>// dynamically typed add
<syntaxhighlight lang="fsharp">// dynamically typed add
let add (x: obj) (y: obj) =
let add (x: obj) (y: obj) =
match x, y with
match x, y with
Line 1,107: Line 1,106:


Actually, it is possible to create a statically typed version by using an inline accumulator creation function.
Actually, it is possible to create a statically typed version by using an inline accumulator creation function.
<syntaxhighlight lang=fsharp>let inline makeAccumulator init =
<syntaxhighlight lang="fsharp">let inline makeAccumulator init =
let acc = ref init
let acc = ref init
fun i ->
fun i ->
Line 1,123: Line 1,122:


=={{header|Factor}}==
=={{header|Factor}}==
<syntaxhighlight lang=factor>USE: locals
<syntaxhighlight lang="factor">USE: locals
:: accumulator ( n! -- quot ) [ n + dup n! ] ;
:: accumulator ( n! -- quot ) [ n + dup n! ] ;


Line 1,133: Line 1,132:
=={{header|Fantom}}==
=={{header|Fantom}}==
The accumulator function is a little unwieldy using multiple ifs to maintain the type of 'sum' until forced to change. Again, a result of the three concrete Num types, Int, Float and Decimal, all being separated in the API.
The accumulator function is a little unwieldy using multiple ifs to maintain the type of 'sum' until forced to change. Again, a result of the three concrete Num types, Int, Float and Decimal, all being separated in the API.
<syntaxhighlight lang=fantom>class AccumulatorFactory
<syntaxhighlight lang="fantom">class AccumulatorFactory
{
{
static |Num -> Num| accumulator (Num sum)
static |Num -> Num| accumulator (Num sum)
Line 1,186: Line 1,185:
=={{header|Forth}}==
=={{header|Forth}}==
Forth is untyped; this works on integers.
Forth is untyped; this works on integers.
<syntaxhighlight lang=forth>: accumulator
<syntaxhighlight lang="forth">: accumulator
create ( n -- ) ,
create ( n -- ) ,
does> ( n -- acc+n ) tuck +! @ ;
does> ( n -- acc+n ) tuck +! @ ;
Line 1,198: Line 1,197:
The idiomatic way to deal with floats is to have a float version of this code; for a mixture of integers and floats, you decide at the start to use a float accumulator, and convert integers to floats explicitly:
The idiomatic way to deal with floats is to have a float version of this code; for a mixture of integers and floats, you decide at the start to use a float accumulator, and convert integers to floats explicitly:


<syntaxhighlight lang=forth>
<syntaxhighlight lang="forth">
: faccumulator ( r "name" -- )
: faccumulator ( r "name" -- )
create falign f,
create falign f,
Line 1,226: Line 1,225:
in Fortran77 but was accepted by virtually all compilers.
in Fortran77 but was accepted by virtually all compilers.


<syntaxhighlight lang=Fortran>#define foo(type,g,nn) \
<syntaxhighlight lang="fortran">#define foo(type,g,nn) \
typex function g(i);\
typex function g(i);\
typex i,s,n;\
typex i,s,n;\
Line 1,255: Line 1,254:
Fortran2003 and later supports objects and overloading. The overloaded functions are encapsulated in an object.
Fortran2003 and later supports objects and overloading. The overloaded functions are encapsulated in an object.


<syntaxhighlight lang=Fortran>
<syntaxhighlight lang="fortran">
module modAcc
module modAcc
implicit none
implicit none
Line 1,349: Line 1,348:


Probably the best we can do is for 'foo' to return the object and then to call the method 'g' directly on that:
Probably the best we can do is for 'foo' to return the object and then to call the method 'g' directly on that:
<syntaxhighlight lang=freebasic>' FB 1.05.0 Win64
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64


' uses overloaded methods to deal with the integer/float aspect (long and single are both 4 bytes)
' uses overloaded methods to deal with the integer/float aspect (long and single are both 4 bytes)
Line 1,406: Line 1,405:
=={{header|Go}}==
=={{header|Go}}==
Small deviation on condition 2. The task specifies to handle all numeric types, and only int and float64 are shown here. The technique would extend to all types just as easily, but Go has lots of numeric types and the program would be big.
Small deviation on condition 2. The task specifies to handle all numeric types, and only int and float64 are shown here. The technique would extend to all types just as easily, but Go has lots of numeric types and the program would be big.
<syntaxhighlight lang=go>package main
<syntaxhighlight lang="go">package main


import "fmt"
import "fmt"
Line 1,444: Line 1,443:


=={{header|Golo}}==
=={{header|Golo}}==
<syntaxhighlight lang=golo>#!/usr/bin/env golosh
<syntaxhighlight lang="golo">#!/usr/bin/env golosh
----
----
An accumulator factory example for Rosetta Code.
An accumulator factory example for Rosetta Code.
Line 1,466: Line 1,465:
=={{header|Groovy}}==
=={{header|Groovy}}==
Solution:
Solution:
<syntaxhighlight lang=groovy>def accumulator = { Number n ->
<syntaxhighlight lang="groovy">def accumulator = { Number n ->
def value = n;
def value = n;
{ it = 0 -> value += it}
{ it = 0 -> value += it}
}</syntaxhighlight>
}</syntaxhighlight>
Test:
Test:
<syntaxhighlight lang=groovy>def x = accumulator(1)
<syntaxhighlight lang="groovy">def x = accumulator(1)


println x()
println x()
Line 1,505: Line 1,504:
=={{header|Haskell}}==
=={{header|Haskell}}==
{{trans|Ruby}}
{{trans|Ruby}}
<syntaxhighlight lang=haskell>import Control.Monad.ST
<syntaxhighlight lang="haskell">import Control.Monad.ST
import Data.STRef
import Data.STRef


Line 1,526: Line 1,525:


'''Note''' The <code>accumulator</code> function could be written in applicative style:
'''Note''' The <code>accumulator</code> function could be written in applicative style:
<syntaxhighlight lang=haskell>accumulator = newSTRef >=> return . factory
<syntaxhighlight lang="haskell">accumulator = newSTRef >=> return . factory
where factory s n = modifySTRef s (+ n) >> readSTRef s</syntaxhighlight>
where factory s n = modifySTRef s (+ n) >> readSTRef s</syntaxhighlight>


Line 1,533: Line 1,532:


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.
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.
<syntaxhighlight lang=Unicon>procedure main()
<syntaxhighlight lang="unicon">procedure main()
a := genAcc(3)
a := genAcc(3)
b := genAcc(5)
b := genAcc(5)
Line 1,560: Line 1,559:


=={{header|Io}}==
=={{header|Io}}==
<syntaxhighlight lang=Io>accumulator := method(sum,
<syntaxhighlight lang="io">accumulator := method(sum,
block(x, sum = sum + x) setIsActivatable(true)
block(x, sum = sum + x) setIsActivatable(true)
)
)
Line 1,570: Line 1,569:
=={{header|J}}==
=={{header|J}}==
See http://www.jsoftware.com/jwiki/Guides/Lexical_Closure, including the [[j:Guides/Lexical%20Closure#dissent|dissent]] section.
See http://www.jsoftware.com/jwiki/Guides/Lexical_Closure, including the [[j:Guides/Lexical%20Closure#dissent|dissent]] section.
<syntaxhighlight lang=J>oleg=:1 :0
<syntaxhighlight lang="j">oleg=:1 :0
a=. cocreate''
a=. cocreate''
n__a=: m
n__a=: m
Line 1,576: Line 1,575:
)</syntaxhighlight>
)</syntaxhighlight>
Example use:
Example use:
<syntaxhighlight lang=j> F=: 10 oleg
<syntaxhighlight lang="j"> F=: 10 oleg
F 11
F 11
21
21
Line 1,590: Line 1,589:


{{works with|Java|5 and up}}
{{works with|Java|5 and up}}
<syntaxhighlight lang=java>public class Accumulator
<syntaxhighlight lang="java">public class Accumulator
//implements java.util.function.UnaryOperator<Number> // Java 8
//implements java.util.function.UnaryOperator<Number> // Java 8
{
{
Line 1,628: Line 1,627:


{{works with|Java|8 and up}}
{{works with|Java|8 and up}}
<syntaxhighlight lang=java>import java.util.function.UnaryOperator;
<syntaxhighlight lang="java">import java.util.function.UnaryOperator;


public class AccumulatorFactory {
public class AccumulatorFactory {
Line 1,658: Line 1,657:
=={{header|JavaScript}}==
=={{header|JavaScript}}==
===ES5===
===ES5===
<syntaxhighlight lang=javascript>function accumulator(sum) {
<syntaxhighlight lang="javascript">function accumulator(sum) {
return function(n) {
return function(n) {
return sum += n;
return sum += n;
Line 1,672: Line 1,671:


===ES6===
===ES6===
<syntaxhighlight lang=javascript>let accumulator = sum => (n => sum += n);
<syntaxhighlight lang="javascript">let accumulator = sum => (n => sum += n);
let x = accumulator(1);
let x = accumulator(1);
console.log(x(5));
console.log(x(5));
Line 1,682: Line 1,681:


===JavaScript 1.8 (SpiderMonkey Only)===
===JavaScript 1.8 (SpiderMonkey Only)===
<syntaxhighlight lang=javascript>function accumulator(sum) function(n) sum += n;
<syntaxhighlight lang="javascript">function accumulator(sum) function(n) sum += n;
var x = accumulator(1);
var x = accumulator(1);
x(5);
x(5);
Line 1,693: Line 1,692:
=={{header|Jsish}}==
=={{header|Jsish}}==
From Javascript ES5 entry.
From Javascript ES5 entry.
<syntaxhighlight lang=javascript>/* Accumulator factory, in Jsish */
<syntaxhighlight lang="javascript">/* Accumulator factory, in Jsish */
function accumulator(sum) {
function accumulator(sum) {
return function(n) {
return function(n) {
Line 1,745: Line 1,744:
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}


<syntaxhighlight lang=julia>function accumulator(i)
<syntaxhighlight lang="julia">function accumulator(i)
f(n) = i += n
f(n) = i += n
return f
return f
Line 1,762: Line 1,761:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
Overloads would be needed for all six primitive numeric types but, in the interests of brevity, only two overloads of 'foo' have been coded:
Overloads would be needed for all six primitive numeric types but, in the interests of brevity, only two overloads of 'foo' have been coded:
<syntaxhighlight lang=scala>// version 1.1
<syntaxhighlight lang="scala">// version 1.1


fun foo(n: Double): (d: Double) -> Double {
fun foo(n: Double): (d: Double) -> Double {
Line 1,793: Line 1,792:
=={{header|Lambdatalk}}==
=={{header|Lambdatalk}}==
Lambdatlk is a functional programming language without closures but with mutable arrays.
Lambdatlk is a functional programming language without closures but with mutable arrays.
<syntaxhighlight lang=scheme>
<syntaxhighlight lang="scheme">
{def acc
{def acc
{lambda {:a :n}
{lambda {:a :n}
Line 1,824: Line 1,823:
=== Traditional closure ===
=== Traditional closure ===


<syntaxhighlight lang=lisp>
<syntaxhighlight lang="lisp">
(defun accum (m)
(defun accum (m)
(lambda (n)
(lambda (n)
Line 1,853: Line 1,852:
We can creating a looping process which provides the same functionality as the self-calling function in the "traditional closure" approach:
We can creating a looping process which provides the same functionality as the self-calling function in the "traditional closure" approach:


<syntaxhighlight lang=lisp>
<syntaxhighlight lang="lisp">
(defun loop (m)
(defun loop (m)
(receive
(receive
Line 1,888: Line 1,887:
=={{header|Lua}}==
=={{header|Lua}}==
A simple implementation:
A simple implementation:
<syntaxhighlight lang=Lua>function acc(init)
<syntaxhighlight lang="lua">function acc(init)
init = init or 0
init = init or 0
return function(delta)
return function(delta)
Line 1,897: Line 1,896:
An expanded example of similar but more complex functionality:
An expanded example of similar but more complex functionality:
{{works with|Lua|5.1}}
{{works with|Lua|5.1}}
<syntaxhighlight lang=lua>do
<syntaxhighlight lang="lua">do
local accSum = 0; -- accumulator factory 'upvalue'
local accSum = 0; -- accumulator factory 'upvalue'
function acc(v) -- the accumulator factory
function acc(v) -- the accumulator factory
Line 1,911: Line 1,910:
end--end of factory closure</syntaxhighlight>
end--end of factory closure</syntaxhighlight>
Usage example:
Usage example:
<syntaxhighlight lang=lua>x = acc(1) -- x stores the product with initial value = 1
<syntaxhighlight lang="lua">x = acc(1) -- x stores the product with initial value = 1
x(5) -- add 5 to x's sum
x(5) -- add 5 to x's sum
acc(3) -- add 3 to factory's sum
acc(3) -- add 3 to factory's sum
Line 1,919: Line 1,918:


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang=M2000 Interpreter>\\ M2000 Interpreter
<syntaxhighlight lang="m2000 interpreter">\\ M2000 Interpreter
\\ accumulator factory
\\ accumulator factory
foo=lambda acc=0 (n as double=0) -> {
foo=lambda acc=0 (n as double=0) -> {
Line 1,954: Line 1,953:
=={{header|Maple}}==
=={{header|Maple}}==
This creates a procedure closed over the local variable total in the factory procedure. The initial value, if not passed to the factory procedure, is taken to be 0 and, if the generated accumulator is given no value, it increments the total by 1.
This creates a procedure closed over the local variable total in the factory procedure. The initial value, if not passed to the factory procedure, is taken to be 0 and, if the generated accumulator is given no value, it increments the total by 1.
<syntaxhighlight lang=Maple>AccumulatorFactory := proc( initial := 0 )
<syntaxhighlight lang="maple">AccumulatorFactory := proc( initial := 0 )
local total := initial;
local total := initial;
proc( val := 1 ) total := total + val end
proc( val := 1 ) total := total + val end
end proc:</syntaxhighlight>
end proc:</syntaxhighlight>
Running this, we get:
Running this, we get:
<syntaxhighlight lang=Maple>> acc := AccumulatorFactory( 1 ):
<syntaxhighlight lang="maple">> acc := AccumulatorFactory( 1 ):
> acc( 5 );
> acc( 5 );
6
6
Line 1,977: Line 1,976:


=={{header|Mathematica}} / {{header|Wolfram Language}}==
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica>accFactory[initial_] :=
<syntaxhighlight lang="mathematica">accFactory[initial_] :=
Module[{total = initial},
Module[{total = initial},
Function[x, total += x]
Function[x, total += x]
Line 1,998: Line 1,997:
2. this likely violates some hidden taste requirements of the task, as used by Paul Graham to dismiss Forth solutions. Certainly, this is not really an example of Mercury that anyone would want to use in a Mercury project.
2. this likely violates some hidden taste requirements of the task, as used by Paul Graham to dismiss Forth solutions. Certainly, this is not really an example of Mercury that anyone would want to use in a Mercury project.


<syntaxhighlight lang=Mercury>:- module accum.
<syntaxhighlight lang="mercury">:- module accum.
:- interface.
:- interface.


Line 2,031: Line 2,030:
As used:
As used:


<syntaxhighlight lang=Mercury>:- module accumuser.
<syntaxhighlight lang="mercury">:- module accumuser.
:- interface.
:- interface.
:- import_module io.
:- import_module io.
Line 2,071: Line 2,070:
2. This doesn't return a closure with mutable state, but the state itself, which the caller can thread through rules that apply to them.
2. This doesn't return a closure with mutable state, but the state itself, which the caller can thread through rules that apply to them.


<syntaxhighlight lang=Mercury>:- module accum2.
<syntaxhighlight lang="mercury">:- module accum2.
:- interface.
:- interface.


Line 2,103: Line 2,102:
As used, with the same output:
As used, with the same output:


<syntaxhighlight lang=Mercury>:- module accumuser2.
<syntaxhighlight lang="mercury">:- module accumuser2.
:- interface.
:- interface.
:- import_module io.
:- import_module io.
Line 2,134: Line 2,133:
=={{header|Nemerle}}==
=={{header|Nemerle}}==
Nemerle doesn't have a <tt>dynamic</tt> type, but we can use matching to bind types to <tt>object</tt>s.
Nemerle doesn't have a <tt>dynamic</tt> type, but we can use matching to bind types to <tt>object</tt>s.
<syntaxhighlight lang=Nemerle>def Foo(n) {
<syntaxhighlight lang="nemerle">def Foo(n) {
mutable value : object = n;
mutable value : object = n;
fun (i : object) {
fun (i : object) {
Line 2,161: Line 2,160:


=={{header|NewLisp}}==
=={{header|NewLisp}}==
<syntaxhighlight lang=NewLisp>(define (sum (x 0)) (inc 0 x))
<syntaxhighlight lang="newlisp">(define (sum (x 0)) (inc 0 x))
</syntaxhighlight>
</syntaxhighlight>


Line 2,184: Line 2,183:


=={{header|NGS}}==
=={{header|NGS}}==
<syntaxhighlight lang=NGS>{
<syntaxhighlight lang="ngs">{
F Acc(start:Int) {
F Acc(start:Int) {
sum = start
sum = start
Line 2,214: Line 2,213:
Argument to the created accumulator function must be float.
Argument to the created accumulator function must be float.
Result is always float.
Result is always float.
<syntaxhighlight lang=Nim>
<syntaxhighlight lang="nim">
proc accumulator[T: SomeNumber](x: T): auto =
proc accumulator[T: SomeNumber](x: T): auto =
var sum = float(x)
var sum = float(x)
Line 2,237: Line 2,236:
Argument to the accumulator function must be of the same type.
Argument to the accumulator function must be of the same type.
Result of the accumulator function is also of the same type.
Result of the accumulator function is also of the same type.
<syntaxhighlight lang=Nim>
<syntaxhighlight lang="nim">
proc accumulator[T: SomeNumber](x: T): auto =
proc accumulator[T: SomeNumber](x: T): auto =
var sum = x
var sum = x
Line 2,267: Line 2,266:


This solution fulfills the requirements.
This solution fulfills the requirements.
<syntaxhighlight lang=Nim>
<syntaxhighlight lang="nim">
type
type


Line 2,345: Line 2,344:
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/accumulator_factory.nit the official Nit repository]
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/accumulator_factory.nit the official Nit repository]


<syntaxhighlight lang=nit># The `accumulator factory` task.
<syntaxhighlight lang="nit"># The `accumulator factory` task.
#
#
# Nit has no first-class function.
# Nit has no first-class function.
Line 2,373: Line 2,372:
=={{header|Objeck}}==
=={{header|Objeck}}==
Uses objects instead of first class functions.
Uses objects instead of first class functions.
<syntaxhighlight lang=objeck>bundle Default {
<syntaxhighlight lang="objeck">bundle Default {
class Accumulator {
class Accumulator {
@sum : Float;
@sum : Float;
Line 2,396: Line 2,395:
=={{header|Objective-C}}==
=={{header|Objective-C}}==
{{works with|Mac OS X|10.6+}}
{{works with|Mac OS X|10.6+}}
<syntaxhighlight lang=objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


typedef double (^Accumulator)(double);
typedef double (^Accumulator)(double);
Line 2,425: Line 2,424:
{{trans|Ruby}}
{{trans|Ruby}}
Deviations: An accumulator instance can take ''either'' integers ''or'' floats, but not both mixed (due to lack of runtime polymorphism).
Deviations: An accumulator instance can take ''either'' integers ''or'' floats, but not both mixed (due to lack of runtime polymorphism).
<syntaxhighlight lang=ocaml>let accumulator sum0 =
<syntaxhighlight lang="ocaml">let accumulator sum0 =
let sum = ref sum0 in
let sum = ref sum0 in
fun n ->
fun n ->
Line 2,442: Line 2,441:
=={{header|Octave}}==
=={{header|Octave}}==


<syntaxhighlight lang=octave># not a function file:
<syntaxhighlight lang="octave"># not a function file:
1;
1;
function fun = foo(init)
function fun = foo(init)
Line 2,460: Line 2,459:
The block returned by foo (a closure), when performed, retrieves the current value from the closure parameter, adds the top of stack, and stores the result back to the closure's parameter. The result is dup, so it is also returned.
The block returned by foo (a closure), when performed, retrieves the current value from the closure parameter, adds the top of stack, and stores the result back to the closure's parameter. The result is dup, so it is also returned.


<syntaxhighlight lang=Oforth>: foo( n -- bl )
<syntaxhighlight lang="oforth">: foo( n -- bl )
#[ n swap + dup ->n ] ;</syntaxhighlight>
#[ n swap + dup ->n ] ;</syntaxhighlight>


Usage :
Usage :
<syntaxhighlight lang=Oforth>: testfoo
<syntaxhighlight lang="oforth">: testfoo
| x y z |
| x y z |
1 foo ->x
1 foo ->x
Line 2,485: Line 2,484:
=={{header|ooRexx}}==
=={{header|ooRexx}}==
ooRexx does not have functions that can maintain state between calls. The standard work around is to use an object instance and a defined method name.
ooRexx does not have functions that can maintain state between calls. The standard work around is to use an object instance and a defined method name.
<syntaxhighlight lang=ooRexx>
<syntaxhighlight lang="oorexx">
x = .accumulator~new(1) -- new accumulator with initial value of "1"
x = .accumulator~new(1) -- new accumulator with initial value of "1"
x~call(5)
x~call(5)
Line 2,578: Line 2,577:
=={{header|Oz}}==
=={{header|Oz}}==
A bit unwieldy because the '+' operator does not allow mixed type operands. The implementation is thread-safe (atomic Exchange operation).
A bit unwieldy because the '+' operator does not allow mixed type operands. The implementation is thread-safe (atomic Exchange operation).
<syntaxhighlight lang=oz>declare
<syntaxhighlight lang="oz">declare
fun {Acc Init}
fun {Acc Init}
State = {NewCell Init}
State = {NewCell Init}
Line 2,609: Line 2,608:
=={{header|PARI/GP}}==
=={{header|PARI/GP}}==


<syntaxhighlight lang=parigp>stack = List([1]);
<syntaxhighlight lang="parigp">stack = List([1]);
factory(b,c=0) = my(a=stack[1]++);listput(stack,c);(b)->stack[a]+=b;
factory(b,c=0) = my(a=stack[1]++);listput(stack,c);(b)->stack[a]+=b;


Line 2,630: Line 2,629:


{{trans|Ruby}}
{{trans|Ruby}}
<syntaxhighlight lang=perl>sub accumulator {
<syntaxhighlight lang="perl">sub accumulator {
my $sum = shift;
my $sum = shift;
sub { $sum += shift }
sub { $sum += shift }
Line 2,664: Line 2,663:
accumulator_factory() and return a pointer to that instead of an id/length.
accumulator_factory() and return a pointer to that instead of an id/length.


<!--<syntaxhighlight lang=Phix>-->
<!--<syntaxhighlight lang="phix">-->
<span style="color: #004080;">sequence</span> <span style="color: #000000;">accumulators</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">accumulators</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
Line 2,708: Line 2,707:


=={{header|PHP}}==
=={{header|PHP}}==
<syntaxhighlight lang=PHP><?php
<syntaxhighlight lang="php"><?php
function accumulator($start){
function accumulator($start){
return create_function('$x','static $v='.$start.';return $v+=$x;');
return create_function('$x','static $v='.$start.';return $v+=$x;');
Line 2,717: Line 2,716:
?></syntaxhighlight>
?></syntaxhighlight>
{{works with|PHP|5.3+}}
{{works with|PHP|5.3+}}
<syntaxhighlight lang=php><?php
<syntaxhighlight lang="php"><?php
function accumulator($sum){
function accumulator($sum){
return function ($x) use (&$sum) { return $sum += $x; };
return function ($x) use (&$sum) { return $sum += $x; };
Line 2,727: Line 2,726:


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<syntaxhighlight lang=PicoLisp>(de accumulator (Sum)
<syntaxhighlight lang="picolisp">(de accumulator (Sum)
(curry (Sum) (N)
(curry (Sum) (N)
(inc 'Sum N) ) )
(inc 'Sum N) ) )
Line 2,738: Line 2,737:
=={{header|Pony}}==
=={{header|Pony}}==


<syntaxhighlight lang=Pony>
<syntaxhighlight lang="pony">
use "assert"
use "assert"
class Accumulator
class Accumulator
Line 2,776: Line 2,775:


=={{header|PostScript}}==
=={{header|PostScript}}==
<syntaxhighlight lang=PostScript>/mk-acc { % accumulator generator
<syntaxhighlight lang="postscript">/mk-acc { % accumulator generator
{0 add 0 0 2 index put}
{0 add 0 0 2 index put}
7 array copy
7 array copy
Line 2,800: Line 2,799:


The GetNewClosure method returns a ScriptBlock with captured variables.
The GetNewClosure method returns a ScriptBlock with captured variables.
<syntaxhighlight lang=PowerShell>
<syntaxhighlight lang="powershell">
function Get-Accumulator ([double]$Start)
function Get-Accumulator ([double]$Start)
{
{
Line 2,806: Line 2,805:
}
}
</syntaxhighlight>
</syntaxhighlight>
<syntaxhighlight lang=PowerShell>
<syntaxhighlight lang="powershell">
$total = Get-Accumulator -Start 1
$total = Get-Accumulator -Start 1
& $total -Plus 5.0 | Out-Null
& $total -Plus 5.0 | Out-Null
Line 2,819: Line 2,818:
{{works with|SWI Prolog}}
{{works with|SWI Prolog}}
Uses the module '''lambda''' written by '''Ulrich Neumerkel'''.
Uses the module '''lambda''' written by '''Ulrich Neumerkel'''.
<syntaxhighlight lang=Prolog>:- use_module(library(lambda)).
<syntaxhighlight lang="prolog">:- use_module(library(lambda)).


define_g(N, G) :-
define_g(N, G) :-
Line 2,843: Line 2,842:
=={{header|Python}}==
=={{header|Python}}==
{{works with|Python|2.x/3.x}}
{{works with|Python|2.x/3.x}}
<syntaxhighlight lang=python>>>> def accumulator(sum):
<syntaxhighlight lang="python">>>> def accumulator(sum):
def f(n):
def f(n):
f.sum += n
f.sum += n
Line 2,872: Line 2,871:
{{trans|Ruby}}
{{trans|Ruby}}
{{works with|Python|3.x}}
{{works with|Python|3.x}}
<syntaxhighlight lang=python>def accumulator(sum):
<syntaxhighlight lang="python">def accumulator(sum):
def f(n):
def f(n):
nonlocal sum
nonlocal sum
Line 2,888: Line 2,887:


{{works with|Python|2.5+}}
{{works with|Python|2.5+}}
<syntaxhighlight lang=python>def accumulator(sum):
<syntaxhighlight lang="python">def accumulator(sum):
while True:
while True:
sum += yield sum
sum += yield sum
Line 2,907: Line 2,906:
Quackery is untyped. This solution works with bignums. <code>factory</code> returns a lambda function. (In Quackery terminology, it leaves a nest on the stack.) Nests on the stack are performed (i.e. executed or evaluated) with <code>do</code>.
Quackery is untyped. This solution works with bignums. <code>factory</code> returns a lambda function. (In Quackery terminology, it leaves a nest on the stack.) Nests on the stack are performed (i.e. executed or evaluated) with <code>do</code>.


<syntaxhighlight lang=Quackery> [ tuck tally share ]this[ swap ] is accumulate ( n s --> [ n )
<syntaxhighlight lang="quackery"> [ tuck tally share ]this[ swap ] is accumulate ( n s --> [ n )


[ [ stack ] copy tuck put nested
[ [ stack ] copy tuck put nested
Line 2,972: Line 2,971:
In accordance with The Building Regulations, it starts with some sanity checks to enable the compiler to fail gracefully. For details see [https://github.com/GordonCharlton/Quackery/blob/main/The%20Book%20of%20Quackery.pdf The Book of Quackery.]
In accordance with The Building Regulations, it starts with some sanity checks to enable the compiler to fail gracefully. For details see [https://github.com/GordonCharlton/Quackery/blob/main/The%20Book%20of%20Quackery.pdf The Book of Quackery.]


<syntaxhighlight lang=Quackery> [ dip
<syntaxhighlight lang="quackery"> [ dip
[ -1 split dup [] = if
[ -1 split dup [] = if
[ $ "accumulator needs a starting value."
[ $ "accumulator needs a starting value."
Line 3,020: Line 3,019:


=={{header|R}}==
=={{header|R}}==
<syntaxhighlight lang=R>accumulatorFactory <- function(init) {
<syntaxhighlight lang="r">accumulatorFactory <- function(init) {
currentSum <- init
currentSum <- init
function(add) {
function(add) {
Line 3,037: Line 3,036:


=={{header|Racket}}==
=={{header|Racket}}==
<syntaxhighlight lang=racket>#lang racket
<syntaxhighlight lang="racket">#lang racket
(define ((accumulator n) i)
(define ((accumulator n) i)
(set! n (+ n i))
(set! n (+ n i))
Line 3,046: Line 3,045:
(formerly Perl 6)
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
{{works with|Rakudo|2018.03}}
<syntaxhighlight lang=perl6>sub accum ($n is copy) { sub { $n += $^x } }
<syntaxhighlight lang="raku" line>sub accum ($n is copy) { sub { $n += $^x } }


#Example use:
#Example use:
Line 3,060: Line 3,059:


=={{header|REBOL}}==
=={{header|REBOL}}==
<syntaxhighlight lang=rebol>make-acc-gen: func [start-val] [
<syntaxhighlight lang="rebol">make-acc-gen: func [start-val] [
use [state] [
use [state] [
state: start-val
state: start-val
Line 3,079: Line 3,078:
Retro only supports integers.
Retro only supports integers.


<syntaxhighlight lang=Retro>:acc (ns-)
<syntaxhighlight lang="retro">:acc (ns-)
d:create , [ [ fetch ] [ v:inc ] bi ] does ;</syntaxhighlight>
d:create , [ [ fetch ] [ v:inc ] bi ] does ;</syntaxhighlight>
{{out}}
{{out}}
Line 3,095: Line 3,094:
This REXX program is partially modeled after the ooRexx example.
This REXX program is partially modeled after the ooRexx example.
<br><br>This example will handle any kind of number: integer, floating point.
<br><br>This example will handle any kind of number: integer, floating point.
<syntaxhighlight lang=rexx>/*REXX program shows one method an accumulator factory could be implemented. */
<syntaxhighlight lang="rexx">/*REXX program shows one method an accumulator factory could be implemented. */
x=.accumulator(1) /*initialize accumulator with a 1 value*/
x=.accumulator(1) /*initialize accumulator with a 1 value*/
x=call(5)
x=call(5)
Line 3,115: Line 3,114:


=={{header|Ring}}==
=={{header|Ring}}==
<syntaxhighlight lang=ring>oGenerator = new Generator
<syntaxhighlight lang="ring">oGenerator = new Generator


Func main
Func main
Line 3,147: Line 3,146:
Ruby deviates from the task because methods and Proc objects have different syntax. So, <tt>x = accumulator(1)</tt> is valid, but <tt>x(5)</tt> is an error: the syntax must be <tt>x.call(5)</tt> or <tt>x[5]</tt> (with square brackets). Ruby 1.9 also allows <tt>x.(5)</tt> (with an extra dot).
Ruby deviates from the task because methods and Proc objects have different syntax. So, <tt>x = accumulator(1)</tt> is valid, but <tt>x(5)</tt> is an error: the syntax must be <tt>x.call(5)</tt> or <tt>x[5]</tt> (with square brackets). Ruby 1.9 also allows <tt>x.(5)</tt> (with an extra dot).


<syntaxhighlight lang=ruby>def accumulator(sum)
<syntaxhighlight lang="ruby">def accumulator(sum)
lambda {|n| sum += n}
lambda {|n| sum += n}
end
end
Line 3,166: Line 3,165:
This accumulator also works with other types that have a <tt>+</tt> method.
This accumulator also works with other types that have a <tt>+</tt> method.


<syntaxhighlight lang=ruby>require 'rational'
<syntaxhighlight lang="ruby">require 'rational'
require 'complex'
require 'complex'
y = accumulator(Rational(2, 3))
y = accumulator(Rational(2, 3))
Line 3,184: Line 3,183:
If we define x as a method of self, then the syntax <code>x(5)</code> works, but we deviate more from the task, because x might get "inadvertently modified" by other methods of self.
If we define x as a method of self, then the syntax <code>x(5)</code> works, but we deviate more from the task, because x might get "inadvertently modified" by other methods of self.


<syntaxhighlight lang=ruby>def accumulator(sum)
<syntaxhighlight lang="ruby">def accumulator(sum)
lambda {|n| sum += n}
lambda {|n| sum += n}
end
end
Line 3,199: Line 3,198:
Changing "x = foo(1.)" to "x = foo(1)" in the code below should not change the output (it does).
Changing "x = foo(1.)" to "x = foo(1)" in the code below should not change the output (it does).


<syntaxhighlight lang=rust>// rustc 1.26.0 or later
<syntaxhighlight lang="rust">// rustc 1.26.0 or later


use std::ops::Add;
use std::ops::Add;
Line 3,225: Line 3,224:
=== Over-engineered Solution ===
=== Over-engineered Solution ===
This solution uses a custom number type that can be either an i64 or f64. It also creates a generic struct that is callable using the unstable fn traits, which can be called to add anything that can be added to it's accumulator value.
This solution uses a custom number type that can be either an i64 or f64. It also creates a generic struct that is callable using the unstable fn traits, which can be called to add anything that can be added to it's accumulator value.
<syntaxhighlight lang=rust>// Accumulator
<syntaxhighlight lang="rust">// Accumulator
#![feature(unboxed_closures, fn_traits)]
#![feature(unboxed_closures, fn_traits)]


Line 3,326: Line 3,325:
=={{header|Scala}}==
=={{header|Scala}}==
The type of a function can't change in Scala, and there is no "numeric" type that is a supertype of all such types. So, if the accumulator is declared as integer, it can only receive and return integers, and so on.
The type of a function can't change in Scala, and there is no "numeric" type that is a supertype of all such types. So, if the accumulator is declared as integer, it can only receive and return integers, and so on.
<syntaxhighlight lang=scala>def AccumulatorFactory[N](n: N)(implicit num: Numeric[N]) = {
<syntaxhighlight lang="scala">def AccumulatorFactory[N](n: N)(implicit num: Numeric[N]) = {
import num._
import num._
var acc = n
var acc = n
Line 3,351: Line 3,350:
=={{header|Scheme}}==
=={{header|Scheme}}==
{{trans|Ruby}}
{{trans|Ruby}}
<syntaxhighlight lang=scheme>(define (accumulator sum)
<syntaxhighlight lang="scheme">(define (accumulator sum)
(lambda (n)
(lambda (n)
(set! sum (+ sum n))
(set! sum (+ sum n))
Line 3,371: Line 3,370:


=={{header|Sidef}}==
=={{header|Sidef}}==
<syntaxhighlight lang=ruby>class Accumulator(sum) {
<syntaxhighlight lang="ruby">class Accumulator(sum) {
method add(num) {
method add(num) {
sum += num;
sum += num;
Line 3,384: Line 3,383:
The same thing can be achieved by returning a closure from the '''Accumulator''' function.
The same thing can be achieved by returning a closure from the '''Accumulator''' function.


<syntaxhighlight lang=ruby>func Accumulator(sum) {
<syntaxhighlight lang="ruby">func Accumulator(sum) {
func(num) { sum += num };
func(num) { sum += num };
}
}
Line 3,394: Line 3,393:


=={{header|Simula}}==
=={{header|Simula}}==
<syntaxhighlight lang=simula>BEGIN
<syntaxhighlight lang="simula">BEGIN


! ABSTRACTION FOR SIMULA'S TWO NUMERIC TYPES ;
! ABSTRACTION FOR SIMULA'S TWO NUMERIC TYPES ;
Line 3,473: Line 3,472:
=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
{{works with|GNU Smalltalk}}
<syntaxhighlight lang=smalltalk>Object subclass: AccumulatorFactory [
<syntaxhighlight lang="smalltalk">Object subclass: AccumulatorFactory [
AccumulatorFactory class >> new: aNumber [
AccumulatorFactory class >> new: aNumber [
|r sum|
|r sum|
Line 3,495: Line 3,494:
the above can also be done without a class to hold the block, simply by putting it into another block (i.e. an outer closure for the sum, returning an inner function which updates that sum):
the above can also be done without a class to hold the block, simply by putting it into another block (i.e. an outer closure for the sum, returning an inner function which updates that sum):
{{works with|Smalltalk}}
{{works with|Smalltalk}}
<syntaxhighlight lang=smalltalk>|factory accu1 accu2|
<syntaxhighlight lang="smalltalk">|factory accu1 accu2|


factory := [:initial |
factory := [:initial |
Line 3,521: Line 3,520:
{{trans|OCaml}}
{{trans|OCaml}}
Deviations: An accumulator instance can take ''either'' integers ''or'' reals, but not both mixed (due to lack of runtime polymorphism).
Deviations: An accumulator instance can take ''either'' integers ''or'' reals, but not both mixed (due to lack of runtime polymorphism).
<syntaxhighlight lang=sml>fun accumulator (sum0:real) : real -> real = let
<syntaxhighlight lang="sml">fun accumulator (sum0:real) : real -> real = let
val sum = ref sum0
val sum = ref sum0
in
in
Line 3,540: Line 3,539:


=={{header|Swift}}==
=={{header|Swift}}==
<syntaxhighlight lang=swift>func makeAccumulator(var sum: Double) -> Double -> Double {
<syntaxhighlight lang="swift">func makeAccumulator(var sum: Double) -> Double -> Double {
return {
return {
sum += $0
sum += $0
Line 3,557: Line 3,556:
{{works with|Tcl|8.6}}
{{works with|Tcl|8.6}}
This uses nested [[wp:coroutine|coroutine]]s to manage the state, which for the outer coroutine is a counter used to generate unique instances of the inner coroutine, and for the inner coroutine it is the actual accumulator variable. Note that Tcl commands (including coroutines) are ''never'' nameless, but it is trivial to synthesize a name for them. It's possible to guarantee uniqueness of names, but just using a simple sequence generator gets 90% of the effect for 10% of the effort.
This uses nested [[wp:coroutine|coroutine]]s to manage the state, which for the outer coroutine is a counter used to generate unique instances of the inner coroutine, and for the inner coroutine it is the actual accumulator variable. Note that Tcl commands (including coroutines) are ''never'' nameless, but it is trivial to synthesize a name for them. It's possible to guarantee uniqueness of names, but just using a simple sequence generator gets 90% of the effect for 10% of the effort.
<syntaxhighlight lang=tcl>package require Tcl 8.6
<syntaxhighlight lang="tcl">package require Tcl 8.6


# make the creation of coroutines without procedures simpler
# make the creation of coroutines without procedures simpler
Line 3,586: Line 3,585:
}</syntaxhighlight>
}</syntaxhighlight>
Sample usage (extra characters over Paul's example to show more clearly what is going on):
Sample usage (extra characters over Paul's example to show more clearly what is going on):
<syntaxhighlight lang=tcl>% set x [accumulator 1]
<syntaxhighlight lang="tcl">% set x [accumulator 1]
::accumulator.1
::accumulator.1
% $x 5
% $x 5
Line 3,599: Line 3,598:
===Verbose===
===Verbose===


<syntaxhighlight lang=txrlisp>(defun accumulate (sum)
<syntaxhighlight lang="txrlisp">(defun accumulate (sum)
(lambda (n)
(lambda (n)
(inc sum n)))
(inc sum n)))
Line 3,629: Line 3,628:
===Sugared===
===Sugared===


<syntaxhighlight lang=txrlisp>(let ((f (let ((sum 0)) (do inc sum @1))))
<syntaxhighlight lang="txrlisp">(let ((f (let ((sum 0)) (do inc sum @1))))
(mapdo (do put-line `@1 -> @[f @1]`) (gun (iread : : nil))))</syntaxhighlight>
(mapdo (do put-line `@1 -> @[f @1]`) (gun (iread : : nil))))</syntaxhighlight>
{{out}}
{{out}}
Line 3,642: Line 3,641:
Using the <code>obtain</code>/<code>yield</code> interface to delimited continuations, we can turn an imperative for loop into an accumulation function:
Using the <code>obtain</code>/<code>yield</code> interface to delimited continuations, we can turn an imperative for loop into an accumulation function:


<syntaxhighlight lang=txrlisp>(defun accum ()
<syntaxhighlight lang="txrlisp">(defun accum ()
(for ((sum (yield-from accum)))
(for ((sum (yield-from accum)))
()
()
Line 3,660: Line 3,659:
OOP languages can use objects to simulate closures. In particular, function-objects which can be called as if they were functions, without any visible method being referenced. TXR Lisp supports functors as an expression of irony in language design. A structure object for which a method named <code>lambda</code> is defined can be used as function. Arguments applied to the objects are applied to lambda, preceded by the object itself as the leftmost argument:
OOP languages can use objects to simulate closures. In particular, function-objects which can be called as if they were functions, without any visible method being referenced. TXR Lisp supports functors as an expression of irony in language design. A structure object for which a method named <code>lambda</code> is defined can be used as function. Arguments applied to the objects are applied to lambda, preceded by the object itself as the leftmost argument:


<syntaxhighlight lang=txrlisp>(defstruct (accum count) nil
<syntaxhighlight lang="txrlisp">(defstruct (accum count) nil
(count 0))
(count 0))


Line 3,673: Line 3,672:
=={{header|Unicon}}==
=={{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.
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.
<syntaxhighlight lang=Unicon>procedure main()
<syntaxhighlight lang="unicon">procedure main()
a := genAcc(3)
a := genAcc(3)
b := genAcc(5)
b := genAcc(5)
Line 3,704: Line 3,703:
The shell is a bad choice for this task. This example plays tricks with <tt>eval</tt>. The difficulty with <tt>eval</tt> is to put the quotation marks " and dollar signs <tt>$</tt> in the correct place, and escape them with the correct number of backslashes \. One missing (or one extra) backslash can ruin the entire program.
The shell is a bad choice for this task. This example plays tricks with <tt>eval</tt>. The difficulty with <tt>eval</tt> is to put the quotation marks " and dollar signs <tt>$</tt> in the correct place, and escape them with the correct number of backslashes \. One missing (or one extra) backslash can ruin the entire program.
{{works with|pdksh}}
{{works with|pdksh}}
<syntaxhighlight lang=bash>#!/bin/sh
<syntaxhighlight lang="bash">#!/bin/sh
accumulator() {
accumulator() {
# Define a global function named $1
# Define a global function named $1
Line 3,729: Line 3,728:
==={{header|es}}===
==={{header|es}}===
A better shell for this task is ''es'', because it has lexical variables and closures. <code>@ i {code}</code> is a lambda with parameter ''i'', and <code>fn accumulator n {code}</code> is sugar for <code>fn-accumulator = @ n {code}</code>.
A better shell for this task is ''es'', because it has lexical variables and closures. <code>@ i {code}</code> is a lambda with parameter ''i'', and <code>fn accumulator n {code}</code> is sugar for <code>fn-accumulator = @ n {code}</code>.
<syntaxhighlight lang=es>fn accumulator n {
<syntaxhighlight lang="es">fn accumulator n {
result @ i {
result @ i {
n = `{echo $n + $i | bc}
n = `{echo $n + $i | bc}
Line 3,745: Line 3,744:
I'm not entirely convinced that this is actually doing what is asked. A VBScript guru I'm not. The answer's right, though.
I'm not entirely convinced that this is actually doing what is asked. A VBScript guru I'm not. The answer's right, though.
;Implementation
;Implementation
<syntaxhighlight lang=vb>class accumulator
<syntaxhighlight lang="vb">class accumulator
dim A
dim A
public default function acc(x)
public default function acc(x)
Line 3,756: Line 3,755:
end class</syntaxhighlight>
end class</syntaxhighlight>
;Invocation
;Invocation
<syntaxhighlight lang=vb>dim a
<syntaxhighlight lang="vb">dim a
set a = new accumulator
set a = new accumulator
x = a( 1 )
x = a( 1 )
Line 3,770: Line 3,769:


=={{header|Wart}}==
=={{header|Wart}}==
<syntaxhighlight lang=python>def (accumulator n)
<syntaxhighlight lang="python">def (accumulator n)
(fn() ++n)</syntaxhighlight>
(fn() ++n)</syntaxhighlight>


Line 3,786: Line 3,785:


=={{header|Wren}}==
=={{header|Wren}}==
<syntaxhighlight lang=ecmascript>var accumulator = Fn.new { |acc| Fn.new { |n| acc = acc + n } }
<syntaxhighlight lang="ecmascript">var accumulator = Fn.new { |acc| Fn.new { |n| acc = acc + n } }


var x = accumulator.call(1)
var x = accumulator.call(1)
Line 3,808: Line 3,807:
With some extra work, floating point numbers can be incorporated, but outputting would be trickier.
With some extra work, floating point numbers can be incorporated, but outputting would be trickier.


<syntaxhighlight lang=asm>
<syntaxhighlight lang="asm">
; Accumulator factory
; Accumulator factory
; Returns a function that returns the sum of all numbers ever passed in
; Returns a function that returns the sum of all numbers ever passed in
Line 3,972: Line 3,971:
=={{header|XLISP}}==
=={{header|XLISP}}==
There are probably other ways of doing it, but this is one way.
There are probably other ways of doing it, but this is one way.
<syntaxhighlight lang=lisp>(defun accumulator (x)
<syntaxhighlight lang="lisp">(defun accumulator (x)
(lambda (n)
(lambda (n)
(setq x (+ n x))
(setq x (+ n x))
Line 3,994: Line 3,993:


=={{header|Yabasic}}==
=={{header|Yabasic}}==
<syntaxhighlight lang=Yabasic>sub foo$(n)
<syntaxhighlight lang="yabasic">sub foo$(n)
local f$
local f$
Line 4,011: Line 4,010:
=={{header|Yorick}}==
=={{header|Yorick}}==
Yorick cannot dynamically create new functions. Instead, the accum function can be called in two ways: directly, in which case its first argument is numerical; or through a closure, where its first argument is implicitly an object and the second is the user-provided argument. This example uses closures and group objects, which require Yorick 2.2 or later.
Yorick cannot dynamically create new functions. Instead, the accum function can be called in two ways: directly, in which case its first argument is numerical; or through a closure, where its first argument is implicitly an object and the second is the user-provided argument. This example uses closures and group objects, which require Yorick 2.2 or later.
<syntaxhighlight lang=yorick>func accum(data, n) {
<syntaxhighlight lang="yorick">func accum(data, n) {
if(!is_obj(data))
if(!is_obj(data))
return closure(accum, save(total=data));
return closure(accum, save(total=data));
Line 4,028: Line 4,027:


=={{header|zkl}}==
=={{header|zkl}}==
<syntaxhighlight lang=zkl>fcn foo(n){ fcn(n,acc){ acc.set(n+acc.value).value }.fp1(Ref(n)) }</syntaxhighlight>
<syntaxhighlight lang="zkl">fcn foo(n){ fcn(n,acc){ acc.set(n+acc.value).value }.fp1(Ref(n)) }</syntaxhighlight>
A strong reference (Ref) is used as the accumulator, a Ref acts like a one element list. The Ref is bound to the new functions second parameter with the .fp1 method.
A strong reference (Ref) is used as the accumulator, a Ref acts like a one element list. The Ref is bound to the new functions second parameter with the .fp1 method.
<pre>
<pre>
Line 4,042: Line 4,041:
The output switches between int and float based on the most recent input: With addition, the first operand casts the second: int + int|float --> int and float + int|float --> float. If the desire is to make the behavior "once float, always float", a 0 or 0.0 can be used to start the sum and stashed in a another bit of state.
The output switches between int and float based on the most recent input: With addition, the first operand casts the second: int + int|float --> int and float + int|float --> float. If the desire is to make the behavior "once float, always float", a 0 or 0.0 can be used to start the sum and stashed in a another bit of state.


{{omit from|ARM Assembly}}
{{omit from|Scratch|cannot generate functions nor pass them as arguments or values}}
{{omit from|Commodore BASIC}}
{{omit from|C}} <!-- C's type system imcompatible with task spec -->
{{omit from|C}} <!-- C's type system imcompatible with task spec -->
{{omit from|ML/I}}
{{omit from|ML/I}}
{{omit from|Scratch|cannot generate functions nor pass them as arguments or values}}
{{omit from|Commodore BASIC}}