Accumulator factory
You're encouraged to unravel this job according for the process description, employing any language you could possibly know. From Rosetta Code
A dilemma posed by Paul Graham is always that of developing a function that will take a single (numeric) argument and which returns one more purpose that is an accumulator. The returned accumulator perform in turn also can take a single numeric argument, and returns the sum of all the numeric values handed in thus far to that accumulator (such as the initial worth handed when the accumulator was designed).
The thorough guidelines are at and therefore are reproduced here for simplicity (with additions in tiny italic text).
Ahead of you submit an instance, be sure the perform Requires a amount n and returns a operate (lets get in touch with it g), that requires a range i, and returns n incremented through the accumulation of i from each get in touch with of purpose g(i).
Although these precise perform and parameter names want not be utilized Operates for any numeric type-- i.e. can consider each ints and floats and returns features that may consider the two ints and floats. (It is not ample just to convert all input to floats. An accumulator that has only seen integers must return integers.) (i.e., if your language doesn't allow for numeric polymorphism, you've got to make use of overloading or one thing like that) Generates features that return the sum of every amount actually passed to them, not just probably the most current. (This needs a bit of state to carry the accrued value, which in turn means that pure purposeful languages cannot be employed for this job.) Returns a true perform, meaning some thing which you can use wherever you could use a function you had defined in the ordinary way within the text of the method. (Stick to your language's conventions here.) Does not keep the accumulated value or the returned capabilities in a very way that can result in them to be inadvertantly modified by other code. (No worldwide variables or other this kind of items.) E.g. if after the instance, you extra the following code (inside a made-up language) in which the factory operate is known as foo:
x = foo(1);
x(five);
foo(three);
print x(2.three); It ought to print 8.3. (There exists no will need to print the type of the accumulator function returned by foo(three); it's not component with the activity at all.)
The purpose of this task would be to develop a perform that implements the explained rules. It will need not deal with any specific error instances not explained previously mentioned. The simplest approach to put into action the job as described is usually to use a closure, providing the language supports them.
Where it isn't achievable to hold precisely towards the constraints over, explain the deviations.
one ABAP 1.one Object Oriented Solution
one.two JavaScript Solution two ActionScript
three Aikido
4 ALGOL 68
five Argile
six Brat
seven C++
8 C#
9 Clojure
10 Widespread Lisp
11 D
12 E
thirteen Elena
14 Aspect
fifteen Fantom
16 Forth
17 F#
eighteen GAP
19 Go
twenty Groovy
21 Haskell
22 Icon and Unicon
23 J
24 Java
twenty five JavaScript
26 Lua
27 Mathematica
28 Objeck
29 Objective-C
thirty OCaml
31 Oz
32 Perl
33 Perl six
34 PHP
35 PicoLisp
36 PostScript
37 Python
38 R
39 REBOL
forty Retro
41 Ruby
42 Scala
43 Scheme
44 Smalltalk
45 Tcl
46 Unicon
47 UNIX Shell
48 VBScript
49 Yorick [edit] ABAP
ABAP, sadly, has no 1st buy functions, nor does its OO paradigm put into action strategy overloading. A single possible remedy to this problem is always to use classes to maintain the state, using the import/export parameters being defined as sort 'any', so that the resultant kind is calculated dynamically.
Another doable resolution will be to use the languages in-built JavaScript processing abilities to dynamically build a JS supply at run-time, which implements the JS Accumulator factory.
[edit] Object Oriented Answer
report z_accumulator
class acc definition.
general public segment.
techniques:
call importing iv_i variety any default 0 exporting ev_r sort any,
constructor importing iv_d variety f.
non-public segment.
knowledge a_sum type f.
endclass.
class acc implementation.
technique contact.
add iv_i to a_sum.
ev_r = a_sum.
endmethod.
start-of-selection.
data: cl_acc sort ref to acc,
lv_ret2 type f,
lv_ret1 sort i.
create object cl_acc exporting iv_d = one.
cl_acc->call( exporting iv_i = 5 ).
cl_acc->call( exporting iv_i = '2.3' importing ev_r = lv_ret2 ).
cl_acc->call( exporting iv_i = two importing ev_r = lv_ret1 ).
write : / lv_ret2 decimals 2 exponent 0 left-justified, / lv_ret1 left-justified.
eight.30
ten [edit] JavaScript Solution
data: lv_source type string,
cl_processor variety ref to cl_java_script,
lv_ret kind string.
cl_processor = cl_java_script=>create( ).
concatenate
'function acc(sum) { '
' return function(n) '
' return sum += n;'
'; '
' }; '
' var x = acc(1); '
' x(5);'
' var ret = acc(3).toString();'
' ret = ret + x(two.three);'
into lv_source.
lv_ret = cl_processor->evaluate( lv_source ).
if cl_processor->last_condition_code <> cl_java_script=>cc_ok.
write cl_processor->last_error_message.
else.
write lv_ret.
write / 'Done'.
endif.
#function (n) # return sum += n;##8.three
[edit] ActionScript
Closures work the same in ActionScript as in JavaScript. ActionScript will transparently convert integers to reals when the function is given a real argument,
Buy Windows 7, but the typeof operator must be utilized to ensure the purpose isn't sent invalid arguments, this kind of as strings (which would silently convert the accumulated quantity to a string without throwing an error).
//Throw an error if a non-number argument is utilized. (typeof evaluates to
// "number" for each integers and reals)
function checkType(obj:Object):void {
if(typeof obj ,
Office Pro Plus 2007!= "number")
throw new ArgumentError("Expected integer or float argument. Recieved " + typeof obj);
}
function accumulator(sum:Object):Function {
checkType(sum);
return function(n:Object):Object {checkType(n); return sum += n};
}
var acc:Function=accumulator(2);
trace(acc(10));
trace(acc(4));
trace(acc("123")); //This causes an ArgumentError to get thrown.
[edit] Aikido
function accumulator (sum:actual) {
return function(n:real) return sum += n
}
var x = accumulator(one)
x(5)
println (accumulator)
println (x(2.3))
Output:
accumulator
8.three [edit] ALGOL 68
Note: Standard ALGOL 68's scoping policies forbids exporting a procedure (or format) out of it can be scope (closure). Hence this specimen will operate on ELLA ALGOL 68, but is non-standard. For a discussion of first-class capabilities in ALGOL 68 consult "The Making of Algol 68" - C.H.A. Koster (1993).
MODE Number = UNION(INT,Real,COMPL);
PROC plus = (Amount within a, in b)Quantity: (
CASE in a very IN
(INT a): CASE in b IN (INT b): a+b, (Actual b): a+b, (COMPL b): a+b ESAC,
(Actual a): CASE in b IN (INT b): a+b, (Genuine b): a+b, (COMPL b): a+b ESAC,
(COMPL a): CASE in b IN (INT b): a+b, (Actual b): a+b, (COMPL b): a+b ESAC
ESAC
);
main: (
# now override the + and +:= OPerators #
OP + = (Quantity a, b)Quantity: plus(a,b);
OP +:= = (REF Number lhs, Quantity rhs)Quantity:
lhs := lhs + rhs;
PROC accumulator = (REF Range sum)PROC(NUMBER)Range:
(Number n)Amount:
sum +:= n;
PROC (NUMBER)Number x = accumulator(LOC Amount := 1);
x(5);
print(("x:",x(two.3), new line));
PROC (NUMBER)Quantity y = accumulator(LOC Range := 100);
y(500);
print(("y:",y(230), new line));
print(("x:",x(0), new line))
)
Output:
x: +.830000000000000e +1
y: +830
x: +.830000000000000e +1 [edit] Argile
use std, array
let A = accumulator 42
print(A 0)
print(A 1)
print(A 10)
print(A 100)
let B = accumulator four.2
print(B 0)
print(B 1)
print(B 10.0)
print(B 100.4)
~A ; ~B
(: use dbg; check mem leak :)
(: accumulator call :)
=: <accumulator a> <num x> := -> (a.t)
get in touch with ((a.func) as operate(any)(a.t)->(a.t)) with (a.info) ((Cgen x) as a.t)
(: accumulator constructors :)
.: accumulator <int x> :. -> int accumulator
(val (int accumulator) A).init(x)
(A as Accumulator).func = ( .:<int& accu, int x>:. ->int accu += x; accu )
A
.: accumulator <actual x> :. -> true accumulator
(val (genuine accumulator) A).init(x)
(A as Accumulator).func = ( .:<real&accu,actual x>:. ->genuineaccu += x; accu )
A
=: <accumulator& a>.init <num x> :=
a = new (Accumulator)
a.information = (new array of one a.t)
*(a.data as (a.t*)) = Cgen x
(: accumulator destructor :)
.: del Accumulator <Accumulator a>:.
free a.data
free a
=: ~ <accumulator a> := del Accumulator a
(: accumulator type :)
class Accumulator
function func
any data
=: [<type t=(int)>] accumulator := -> type
Accumulator.prefix
Accumulator.suffix
autocast accumulator<->Accumulator
[edit] Brat
accumulator = { sum |
n
}
x = accumulator 1
x 5
accumulator 3 #Does not affect x
p x 2.3 #Prints eight.three (1 + 5 + two.three)
[edit] C++
Deviation: The return variety is wrong once the accumulator is called with an integer argument soon after is has been known as with a float argument.
class Acc
{
public:
Acc(int init)
: _type(intType)
, _intVal(init)
{}
Acc(float init)
: _type(floatType)
, _floatVal(init)
{}
int operator()(int x)
{
if( _type == intType )
{
_intVal += x;
return _intVal;
}
else
{
_floatVal += x;
return static_cast<int>(_floatVal);
}
}
float operator()(float x)
{
if( _type == intType )
{
_floatVal = _intVal + x;
_type = floatType;
return _floatVal;
}
else
{
_floatVal += x;
return _floatVal;
}
}
private:
enum {floatType, intType} _type;
float _floatVal;
int _intVal;
};
int main(int argc, char* argv[])
{
Acc a(1);
a(5);
Acc(3);
std::cout << a(2.3f);
return 0;
}
[edit] C#
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(two.3));
}
}
[edit] Clojure
The atom perform creates an atomically updatable identity holding a appeal. The swap! function atomically updates the atom's appeal, returning the new price. The operate returned from an accum get in touch with satisfies every one of the requirements.
(defn accum [n]
(let [acc (atom n)]
(fn [m] (swap! acc + m))))
Similarly, a ref could be used.
(defn accum [n]
(let [acc (ref n)]
#(dosync (alter acc + %))))
[edit] Common Lisp
(defun accumulator (sum)
(lambda (n)
(setf sum (+ sum n))))
Example usage:
(defvar x (accumulator 1))
(funcall x 5)
(accumulator 3)
(funcall x two.3)
This prints:
X
6
#<CLOSURE :LAMBDA (N) (SETF SUM (+ SUM N))>
8.three [edit] D
auto acc(U = genuine, T)(T initvalue) { // U is variety with the accumulator
auto accum = cast(U)initvalue ;
return (U n) { return accum += n ; } ;
}
[edit] E
def foo(var x) {
return fn y { x += y }
}
[edit] Elena
#define basic'* = std'basic'*.
#symbol AccumulatorFactory =
{
new : aValue
[
#var anAccumulator := basic'Variable::aValue.
^ #annex(anAccumulator)
evaluate : aValue [ anAccumulator new:(aValue + anAccumulator). ]
.
]
}.
#symbol Plan =>
[
#var x := AccumulatorFactory new:one.
x evaluate:5.
AccumulatorFactory new:3.
'program'Output << x evaluate:2.3r.
].
[edit] Element
:: accumulator ( n! -- quot ) [ n + dup n! ] ;
1 accumulator
[ 5 swap call drop ]
[ drop three accumulator drop ]
[ 2.three swap call ] tri .
[edit] Fantom
The accumulator purpose is a little unwieldy employing multiple ifs to take care of the type of 'sum' until forced to change. Again, a result from the three concrete Num types, Int, Float and Decimal, all currently being separated inside the API.
class AccumulatorFactory
{
static |Num -> Num| accumulator (Num sum)
{
return |Num a -> Num|
{ // switch on type of sum
if (sum is Int)
// and then type of a
if (a is Int)
return sum = sum->plus(a)
else if (a is Float)
return sum = sum->plusFloat(a)
else
return sum = sum->plusDecimal(a)
else if (sum is Float)
if (a is Int)
return sum = sum->plusInt(a)
else if (a is Float)
return sum = sum->plus(a)
else
return sum = sum->plusDecimal(a)
else // if (sum is Decimal)
if (a is Int)
return sum = sum->plusInt(a)
else if (a is Float)
return sum = sum->plusFloat(a)
else
return sum = sum->plus(a)
}
}
public static Void main ()
x := accumulator (3.1)
y := accumulator (3f)
echo (x(5)) // the Decimal sum combines with an Int
echo (x(2))
echo (y(5.1)) // the Float sum combines with a Decimal
x = accumulator (1)
x (5)
accumulator (3)
echo (x(2.3)) // the Int sum is now a Decimal
}
[edit] Forth
Forth is untyped; this functions on integers.
: accumulator
generate ( n -- ) ,
does> ( n -- acc+n ) tuck +! @ ;
0 accumulator foo
1 foo . \ 1
2 foo . \ 3
3 foo . \ 6
[edit] F#
A statically typed version just isn't possible, but it is quite easy to write dynamically typed functions in F#:
// 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 variety 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 three |> ignore
printfn "%A" (x two.3) // prints "8.3"
[edit] GAP
accu := operate(n)
local f, v;
v := n;
f := perform(a)
v := v + a;
return v;
end;
return f;
end;
a := accu(0);
# function( a ) ... end
b := accu(100);
# purpose( a ) ... end
a(six);
# 6
b(6);
# 106
a(1);
# 7
b(one);
# 107
# These capabilities also accept other types,
Office 2010 Professional, as long as addition is meaningful
b(1/FLOAT_INT(3))
# 107.333
a(2/3);
# 23/3
a([1, 2, 3]);
# [ 26/3, 29/3, 32/3 ]
[edit] Go
Deviations: This does not fulfill condition 2. The result is a float even if you only use integers.
package main
import "fmt"
func accumulator(sum float64) func(float64) float64 {
return func (n float64) float64
sum += n
return sum
}
func main()
x := accumulator(1.0)
x(5.0)
accumulator(3.0)
fmt.Printf("%g\n", x(2.3))
outputs
8.3
[edit] Groovy
Solution:
def accumulator = { Quantity n ->
def value = n;
{ it = 0 -> value += it}
}
Test:
def x = accumulator(1)
println x()
assert x() instanceof Integer
println x(5)
assert x() instanceof Integer
def y = accumulator(3)
println y()
assert y() instanceof Integer
println x(two.3)
assert x() instanceof BigDecimal
println y(10)
assert y() instanceof Integer
println y(200L)
assert y() instanceof Long
println y(two.25D)
assert y() instanceof Double
Output:
1
six
3
eight.three
13
213
215.25
[edit] Haskell
import Control.Monad.ST
import Information.STRef
accumulator :: (Num a) => a -> ST s (a -> ST s a)
accumulator sum0 = do
sum <- newSTRef sum0
return $ \n -> do
modifySTRef sum (+ n)
readSTRef sum
main :: IO ()
main = print foo
wherever foo = runST $ do
x <- accumulator 1
x 5
accumulator 3
x 2.3
outputs
8.3
[edit] Icon and Unicon
At 1st glance you might expect the illustration below to run under Icon; however, as the co-expression calling sequence is Unicon specific.
Strictly speaking, genAcc(n) returns a co-expression, not a operate. However,
the invocation syntax right here is indistinguishable from calling a purpose.
procedure main()
a := genAcc(3)
b := genAcc(5)
write(" " ,center("a",
Microsoft Office Home And Student 2010,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(four.5),5)," ", right(b(one.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
This example produces the output:
a b genAcc: seven 9
genAcc: 9 twelve
genAcc: 13.5 13.three show Icon co-expression calling sequence as a note. [edit] J
See which includes the dissent part.
oleg=:1 :0
a=. cocreate''
n__a=: m
a&(4 : 'n__x=: n__x + y')
)
Example use:
F=: ten oleg
F 11
21
F 12
33
F 11
44
[edit] Java
Java has no first-class capabilities; the standard syntactic workaround is usually to use a standard method name. Java uses objects to maintain state.
public class Accumulator {
personal double sum;
general public Accumulator(double sum0) {
sum = sum0;
}
public double call(double n) {
return sum += n;
}
public static void main(String[] args) {
Accumulator x = new Accumulator(1);
x.call(5);
System.out.println(new Accumulator(3));
System.out.println(x.call(two.3));
}
}
outputs
Accumulator@42e816
8.3
To do a full version that sums with integers as long as achievable ahead of switching to double-precision floats demands a little more work and the use of the Range class...
Optimized
Java has no first-class functions, but with minor syntaxical sugar it does (and yes, this will work in Java 6 and up).
import com.google.typical.base.Purpose;
public class AccumulatorFactory {
private static Function<Double, Double> accumulator(final Double elem) {
return new Function<Double, Double>() {
Double sum = elem;
@Override public Double apply(Double val) {
return sum += val;
}
};
}
public static void main(String[] args) {
Function<Double, Double> x = accumulator(1d);
x.apply(5d);
System.out.println(accumulator(3d));
System.out.println(x.apply(2.3));
}
}
Output:
AccumulatorFactory$1@e86da0
8.3
public class Accumulator {
private Long sumA; // non-null if we're working inside the integer domain
personal double sumB;
general public Accumulator(Amount sum0) {
if (sum0 instanceof Double) {
sumB = sum0.doubleValue();
} else {
sumA = sum0.longValue();
}
}
public Range call(Number n) {
if (sumA != null) {
if (n instanceof Double) {
sumB = n.doubleValue() + sumA;
sumA = null;
return sumB;
}
return sumA += n.longValue();
}
return sumB += n.doubleValue();
}
general public static void main(String[] args) {
Accumulator x = new Accumulator(1);
x.call(5);
Accumulator y = new Accumulator(3);
System.out.println(y+" has price "+y.call(0));
System.out.println(x.call(2.3));
}
}
Producing this sample output:
Accumulator@6100ab23 has appeal 3
8.three [edit] JavaScript
function accumulator(sum) {
return function(n) {
return sum += n;
}
}
var x = accumulator(1);
x(5);
document.write(accumulator(3).toString() + '<br>');
document.write(x(two.3));
output
function (n) return sum += n;
eight.3
function accumulator(sum) function(n) sum += n;
var x = accumulator(1);
x(5);
console.log(accumulator(3).toSource());
console.log(x(2.3));
output
(perform (n) sum += n)
8.three
[edit] Lua
do
local accSum = 0; -- accumulator factory 'upvalue'
function acc(v) -- the accumulator factory
accSum = accSum + (v or 0) -- increment factory sum
local closuredSum = accSum; -- new 'upvalue' at each factory call
return function (w) -- the produced accumulator function
closuredSum = closuredSum + (w or 0) -- increment product 'upvalue'
return closuredSum -- return 'upvalue'
end, accSum -- end of product closure
end--acc
end--end of factory closure
Usage illustration:
x = acc(1) -- x stores the product with preliminary price = 1
x(5) -- add five to x's sum
acc(3) -- add 3 to factory's sum
print (x(two.3)) --> 8.three -- add two.three to x's sum then print the result
y = acc() -- generate new purpose with factory's sum as initial value
print (y()) --> four -- print the accumulated worth inside the product y
[edit] Mathematica
accFactory[initial_] :=
Module[total = initial,
Function[x, total += x]
]
x=accFactory[1];
x[5.0];
accFactory[3];
x[2.3]
outputs
8.3
[edit] Objeck
Uses objects instead of very first class functions.
bundle Default {
class Accumulator {
@sum : Float;
New(sum : Float) {
@sum := sum;
}
method : general public : Call(n : Float) ~ Float {
@sum += n;
return @sum;
}
purpose : Main(args : String[]) ~ Nil {
x := Accumulator->New(1.0);
x->Call(5.0 );
x->Call(2.3)->PrintLine();
}
}
}
[edit] Objective-C
#import <Foundation/Foundation.h>
typedef double (^Accumulator)(double);
Accumulator accumulator_factory(double initial) {
__block double sum = preliminary;
Accumulator acc = ^(double n){
return sum += n;
};
return [[acc copy] autorelease];
}
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Accumulator x = accumulator_factory(1);
x(5);
accumulator_factory(3);
NSLog(@"%f", x(2.3));
[pool drain];
return 0;
}
outputs
8.300000
[edit] OCaml
Deviations: An accumulator instance can take either integers or floats, but not the two mixed (due to lack of runtime polymorphism).
let accumulator sum0 =
let sum = ref sum0 in
fun n ->
sum := !sum +. n;
!sum;;
let _ =
let x = accumulator 1.0 in
ignore (x 5.0);
let _ = accumulator three.0 in
Printf.printf "%g\n" (x two.3)
;;
outputs
8.three
[edit] Oz
A bit unwieldy because the '+' operator does not enable mixed variety operands. The implementation is thread-safe (atomic Exchange operation).
declare
fun {Acc Init}
State = {NewCell Init}
in
fun {$ X}
OldState
in
{Exchange State OldState} = {Sum OldState X}
end
end
fun {Sum A B}
if {All [A B] Int.is} then A+B
else {ToFloat A}+{ToFloat B}
end
end
fun {ToFloat X}
if {Float.is X} then X
elseif {Int.is X} then {Int.toFloat X}
end
end
X = {Acc 1}
in
{X five _}
{Acc three _}
{Show {X 2.3}}
[edit] Perl
sub accumulator {
my $sum = shift;
sub { $sum += shift }
}
my $x = accumulator(1);
$x->(5);
print accumulator(3), "\n";
print $x->(two.3), "\n";
outputs
CODE(0x91131f0)
8.3
[edit] Perl six
sub accum ($n is copy) { sub { $n += $^x } }
Example use:
my $a = accum 5;
$a(four.5);
say $a(.5); # Prints "10".
You can also utilize the "&" sigil to build a operate that behaves syntactically like any other purpose (i.e. no sigil nor parentheses needed to call it):
my &b = accum 5;
say b 3; # Prints "8".
[edit] PHP
<?
function accumulator($start){
return create_function('$x','static $v='.$start.';return $v+=$x;');
}
$acc=accumulator(5);
echo $acc(5); //prints 10
echo $acc(10); //prints 20
?>
[edit] PicoLisp
(de accumulator (Sum)
(curry (Sum) (N)
(inc 'Sum N) ) )
(def 'a (accumulator seven))
(a 1) # Output: -> 8
(a two) # Output: -> 10
(a -5) # Output: -> five
[edit] PostScript
/mk-acc { % accumulator generator
0 add 0 0 2 index put
7 array copy
dup 0 four -1 roll put
dup dup 2 exch put
cvx
} def
% Examples (= is a printing command in PostScript):
/a 1 mk-acc def % develop accumulator #1, name it a
5 a = % add 5 to 1, print it
10 mk-acc % generate accumulator #2, leave it anonymous on the stack
2.71 a = % add 2.71 to 6, print it
dup 3.14 exch exec = % add 3.14 to 10, print it
dup 100 exch exec = % add 100 to 13.14,
Microsoft Office Ultimate 2007, print it
12 a = % add twelve to eight.71, print it
% accumulator #2 is still available on the stack
[edit] Python
>>> def accumulator(sum):
def f(n):
f.sum += n
return f.sum
f.sum = sum
return f
>>> x = accumulator(1)
>>> x(5)
6
>>> x(2.3)
8.3000000000000007
>>> x = accumulator(1)
>>> x(5)
6
>>> x(two.3)
8.3000000000000007
>>> x2 = accumulator(3)
>>> x2(5)
8
>>> x2(three.3)
11.300000000000001
>>> x(0)
8.3000000000000007
>>> x2(0)
11.300000000000001
def accumulator(sum):
def f(n):
nonlocal sum
sum += n
return sum
return f
x = accumulator(1)
x(5)
print(accumulator(3))
print(x(2.3))
outputs
<function f at 0xb7c2d0ac>
8.3
[edit] R
accumulatorFactory <- purpose(init) {
currentSum <- init
function(add)
currentSum <<- currentSum + add
currentSum
}
outputs
> f <- accumulatorFactory(1)
> f(five)
[1] six
> f(2.three)
[1] eight.three [edit] REBOL
make-acc-gen: func [start-val] [
use [state] [
state: start-val
func [value] [
state: state + value
]
]
]
outputs
>> x: make-acc-gen one
>> x 5
== six
>> make-acc-gen 3
>> print x 2.three
8.three
[edit] Retro
Retro only supports integers.
: acc here swap , [ &+! &@ bi ] curry ;
( produce an accumulator operate )
one acc
( and give it a name )
constant x
( add values to it and display the results )
five x do putn
2 x do putn
[edit] Ruby
Ruby has methods and blocks. These are equally real features, but not with the same syntax. Our accumulator factory is a approach that returns a block (in a Proc object). So, x = accumulator(one) is valid, but x(five) is surely an error: the syntax must be x.phone(five) or x[5] (with square brackets). Ruby one.9 also allows x.(5) (with an extra dot).
def accumulator(sum)
lambda {|n| sum += n}
end
# mixing Integer and Float
x = accumulator(1)
x.call(5)
p accumulator(3) # add some output to show what it returns
puts x.call(two.3) # prints eight.3
# mixing Rational and Complex
require 'rational'
require 'complex'
y = accumulator(Rational(2, 3))
y.call(Rational(1, 2))
puts y.call(4)
puts y.call(Complex(0, 1))
puts y.call(Complex.polar(six, five * Math::PI / 4))
puts x.call(0) # again prints 8.3
# utilizing other things that have a + method
t = accumulator(Time.utc(1999, eight, 7, six, 5))
puts t.call(4) # prints 1999-08-07 06:05:04 UTC
require 'matrix'
m = accumulator(Matrix[[1, 2], [3, 4]])
puts m.call(Matrix[[5, 6], [7, 8]])
puts t.call(-12 * 60 * 60) # subtracts 12 hours
puts y.call(1e200)
puts x.call(0) # again prints eight.three Output from Ruby 1.8.6 Output from Ruby one.nine.two
#<Proc:0xba7f30@/tmp/accumulator.rb:2>
8.three
31/6
31/6+1i
0.924025979547381-3.24264068711928i
eight.3
Sat Aug 07 06:05:04 UTC 1999
Matrix[[6, 8], [10, 12]]
Fri Aug 06 18:05:04 UTC 1999
1.0e+200-3.24264068711928i
eight.three
#<Proc:0x000002060d1788@/tmp/accumulator.rb:two (lambda)>
8.three
31/6
31/6+1i
0.9240259795473813-3.2426406871192848i
8.3
1999-08-07 06:05:04 UTC
Matrix[[6, 8], [10, 12]]
1999-08-06 eighteen:05:04 UTC
one.0e+200-3.2426406871192848i
eight.3 [edit] Scala
The kind of a operate can not change in Scala, and there exists no "numeric" sort that is certainly a supertype
of all this sort of types. So, if your accumulator is declared as integer, it can only receive and return
integers, and so on.
def AccumulatorFactory[N](n: N)(implicit num: Numeric[N]) = {
import num._
var acc = n
(inc: N) => {
acc = acc + inc
acc
}
}
Sample:
scala> val x = AccumulatorFactory(one.0)
x: (Double) => Double = <function1> scala> x(five.0)
res7: Double = six.0 scala> AccumulatorFactory(three.0)
res8: (Double) => Double = <function1> scala> println(x(two.three))
eight.3 [edit] Scheme
(define (accumulator sum)
(lambda (n)
(set! sum (+ sum n))
sum))
;; or:
(define ((accumulator sum) n)
(set! sum (+ sum n))
sum)
(define x (accumulator 1))
(x 5)
(display (accumulator 3)) (newline)
(display (x two.3)) (newline)
outputs
#<procedure>
eight.three
[edit] Smalltalk
Object subclass: AccumulatorFactory [
AccumulatorFactory class >> new: aNumber [
|r sum|
sum := aNumber.
r := [ :a |
sum := sum + a.
sum
].
^r
]
]
|x y|
x := AccumulatorFactory new: 1.
x appeal: 5.
y := AccumulatorFactory new: 3.
(x worth: two.3) displayNl.
"x inspect."
"de-comment the previous line to show that x is a block closure"
[edit] Tcl
This uses nested coroutines to manage the state, which for the outer coroutine is a counter utilized to generate unique instances with the inner coroutine, and for the inner coroutine it is the actual accumulator variable. Note that Tcl commands (which includes coroutines) are never nameless, but it really is trivial to synthesize a name for them. It really is possible to guarantee uniqueness of names, but just employing a simple sequence generator gets 90% from the effect for 10% with the effort.
package require Tcl eight.6
# make the creation of coroutines without procedures simpler
proc coro {name arguments body args} {
coroutine $name apply [list $arguments $body] {*}$args
}
# Wrap the feeding of values in and out of a generator
proc coloop {var body} {
set val [info coroutine]
upvar one $var v
while one {
set v [yield $val]
if {$v eq "stop"} break
set val [uplevel one $body]
}
}
# The outer coroutine is the accumulator factory
# The inner coroutine is the particular accumulator
coro accumulator {} {
coloop n {
coro accumulator.[incr counter] n {
coloop i {
set n [expr {$n + $i}]
}
} $n
}
}
Sample usage (extra characters over Paul's instance to show more clearly what is going on):
% set x [accumulator 1]
::accumulator.1
% $x 5
6
% accumulator 3
::accumulator.2
% puts ">>[$x 2.3]<<"
>>8.3<<
[edit] Unicon
Strictly speaking, genAcc(n) returns a co-expression, not a operate. However,
the invocation syntax here is indistinguishable from calling a operate.
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(four.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
Note: The co-expression calling sequence utilised is Unicon specific.
This illustration produces the output:
a b genAcc: 7 nine
genAcc: 9 12
genAcc: thirteen.5 thirteen.3 [edit] UNIX Shell
Deviation from task: The accumulator factory returns a worldwide perform, which stores the sum inside a global variable. Other code can modify the purpose or the variable, perhaps by accident.
The shell is a bad choice for this activity. This illustration plays tricks with eval. The difficulty with eval is to put the quotation marks " and dollar signs $ from the correct place, and escape them together with the correct quantity of backslashes \. One missing (or 1 extra) backslash can ruin the entire system.
#!/bin/sh
accumulator() {
# Define a worldwide perform named $1
# with a world-wide variable named $1_sum.
eval "$1_sum=\$2"
eval "$1() {
$1_sum=\$(echo \"(\$$1_sum) + (\$2)\" | bc)
eval \"\$1=\\\$$1_sum\" # Provide the current sum.
}"
}
accumulator x 1
x r 5
accumulator y 3
x r 2.3
echo $r
y r -3000
echo $r
Output:
$ sh accumulator.sh
8.3
-2997
[edit] VBScript
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
class accumulator
dim A
public default purpose acc(x)
A = A + x
acc = A
end function
public property get accum
accum = A
end property
end class
Invocation
dim a
set a = new accumulator
x = a( 1 )
a 5
dim b
set b = new accumulator
b 3
wscript.echo a(two.three)
Output
8.3 [edit] Yorick
Yorick cannot dynamically develop new functions. Instead, the accum perform can be named in two ways: directly, in which case its initial argument is numerical; or through a closure, exactly where its 1st argument is implicitly an object and the second is the user-provided argument. This illustration uses closures and group objects, which require Yorick 2.two or later.
func accum(knowledge, n)
if(!is_obj(data))
return closure(accum, save(total=data));
save, data, total=data.total + n;
return data.total;
Example of use (interactive session):
> x = accum(one)
> x(5)
six
> y = accum(3)
> x(two.3)
eight.three
> y(2.3)
five.3