Accumulator factory: Difference between revisions
added RPL
(Added comment.) |
(added RPL) |
||
(32 intermediate revisions by 18 users not shown) | |||
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>
: 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>:
:: <
x(5);
foo(3);
print x(2.3);</
: It should print <tt>8.3</tt>. <small>''(There is no need to print the form of the accumulator function returned by <tt>foo(3)</tt>; it's not part of the task at all.)''</small>
Line 31:
Where it is not possible to hold exactly to the constraints above, describe the deviations.
<br><br>
=={{header|11l}}==
<syntaxhighlight lang="11l">F accumulator(n)
T Accumulator
Float s
F (Float n)
.s = n
F ()(Float n)
.s += n
R .s
R Accumulator(n)
V x = accumulator(1)
print(x(5))
print(x(2.3))
V x2 = accumulator(3)
print(x2(5))
print(x2(3.3))
print(x2(0))</syntaxhighlight>
{{out}}
<pre>
6
8.3
8
11.3
11.3
</pre>
=={{header|8th}}==
<syntaxhighlight lang="forth">
\ RossetaCode 'accumulator factory'
Line 58 ⟶ 87:
\ results 11,13,16:
( +10 . cr ) 1 3 loop
bye</
{{out}}
Line 72 ⟶ 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.
=== Object Oriented Solution ===
<
class acc definition.
public section.
Line 98 ⟶ 127:
cl_acc->call( exporting iv_i = '2.3' importing ev_r = lv_ret2 ).
cl_acc->call( exporting iv_i = 2 importing ev_r = lv_ret1 ).
write : / lv_ret2 decimals 2 exponent 0 left-justified, / lv_ret1 left-justified.</
{{out}}
<pre>
Line 105 ⟶ 134:
</pre>
=== JavaScript Solution ===
<
cl_processor type ref to cl_java_script,
lv_ret type string.
Line 128 ⟶ 157:
write lv_ret.
write / 'Done'.
endif.</
<pre>#function (n) {# return sum += n;#}#8.3</pre>
Line 135 ⟶ 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).
{{trans|Javascript}}
<
// "number" for both integers and reals)
function checkType(obj:Object):void {
Line 148 ⟶ 177:
trace(acc(10));
trace(acc(4));
trace(acc("123")); //This causes an ArgumentError to be thrown.</
=={{header|Ada}}==
<
with Ada.Text_IO; use Ada.Text_IO;
Line 161 ⟶ 190:
Put_Line (Integer'Image (B.The_Function (3)));
Put_Line (Float'Image (A.The_Function (2.3)));
end;</
<
-- This Ada generic package represents an accumulator factory.
Line 173 ⟶ 202:
function The_Function (X : Integer) return Float;
function The_Function (X : Float) return Float;
end;</
<
-- The accumulator lives through three states. It is in Virgin_State
Line 238 ⟶ 267:
end;
end;</
=={{header|Aikido}}==
{{trans|Javascript}}
<
return function(n:real) { return sum += n }
}
Line 249 ⟶ 278:
x(5)
println (accumulator)
println (x(2.3))</
{{out}}
accumulator
Line 255 ⟶ 284:
=={{header|Aime}}==
<
{
l[0] = l[0] + o;
Line 271 ⟶ 300:
0;
}</
{{Out}}
<pre>8.3</pre>
The type is properly preserved over summing:
<
f(-6);
Line 285 ⟶ 314:
f(-6.6);
f(4.2);
o_form("~: /d1/\n", f(0).__type, f(0));</
{{Out}}
<pre>integer: 6
Line 295 ⟶ 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]}}
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 -->
<
PROC plus = (NUMBER in a, in b)NUMBER: (
Line 327 ⟶ 356:
print(("x:",x(0), new line))
)</
{{out}}
<pre>
Line 338 ⟶ 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>.
<
-- Returns a new script object
-- containing a handler.
Line 353 ⟶ 382:
log y's call(2)
log x's call(3.5)
-- Event Log: (*11*) (*7*) (*14.5*)</
Or, to match the task spec and output a little more closely:
<
set x to foo(1)
Line 375 ⟶ 404:
end |λ|
end script
end foo</
{{Out}}
<pre>8.3</pre>
Line 381 ⟶ 410:
=={{header|Argile}}==
{{works with|Argile|1.1.1}}
<
let A = accumulator 42
Line 433 ⟶ 462:
Accumulator.suffix
autocast accumulator<->Accumulator</
=={{header|Astro}}==
<
n => sum += n
Line 442 ⟶ 472:
print f(5) # 10
print f(10) # 20
print f(2.4) # 22.4</
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
This code works by copying the function FNdummy() onto the heap and returning a pointer to it.
<
dummy = FN(x)(5)
dummy = FNaccumulator(3)
Line 463 ⟶ 493:
PRIVATE sum
sum += n
= sum</
=={{header|Bracmat}}==
<
=
.
Line 481 ⟶ 511:
& accumulator$3
& out$(x$23/10)
)</
Output:
<pre>83/10</pre>
The following solution uses UFP (UnIfancyfied Floating Point) objects to handle the terms in case not both are rational numbers.
<syntaxhighlight lang="bracmat">( ( accumulator
=
.
' ( add sum object addFunction
. ( addFunction
= A B
. !arg:(?A.?B)
& ( !A:#
& !B:#
& "If both values are recognized as integer or fractional values, just use '+'."
& !A+!B
| "Otherwise, create an object for adding two C doubles and let that run."
& ( new
$ (UFP,'(.$($A)+$($B)))
. go
)
$
)
)
& ( object
= add
= addFunction$($arg.!arg)
)
& !(object.add):?sum
& 'addFunction$($($sum).!arg)
: (=?(object.add))
& !sum
)
)
& accumulator$1:(=?x)
& x$5
& accumulator$1:(=?y)
& y$"5.0"
& out$(x$23/10)
& out$(y$"2.3")
)</syntaxhighlight>
Output
<pre>83/10
8.3000000000000007E+00</pre>
=={{header|Brat}}==
<
{ n | sum = sum + n }
}
Line 493 ⟶ 565:
x 5
accumulator 3 #Does not affect x
p x 2.3 #Prints 8.3 (1 + 5 + 2.3)</
=={{header|BQN}}==
Ported from [[Ruby]].
<syntaxhighlight lang="bqn">Acc ← {
𝕊 sum:
{sum+↩𝕩}
}
x ← Acc 1
X 5
Acc 3
X 2.3</syntaxhighlight>
[https://mlochbaum.github.io/BQN/try.html#code=QWNjIOKGkCB7CiAg8J2ViiBzdW06CiAge3N1bSvihqnwnZWpfQp9Cngg4oaQIEFjYyAxClggNQpBY2MgMwpYIDIuMw== Try It!]
=={{header|C}}==
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.
<
//~ Take a number n and return a function that takes a number i
#define ACCUMULATOR(name,n) __typeof__(n) name (__typeof__(n) i) { \
Line 515 ⟶ 602:
printf ("%c\n", z(5)); /* f */
return 0;
}</
=={{header|C sharp|C#}}==
{{works with|C sharp|4.0}}
<
class Program
Line 535 ⟶ 622:
Console.WriteLine(x(2.3));
}
}</
=={{header|C++}}==
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.
<
class Acc
Line 596 ⟶ 683:
std::cout << a(2.3f);
return 0;
}</
{{works with|C++11}}
The following is similar to the above, using lambda functions from C++11. Note that we declared the lambda <code>mutable</code>, which allows us to modify variables that were captured by value. This feature allows us to maintain mutable state, which is essential for an accumulator.
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.
<
#include <functional>
Line 617 ⟶ 704:
std::cout << acc(2.3) << std::endl;
return 0;
}</
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:
<
{
virtual ~CumulantBase_();
Line 641 ⟶ 728:
template<class T_> Accumulator_(const T_& val) { Set(val); }
template<class T_> void Set(const T_& val) { val_.reset(new Cumulant_<T_>(val)); }
</syntaxhighlight>
(This is Coplien's "State" pattern.)
The second issue is that the built-in operator + is a multimethod, implementing a compile-time dispatch and promotion which we must manually reproduce.
<
// various operator() implementations provide a de facto multimethod
Accumulator_& operator()(int more)
Line 674 ⟶ 761:
}
};
</syntaxhighlight>
These rely on coercion functions which switch on the so-far-accumulated type:
<
boost::optional<int> CoerceInt(const CumulantBase_& c)
{
Line 698 ⟶ 785:
return boost::optional<String_>();
}
</syntaxhighlight>
All that remains is to write to the stream:
<
{
return acc.val_->Write(dst);
}
</syntaxhighlight>
=={{header|Ceylon}}==
<
Integer|Float accumulator
(variable Integer|Float n)
Line 724 ⟶ 811:
print(accumulator(3));
print(x(2.3));
}</
{{out}}
Line 735 ⟶ 822:
=={{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):
<
return (m) => {
n = n + m;
Line 747 ⟶ 834:
acc(3);
println(x(2.3)); // Prints “8.300000000000001”.
}</
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:
<
println(y(" World!")); // Prints "Hello World!”.</
But you could constrain the function to numeric types were you so inclined:
<
return (m) => {
n = n + m;
return n;
};
}</
One could go crazy with tagged unions and runtime dispatching to rig something up that adhered more closely to the problem’s specification. But I know of no easier way to “change types” in the fashion necessary.
=={{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.
<
(let [acc (atom n)]
(fn [m] (swap! acc + m))))</
Similarly, a ''ref'' could be used.
<
(let [acc (ref n)]
#(dosync (alter acc + %))))</
=={{header|CoffeeScript}}==
<
(n) -> sum += n
f = accumulator(1)
console.log f(5)
console.log f(2.3)</
=={{header|Common Lisp}}==
{{trans|TXR}}
<
(lambda (n)
(incf sum n)))</
Example usage:
<
(funcall x 5)
(accumulator 3)
(funcall x 2.3)</
{{out}}
<pre>
Line 797 ⟶ 884:
=={{header|Crystal}}==
<
# Make types a bit easier with an alias
alias Num = Int32 | Int64 | Float32 | Float64
Line 810 ⟶ 897:
puts x.call(10) #=> 20
puts x.call(2.4) #=> 22.4
</syntaxhighlight>
=={{header|D}}==
<
void main() {
Line 826 ⟶ 913:
auto accum = cast(U)initvalue ;
return (U n) { return accum += n ; } ;
}</
=={{header|Dart}}==
The <code>=></code> operator is Dart's special syntax for single line closures. When you use it the value of the expression is automatically returned without the return statement.
<code>num</code> is base type for <code>int</code> and <code>double</code>.
Implementation with dynamic typing:
<syntaxhighlight lang="dart">makeAccumulator(s) => (n) => s += n;</syntaxhighlight>
Implementation with static typing (preferred in Dart 2):
<syntaxhighlight lang="dart">typedef Accumulator = num Function(num);
Accumulator makeAccumulator(num s) => (num n) => s += n;</syntaxhighlight>
Verbose version:
<syntaxhighlight lang="dart">typedef Accumulator = num Function(num);
Accumulator makeAccumulator(num initial) {
num s = initial;
num accumulator(num n) {
s += n;
return s;
}
return accumulator;
}</syntaxhighlight>
Usage example for any of above:
<syntaxhighlight lang="dart">void main() {
var x = makeAccumulator(1);
x(5);
makeAccumulator(3);
print(x(2.3));
}</syntaxhighlight>
{{out}}
<pre>
Type checking:
<syntaxhighlight lang="dart">void main() {
var x = makeAccumulator(1);
print(x(5).runtimeType); // int
print(x(2.3).runtimeType); // double
print(x(4).runtimeType); // double
}</syntaxhighlight>
=={{header|Déjà Vu}}==
<
labda i:
set :n + n i
Line 857 ⟶ 969:
drop x 5
drop accum 3
!print x 2.3</
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.Variants}}
<syntaxhighlight lang="delphi">
program Accumulator_factory;
Line 889 ⟶ 1,001:
Writeln(x(2.3));
Readln;
end.</
=={{header|E}}==
<
return fn y { x += y }
}</
=={{header|EchoLisp}}==
<
(define-syntax-rule (inc x v) (set! x (+ x v)))
(define (accumulator (sum 0)) (lambda(x) (inc sum x) sum))
Line 907 ⟶ 1,019:
(x 2.3) → 8.3
</syntaxhighlight>
=={{header|Elena}}==
ELENA
<
= (n => acc.append
accumulator(n)
Line 926 ⟶ 1,038:
console.write(x(2.3r))
}</
{{out}}
<pre>
Line 934 ⟶ 1,046:
=={{header|Elixir}}==
Elixir provides Agents to simplify creating a process to maintain state where mutable variables aren't allowed.
<
def new(initial) do
{:ok, pid} = Agent.start_link(fn() -> initial end)
Line 941 ⟶ 1,053:
end
end
end</
The passing test to exercise the Accumulator and show usage:
<
defmodule AccumulatorFactoryTest do
Line 955 ⟶ 1,067:
assert foo.(2.3) == 8.3
end
end</
{{out}}
Line 965 ⟶ 1,077:
Randomized with seed 587000
</pre>
=={{header|EMal}}==
<syntaxhighlight lang="emal">
in Org:RosettaCode
^|EMal has a mechanism to force the type system to allow nulls on types
|that are usually not nullable, such as int or real.
|In the following code we are telling EMal that int and real implement
|the Number virtual interface, so that it can only
|accept null (because it is an interface), int, and real values.
|^
type Number allows int, real
type AccumulatorUsingNumber
fun foo = fun by Number n
fun g = Number by Number i
return n += i
end
return g
end
type AccumulatorUsingVar
^|EMal has an universal supertype Variable (var) that can be used.
|Some manual type checks are required.
|^
fun checkType = void by var value
if generic!value != real and generic!value != int
Event.error(1, "Only real and int values can be used").raise()
end
end
fun foo = fun by var n
checkType(n)
fun g = var by var i
checkType(i)
return n += i
end
return g
end
type Main
^|we have developed two solutions,
|it is time to create a list holding both data types.
|We iterate over the solutions in order to test them.
|^
List solutions = generic[AccumulatorUsingNumber, AccumulatorUsingVar]
for int i = 0; i < solutions.length; ++i
generic solution = solutions[i]
writeLine("=== solution " + (i + 1) + " ===")
fun x = :solution.foo(1)
x(5)
:solution.foo(3)
watch(x(2.3))
fun y = :solution.foo(1)
y(5)
:solution.foo(3)
watch(y(2))
end
</syntaxhighlight>
{{out}}
<pre>
=== solution 1 ===
Org:RosettaCode:Number, Real: <8.3>
Org:RosettaCode:Number, Integer: <8>
=== solution 2 ===
Variable, Real: <8.3>
Variable, Integer: <8>
</pre>
=={{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.
<
-module(acc_factory).
-export([loop/1,new/1]).
Line 987 ⟶ 1,162:
end
end.
</syntaxhighlight>
=={{header|ERRE}}==
<
PROCEDURE ACCUMULATOR(SUM,N,A->SUM)
Line 1,006 ⟶ 1,181:
ACCUMULATOR(Z,2.3,TRUE->Z)
PRINT(X,Z)
END PROGRAM</
{{out}}
<pre>
Line 1,014 ⟶ 1,189:
=={{header|F Sharp|F#}}==
A statically typed version is not possible, but it is quite easy to write dynamically typed functions in F#:
<
let add (x: obj) (y: obj) =
match x, y with
Line 1,033 ⟶ 1,208:
printfn "%A" (x 5) // prints "6"
acc 3 |> ignore
printfn "%A" (x 2.3) // prints "8.3"</
Actually, it is possible to create a statically typed version by using an inline accumulator creation function.
<
let acc = ref init
fun i ->
Line 1,047 ⟶ 1,222:
acc 5.0 |> ignore
let _ = makeAccumulator 3 // create an unused integer accumulator
printfn "%A" (acc 2.3)</
{{out}}
<pre>8.3</pre>
=={{header|Factor}}==
<
:: accumulator ( n! -- quot ) [ n + dup n! ] ;
Line 1,058 ⟶ 1,233:
[ 5 swap call drop ]
[ drop 3 accumulator drop ]
[ 2.3 swap call ] tri .</
=={{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.
<
{
static |Num -> Num| accumulator (Num sum)
Line 1,111 ⟶ 1,286:
echo (x(2.3)) // the Int sum is now a Decimal
}
}</
=={{header|Forth}}==
Forth is untyped; this works on integers.
<
create ( n -- ) ,
does> ( n -- acc+n ) tuck +! @ ;
Line 1,123 ⟶ 1,298:
1 foo . \ 1
2 foo . \ 3
3 foo . \ 6</
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:
<
: faccumulator ( r "name" -- )
create falign f,
Line 1,137 ⟶ 1,312:
3 s>f faccumulator y \ unused
2.3e x f.
</syntaxhighlight>
=={{header|Fortran}}==
Line 1,155 ⟶ 1,330:
in Fortran77 but was accepted by virtually all compilers.
<
typex function g(i);\
typex i,s,n;\
Line 1,174 ⟶ 1,349:
print *, y(2)
stop
end</
{{out}}
<pre>
Line 1,184 ⟶ 1,359:
Fortran2003 and later supports objects and overloading. The overloaded functions are encapsulated in an object.
<syntaxhighlight lang="fortran">
module modAcc
implicit none
Line 1,263 ⟶ 1,438:
itemp = y%fun(5)
print *, y%fun(2)
end program test</
{{out}}
<pre>
Line 1,278 ⟶ 1,453:
Probably the best we can do is for 'foo' to return the object and then to call the method 'g' directly on that:
<
' uses overloaded methods to deal with the integer/float aspect (long and single are both 4 bytes)
Line 1,326 ⟶ 1,501:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,335 ⟶ 1,510:
=={{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.
<
import "fmt"
Line 1,368 ⟶ 1,543:
accumulator(3)
fmt.Println(x(2.3))
}</
{{out}}
<pre>8.3</pre>
=={{header|Golo}}==
<
----
An accumulator factory example for Rosetta Code.
Line 1,391 ⟶ 1,566:
println(acc(10))
println(acc(100.101))
}</
=={{header|Groovy}}==
Solution:
<
def value = n;
{ it = 0 -> value += it}
}</
Test:
<
println x()
Line 1,422 ⟶ 1,597:
println y(2.25D)
assert y() instanceof Double</
{{out}}
<pre>1
Line 1,434 ⟶ 1,609:
=={{header|Haskell}}==
{{trans|Ruby}}
<
import Data.STRef
Line 1,450 ⟶ 1,625:
x 5
accumulator 3
x 2.3</
{{out}}
<pre>8.3</pre>
'''Note''' The <code>accumulator</code> function could be written in applicative style:
<
where factory s n = modifySTRef s (+ n) >> readSTRef s</
=={{header|Icon}} and {{header|Unicon}}==
Line 1,462 ⟶ 1,637:
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.
<
a := genAcc(3)
b := genAcc(5)
Line 1,478 ⟶ 1,653:
procedure makeProc(A) # A Programmer-Defined Control Operation
return (@A[1],A[1])
end</
This example produces the output:
<pre>
Line 1,489 ⟶ 1,664:
=={{header|Io}}==
<
block(x, sum = sum + x) setIsActivatable(true)
)
Line 1,495 ⟶ 1,670:
x(5)
accumulator(3)
x(2.3) println // --> 8.3000000000000007</
=={{header|J}}==
See
<
a=. cocreate''
n__a=: m
a&(4 : 'n__x=: n__x + y')
)</
Example use:
<
F 11
21
Line 1,511 ⟶ 1,686:
33
F 11
44</
=={{header|Java}}==
Line 1,519 ⟶ 1,694:
{{works with|Java|5 and up}}
<
//implements java.util.function.UnaryOperator<Number> // Java 8
{
Line 1,548 ⟶ 1,723:
}
}
</syntaxhighlight>
{{out}}
<pre>8.3</pre>
Line 1,557 ⟶ 1,732:
{{works with|Java|8 and up}}
<
public class AccumulatorFactory {
Line 1,583 ⟶ 1,758:
System.out.println(x.apply(2.3));
}
}</
=={{header|JavaScript}}==
===ES5===
<
return function(n) {
return sum += n;
Line 1,595 ⟶ 1,770:
x(5);
console.log(accumulator(3).toString() + '<br>');
console.log(x(2.3));</
{{out}}
<pre>function (n) { return sum += n; }
Line 1,601 ⟶ 1,776:
===ES6===
<
let x = accumulator(1);
console.log(x(5));
accumulator(3);
console.log(x(2.3));</
{{out}}
<pre>6
Line 1,611 ⟶ 1,786:
===JavaScript 1.8 (SpiderMonkey Only)===
<
var x = accumulator(1);
x(5);
console.log(accumulator(3).toSource());
console.log(x(2.3));</
{{out}}
<pre>(function (n) sum += n)
Line 1,622 ⟶ 1,797:
=={{header|Jsish}}==
From Javascript ES5 entry.
<
function accumulator(sum) {
return function(n) {
Line 1,665 ⟶ 1,840:
x(5) ==> 17.3
=!EXPECTEND!=
*/</
{{out}}
Line 1,674 ⟶ 1,849:
{{works with|Julia|0.6}}
<
f(n) = i += n
return f
Line 1,683 ⟶ 1,858:
accumulator(3)
@show x(2.3)</
{{out}}
Line 1,691 ⟶ 1,866:
=={{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:
<
fun foo(n: Double): (d: Double) -> Double {
Line 1,712 ⟶ 1,887:
foo(5)
println(y(2))
}</
{{out}}
Line 1,722 ⟶ 1,897:
=={{header|Lambdatalk}}==
Lambdatlk is a functional programming language without closures but with mutable arrays.
<
{def acc
{
{+ {A.toS {A.addlast! :n :a}}}}}
-> acc
1) using a global:
{
-> A
{acc {A} 5}
-> 6
{acc {A} 2.3}
-> 8.3
2) inside a local context:
{let { {:a {A.new 1}}
} {br}{acc :a 5}
{br}{acc :a 2.3}
} ->
6
8.3
</syntaxhighlight>
=={{header|Lang}}==
Lang does not support closures. The use of combinator functions and pointers allows a function to store state.
<syntaxhighlight lang="lang">
fp.accumulator = ($sum) -> {
$sumPtr = $[sum]
fp.f = ($sumPtr, $n) -> {
$*sumPtr += $n
return $*sumPtr
}
return fn.argCnt1(fn.combA2(fp.f, $sumPtr))
}
$x = fp.accumulator(1)
fn.println($x(5))
fp.accumulator(3)
fn.println($x(2.3))
fn.println()
$y = fp.accumulator(1.)
fn.println($y(5))
fn.println($y(2.3))
</syntaxhighlight>
{{out}}
<pre>
6
8.3
6.0
8.3
</pre>
=={{header|LFE}}==
Line 1,740 ⟶ 1,964:
=== Traditional closure ===
<
(defun accum (m)
(lambda (n)
Line 1,746 ⟶ 1,970:
`(#(func ,(accum sum))
#(sum ,sum)))))
</syntaxhighlight>
Since we want to use both the returned function as well as the data for the call, we return a tuple containing both. Using standard LFE pattern matching, we can extract these.
Line 1,769 ⟶ 1,993:
We can creating a looping process which provides the same functionality as the self-calling function in the "traditional closure" approach:
<
(defun loop (m)
(receive
Line 1,783 ⟶ 2,007:
(receive
(sum sum)))))
</syntaxhighlight>
Usage (in the REPL):
Line 1,804 ⟶ 2,028:
=={{header|Lua}}==
A simple implementation:
<
init = init or 0
return function(delta)
Line 1,810 ⟶ 2,034:
return init
end
end</
An expanded example of similar but more complex functionality:
{{works with|Lua|5.1}}
<
local accSum = 0; -- accumulator factory 'upvalue'
function acc(v) -- the accumulator factory
Line 1,825 ⟶ 2,049:
end--acc
end--end of factory closure</
Usage example:
<
x(5) -- add 5 to x's sum
acc(3) -- add 3 to factory's sum
print (x(2.3)) --> 8.3 -- add 2.3 to x's sum then print the result
y = acc() -- create new function with factory's sum as initial value
print (y()) --> 4 -- print the accumulated value inside the product y</
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">\\ M2000 Interpreter
\\ accumulator factory
foo=lambda acc=0 (n as double=0) -> {
Line 1,868 ⟶ 2,090:
print ExpType$(x(0@))="Decimal"
print ExpType$(x())="Double"
print ExpType$(foo(20))="lambda"</syntaxhighlight>
=={{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.
<
local total := initial;
proc( val := 1 ) total := total + val end
end proc:</
Running this, we get:
<
> acc( 5 );
6
Line 1,893 ⟶ 2,114:
> acc( I ); # add the imaginary unit
12.3 - 3. I</
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
Module[{total = initial},
Function[x, total += x]
Line 1,903 ⟶ 2,124:
x[5.0];
accFactory[3];
x[2.3]</
{{out}}
<pre>8.3</pre>
Line 1,917 ⟶ 2,138:
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.
<
:- interface.
Line 1,946 ⟶ 2,167:
!SF ^ elem(Size) := univ(M),
impure set_states(!.SF)
)).</
As used:
<
:- interface.
:- import_module io.
Line 1,974 ⟶ 2,195:
impure R2 = impure_apply(G, -50.0),
io.format("%d, %d\n", [i(N1), i(N2)], !IO),
io.format("%.0f, %.0f\n", [f(R1), f(R2)], !IO).</
{{out}}
Line 1,990 ⟶ 2,211:
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.
<
:- interface.
Line 2,018 ⟶ 2,239:
bump(X, N, N0, N) :-
N = X + N0.</
As used, with the same output:
<
:- interface.
:- import_module io.
Line 2,049 ⟶ 2,270:
),
io.format("%d, %d\n", [i(N1), i(N2)], !IO),
io.format("%.0f, %.0f\n", [f(R1), f(R2)], !IO).</
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">
Accumulator = function(n)
adder = {"sum": n}
adder.plus = function(n)
self.sum += n
return self.sum
end function
adder.getSum = function(n)
obj = self
_sum = function(n)
return obj.plus(n)
end function
return @_sum
end function
return adder.getSum
end function
acc1 = Accumulator(0)
print acc1(10) // prints 10
print acc1(2) // prints 12
acc2 = Accumulator(1)
print acc2(100) // prints 101
print acc1(0) // prints 12
</syntaxhighlight>
{{out}}
<pre>miniscript.exe accumulator.ms
10
12
101
12</pre>
=={{header|Nemerle}}==
Nemerle doesn't have a <tt>dynamic</tt> type, but we can use matching to bind types to <tt>object</tt>s.
<
mutable value : object = n;
fun (i : object) {
Line 2,074 ⟶ 2,333:
x(5);
System.Console.WriteLine(x(2.3));
System.Console.WriteLine(y(3));</
Output:
<pre>8.3
Line 2,080 ⟶ 2,339:
=={{header|NewLisp}}==
<
</syntaxhighlight>
{{out}}
Line 2,103 ⟶ 2,362:
=={{header|NGS}}==
<syntaxhighlight lang="ngs">{
F Acc(start:Int) {
sum = start
Line 2,115 ⟶ 2,374:
echo(acc(5))
echo(acc(2))
}</
{{out}}
<pre>15
Line 2,133 ⟶ 2,392:
Argument to the created accumulator function must be float.
Result is always float.
<syntaxhighlight lang="nim">
proc accumulator[T: SomeNumber](x: T): auto =
var sum = float(x)
Line 2,144 ⟶ 2,403:
discard accumulator(3) # Create another accumulator.
echo acc(2.3) # 8.3
</syntaxhighlight>
{{out}}
Line 2,153 ⟶ 2,412:
=== Fixed accumulator type ===
Argument to the factory function nay be any signed integer, unsigned integer or float.
Argument to the accumulator function must be of the same type.
Result of the accumulator function is also of the same type.
<syntaxhighlight lang="nim">
proc accumulator[T: SomeNumber](x: T): auto =
var sum = x
Line 2,166 ⟶ 2,428:
echo y(2) # 5.5
echo y(3) # 8.5
</syntaxhighlight>
{{out}}
<pre>
Line 2,176 ⟶ 2,438:
=== Customized number type ===
Argument to the factory function must be "int" or "float" (extension to other types is possible).
Argument of the accumulator function is of the customized type "Number" but may be "int" or "float"
thanks to the converters.
Result of the accumulator function is of type "Number" but will be displayed either as "int" or "float"
according to the actual contents.
This solution fulfills the requirements.
<syntaxhighlight lang="nim">
type
Line 2,242 ⟶ 2,511:
discard accumulator(3) # Create another accumulator.
echo acc(2.3) # 8.3
</syntaxhighlight>
{{out}}
Line 2,254 ⟶ 2,523:
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/accumulator_factory.nit the official Nit repository]
<
#
# Nit has no first-class function.
Line 2,275 ⟶ 2,544:
x.call(5)
var y = new Accumulator(3)
print x.call(2.3)</
Output:
Line 2,282 ⟶ 2,551:
=={{header|Objeck}}==
Uses objects instead of first class functions.
<
class Accumulator {
@sum : Float;
Line 2,301 ⟶ 2,570:
}
}
}</
=={{header|Objective-C}}==
{{works with|Mac OS X|10.6+}}
<
typedef double (^Accumulator)(double);
Line 2,327 ⟶ 2,596:
}
return 0;
}</
{{out}}
<pre>8.300000</pre>
Line 2,334 ⟶ 2,603:
{{trans|Ruby}}
Deviations: An accumulator instance can take ''either'' integers ''or'' floats, but not both mixed (due to lack of runtime polymorphism).
<
let sum = ref sum0 in
fun n ->
Line 2,345 ⟶ 2,614:
let _ = accumulator 3.0 in
Printf.printf "%g\n" (x 2.3)
;;</
{{out}}
<pre>8.3</pre>
Line 2,351 ⟶ 2,620:
=={{header|Octave}}==
<
1;
function fun = foo(init)
Line 2,361 ⟶ 2,630:
x(5);
foo(3);
disp(x(2.3));</
=={{header|Oforth}}==
Line 2,369 ⟶ 2,638:
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.
<
#[ n swap + dup ->n ] ;</
Usage :
<
| x y z |
1 foo ->x
Line 2,382 ⟶ 2,651:
"aaa" foo ->z
"bbb" z perform dup . ", z accumulator value is a" . class .cr
;</
{{out}}
Line 2,394 ⟶ 2,663:
=={{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.
<syntaxhighlight lang="oorexx">
x = .accumulator~new(1) -- new accumulator with initial value of "1"
x~call(5)
Line 2,419 ⟶ 2,688:
return sum
</syntaxhighlight>
=={{header|OxygenBasic}}==
Line 2,487 ⟶ 2,756:
=={{header|Oz}}==
A bit unwieldy because the '+' operator does not allow mixed type operands. The implementation is thread-safe (atomic Exchange operation).
<
fun {Acc Init}
State = {NewCell Init}
Line 2,514 ⟶ 2,783:
{X 5 _}
{Acc 3 _}
{Show {X 2.3}}</
=={{header|PARI/GP}}==
<
factory(b,c=0) = my(a=stack[1]++);listput(stack,c);(b)->stack[a]+=b;
foo(f) = factory(0, f); \\ initialize the factory</
Run the factory:<pre>gp > x = foo(1);
Line 2,539 ⟶ 2,808:
{{trans|Ruby}}
<
my $sum = shift;
sub { $sum += shift }
Line 2,547 ⟶ 2,816:
$x->(5);
accumulator(3);
print $x->(2.3), "\n";</
{{out}}
<pre>8.3</pre>
Line 2,572 ⟶ 2,841:
accumulators being visible (??) I suppose you could always just allocate a bit of memory in
accumulator_factory() and return a pointer to that instead of an id/length.
<!--<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: #008080;">function</span> <span style="color: #000000;">accumulate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">accumulators</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">v</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">accumulators</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">r_accumulate</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"accumulate"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">accumulator_factory</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">initv</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">accumulators</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">accumulators</span><span style="color: #0000FF;">,</span><span style="color: #000000;">initv</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">r_accumulate</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">accumulators</span><span style="color: #0000FF;">)}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">call_function</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rid</span>
<span style="color: #000000;">args</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">&</span><span style="color: #000000;">args</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">call_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">standard_function</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span> <span style="color: #008000;">"standard function"</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">r_standard_function</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"standard_function"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">accumulator_factory</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">accumulator_factory</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">call_function</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">call_function</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">call_function</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2.3</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">call_function</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">call_function</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r_standard_function</span><span style="color: #0000FF;">,{})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,613 ⟶ 2,886:
=={{header|PHP}}==
<
function accumulator($start){
return create_function('$x','static $v='.$start.';return $v+=$x;');
Line 2,620 ⟶ 2,893:
echo $acc(5), "\n"; //prints 10
echo $acc(10), "\n"; //prints 20
?></
{{works with|PHP|5.3+}}
<
function accumulator($sum){
return function ($x) use (&$sum) { return $sum += $x; };
Line 2,629 ⟶ 2,902:
echo $acc(5), "\n"; //prints 10
echo $acc(10), "\n"; //prints 20
?></
=={{header|PicoLisp}}==
<
(curry (Sum) (N)
(inc 'Sum N) ) )
Line 2,639 ⟶ 2,912:
(a 1) # Output: -> 8
(a 2) # Output: -> 10
(a -5) # Output: -> 5</
=={{header|Pony}}==
<syntaxhighlight lang="pony">
use "assert"
class Accumulator
Line 2,678 ⟶ 2,951:
r(F64(5.5))
env.out.print("This is okay..." + r().string())
</syntaxhighlight>
=={{header|PostScript}}==
<
{0 add 0 0 2 index put}
7 array copy
Line 2,697 ⟶ 2,970:
dup 100 exch exec = % add 100 to 13.14, print it
12 a = % add 12 to 8.71, print it
% accumulator #2 is still available on the stack</
=={{header|PowerShell}}==
Line 2,705 ⟶ 2,978:
The GetNewClosure method returns a ScriptBlock with captured variables.
<syntaxhighlight lang="powershell">
function Get-Accumulator ([double]$Start)
{
{param([double]$Plus) return $script:Start += $Plus}.GetNewClosure()
}
</syntaxhighlight>
<syntaxhighlight lang="powershell">
$total = Get-Accumulator -Start 1
& $total -Plus 5.0 | Out-Null
& $total -Plus 2.3
</syntaxhighlight>
{{Out}}
<pre>
Line 2,724 ⟶ 2,997:
{{works with|SWI Prolog}}
Uses the module '''lambda''' written by '''Ulrich Neumerkel'''.
<
define_g(N, G) :-
Line 2,738 ⟶ 3,011:
writeln(S),
call(G, 2.3, R1),
writeln(R1).</
{{out}}
<pre>8 ?- accumulator.
Line 2,748 ⟶ 3,021:
=={{header|Python}}==
{{works with|Python|2.x/3.x}}
<
def f(n):
f.sum += n
Line 2,773 ⟶ 3,046:
8.3000000000000007
>>> x2(0)
11.300000000000001</
{{trans|Ruby}}
{{works with|Python|3.x}}
<
def f(n):
nonlocal sum
Line 2,787 ⟶ 3,060:
x(5)
print(accumulator(3))
print(x(2.3))</
{{out}}
<pre><function f at 0xb7c2d0ac>
Line 2,793 ⟶ 3,066:
{{works with|Python|2.5+}}
<
while True:
sum += yield sum
Line 2,801 ⟶ 3,074:
x.send(5)
print(accumulator(3))
print(x.send(2.3))</
{{out}}
<pre><generator object accumulator at 0x106555e60>
8.3</pre>
=={{header|Quackery}}==
===Dynamic, Lambda===
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 )
[ [ stack ] copy tuck put nested
' accumulate nested join ] is factory ( n --> [ )</syntaxhighlight>
{{out}}
Let's see this in action in the Quackery shell.
<pre>/O> 23 factory
...
Stack: [ [ stack 23 ] accumulate ]
</pre>
<code>23 factory</code> has returned an accumulator function initialised to <code>23</code>.
Now let's put <code>100</code> underneath it using <code>swap</code>, perform the accumulator using <code>do</code> and then print the top of stack using <code>echo</code>.
<pre>/O> 100 swap do echo
...
123
Stack: [ [ stack 123 ] accumulate ]
</pre>
The running total has been printed, and the updated accumulator function has remained on the stack. (Everything in Quackery is immutable ''except for'' ancillary stacks (created with <code>[ stack ]</code>), which Quackery has instead of variables. It is rare to embed an ancillary stack in a nest, but this is a good use case.)
Now let's create a second accumulator function with <code>factory</code> and confirm that the two accumulator functions behave independently of one another by <code>do</code>-ing first one of them, then the other.
<pre>/O> 10 6 ** factory
...
Stack: [ [ stack 123 ] accumulate ] [ [ stack 1000000 ] accumulate ]
/O> 234567 swap do echo
...
1234567
Stack: [ [ stack 123 ] accumulate ] [ [ stack 1234567 ] accumulate ]
/O> swap
...
Stack: [ [ stack 1234567 ] accumulate ] [ [ stack 123 ] accumulate ]
/O> 123 swap do echo
...
246
Stack: [ [ stack 1234567 ] accumulate ] [ [ stack 246 ] accumulate ]
</pre>
And since we've finished testing, we should tidy up after ourselves.
<pre>/O> empty
...
Stack empty.</pre>
===Static, Named===
We can create a named version by extending the Quackery compiler, <code>build</code>.
This version does not need to leave a lambda function on the stack, as it can be referred to by name.
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
[ -1 split dup [] = if
[ $ "accumulator needs a starting value."
message put bail ]
do dup number? not if
[ $ "accumulator needs a number."
message put bail ]
[ stack ] copy
tuck put nested
' [ tuck tally share ]
join nested join ] ] builds accumulator ( [ $ --> [ $ )</syntaxhighlight>
{{out}}
First we will check that it complies with The Building Regulations, then we will create two accumulators, <code>foo</code> and <code>bar</code> and use them alternately to confirm they do not affect each other.
<pre>/O> accumulator is foobar
...
accumulator needs a starting value.
Stack empty.
/O> $ "this is a string" accumulator is foobar
...
accumulator needs a number.
Stack empty.
/O> 23 accumulator is foo
... [ 10 6 ** ] accumulator is bar
...
Stack empty.
/O> 100 foo echo
...
123
Stack empty.
/O> 234567 bar echo
...
1234567
Stack empty.
/O> 123 foo echo
...
246
Stack empty.</pre>
=={{header|R}}==
<
currentSum <- init
function(add) {
Line 2,813 ⟶ 3,204:
currentSum
}
}</
{{out}}
<pre>
Line 2,824 ⟶ 3,215:
=={{header|Racket}}==
<
(define ((accumulator n) i)
(set! n (+ n i))
n)
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
<syntaxhighlight lang="raku"
#Example use:
Line 2,844 ⟶ 3,235:
my &b = accum 5;
say b 3; # Prints "8".</
=={{header|REBOL}}==
<
use [state] [
state: start-val
Line 2,854 ⟶ 3,245:
]
]
]</
{{out}}
<pre>>> x: make-acc-gen 1
Line 2,866 ⟶ 3,257:
Retro only supports integers.
<
d:create , [ [ fetch ] [ v:inc ] bi ] does ;</
{{out}}
<pre> #10 'foo acc
Line 2,882 ⟶ 3,273:
This REXX program is partially modeled after the ooRexx example.
<br><br>This example will handle any kind of number: integer, floating point.
<
x=.accumulator(1) /*initialize accumulator with a 1 value*/
x=call(5)
Line 2,894 ⟶ 3,285:
return sum
/*──────────────────────────────────────────────────────────────────────────────────────*/
call: procedure expose sum; sum=sum+arg(1); return sum /*add arg1 ──► sum.*/</
'''output'''
<pre>
Line 2,902 ⟶ 3,293:
=={{header|Ring}}==
<
Func main
Line 2,923 ⟶ 3,314:
return aN[#id#]
}
}","#id#",string(len(aN))))</
{{out}}
Line 2,929 ⟶ 3,320:
6
8.30
</pre>
=={{header|RPL}}==
This implementation complies with all the rules except maybe the last one ("Doesn't store the accumulated value or the returned functions in a way that could cause them to be inadvertently modified by other code"). The accumulated value is actually stored in a global variable, but as its name is generated with the system time, the likelihood of another code guessing it is very low - unless that code deliberately intends to do so.
{{works with|HP|48}}
{| class="wikitable" ≪
! RPL code
! Comment
|-
|
≪
"M" TIME →STR + SWAP
OVER OBJ→ STO
"≪ '" SWAP + "' STO+ SWAP DROP RCL ≫" + OBJ→
≫ ‘<span style="color:blue">FOO</span>’ STO
|
<span style="color:blue">FOO</span> ''( n → ≪ accumulator ≫ ) ''
create a global variable with a timestamp name
initialize variable with n
create lambda function
.
|}
Let's check it works:
{| class="wikitable" ≪
! Command line
! Test example
|-
|
1 <span style="color:blue">FOO</span> 'X' STO
5 X DROP
3 <span style="color:blue">FOO</span> DROP
2.3 X
|
x = foo(1); <span style="color:grey">// X contains ≪ 'M17.3741285888' STO+ LASTARG SWAP DROP RCL ≫</span>
x(5);
foo(3);
print x(2.3);
|}
{{out}}
<pre>
1: 8.3
</pre>
Line 2,934 ⟶ 3,367:
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).
<
lambda {|n| sum += n}
end
Line 2,942 ⟶ 3,375:
x.call(5)
accumulator(3)
puts x.call(2.3) # prints 8.3</
The output of <tt>p accumulator(3)</tt> looks like
Line 2,953 ⟶ 3,386:
This accumulator also works with other types that have a <tt>+</tt> method.
<
require 'complex'
y = accumulator(Rational(2, 3))
Line 2,967 ⟶ 3,400:
require 'matrix'
m = accumulator(Matrix[[1, 2], [3, 4]])
puts m[Matrix[[5, 6], [7, 8]]] # Matrix[[6, 8], [10, 12]]</
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.
<
lambda {|n| sum += n}
end
Line 2,979 ⟶ 3,412:
x(5)
accumulator(3)
puts x(2.3) # prints 8.3</
=={{header|Rust}}==
Line 2,986 ⟶ 3,419:
Changing "x = foo(1.)" to "x = foo(1)" in the code below should not change the output (it does).
<
use std::ops::Add;
Line 3,004 ⟶ 3,437:
foo(3.);
println!("{}", x(2.3));
}</
{{out}}
<pre>
Line 3,012 ⟶ 3,445:
=== 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.
<
#![feature(unboxed_closures, fn_traits)]
Line 3,106 ⟶ 3,539:
s(" ");
println!("{}", s("code"));
}</
{{out}}
<pre>8.3
Line 3,113 ⟶ 3,546:
=={{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.
<
import num._
var acc = n
Line 3,120 ⟶ 3,553:
acc
}
}</
{{out|Sample}}
<pre>
Line 3,138 ⟶ 3,571:
=={{header|Scheme}}==
{{trans|Ruby}}
<
(lambda (n)
(set! sum (+ sum n))
Line 3,152 ⟶ 3,585:
(x 5)
(display (accumulator 3)) (newline)
(display (x 2.3)) (newline)</
{{out}}
<pre>#<procedure>
Line 3,158 ⟶ 3,591:
=={{header|Sidef}}==
<
method add(num) {
sum += num;
Line 3,167 ⟶ 3,600:
x.add(5);
Accumulator(3);
say x.add(2.3); # prints: 8.3</
The same thing can be achieved by returning a closure from the '''Accumulator''' function.
<
func(num) { sum += num };
}
Line 3,178 ⟶ 3,611:
x(5);
Accumulator(3);
say x(2.3); # prints: 8.3</
=={{header|Simula}}==
<
! ABSTRACTION FOR SIMULA'S TWO NUMERIC TYPES ;
Line 3,250 ⟶ 3,683:
END.
</syntaxhighlight>
{{out}}
<pre>
Line 3,260 ⟶ 3,693:
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<
AccumulatorFactory class >> new: aNumber [
|r sum|
Line 3,278 ⟶ 3,711:
(x value: 2.3) displayNl.
"x inspect."
"de-comment the previous line to show that x is a block closure"</
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
<
factory := [:initial |
Line 3,293 ⟶ 3,726:
].
accu2 := factory value:
accu2 value:5.
(accu1 value:2.3) printCR. "-> 8.3 (a float)"
(accu2 value:0) printCR. "-> 15 (an integer)"
(accu2 value:22 factorial) printCR. "-> a large integer"</syntaxhighlight>
{{out}}
<pre>8.3
15
1124000727777607680015</pre>
=={{header|Standard ML}}==
{{trans|OCaml}}
Deviations: An accumulator instance can take ''either'' integers ''or'' reals, but not both mixed (due to lack of runtime polymorphism).
<
val sum = ref sum0
in
Line 3,315 ⟶ 3,755:
in
print (Real.toString (x 2.3) ^ "\n")
end;</
{{out}}
<pre>8.3</pre>
=={{header|Swift}}==
<
return {
sum += $0
Line 3,330 ⟶ 3,770:
x(5)
let _ = makeAccumulator(3)
println(x(2.3))</
{{out}}
<pre>8.3</pre>
Line 3,337 ⟶ 3,777:
{{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.
<
# make the creation of coroutines without procedures simpler
Line 3,364 ⟶ 3,804:
} $n
}
}</
Sample usage (extra characters over Paul's example to show more clearly what is going on):
<
::accumulator.1
% $x 5
Line 3,373 ⟶ 3,813:
::accumulator.2
% puts ">>[$x 2.3]<<"
>>8.3<<</
=={{header|TXR}}==
Line 3,379 ⟶ 3,819:
===Verbose===
<
(lambda (n)
(inc sum n)))
Line 3,387 ⟶ 3,827:
((set num (iread : : nil)))
((format t "~s -> ~s\n" num [f num])))
(exit 0)</
{{out|Run}}
Line 3,409 ⟶ 3,849:
===Sugared===
<
(mapdo (do put-line `@1 -> @[f @1]`) (gun (iread : : nil))))</
{{out}}
<pre>$ echo "1 2 3 4.5" | txr accumulator-factory2.tl
Line 3,422 ⟶ 3,862:
Using the <code>obtain</code>/<code>yield</code> interface to delimited continuations, we can turn an imperative for loop into an accumulation function:
<
(for ((sum (yield-from accum)))
()
Line 3,428 ⟶ 3,868:
(let ((f (obtain (accum))))
(mapdo (do put-line `@1 -> @[f @1]`) (gun (iread : : nil))))</
{{out}}
<pre>$ echo "1 2 3 4.5" | txr accumulator-factory2.tl
Line 3,440 ⟶ 3,880:
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:
<
(count 0))
Line 3,449 ⟶ 3,889:
;; the construction of the function object bound to variable f.
(let ((f (new (accum 0))))
(mapdo (do put-line `@1 -> @[f @1]`) (gun (iread : : nil))))</
=={{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.
<
a := genAcc(3)
b := genAcc(5)
Line 3,469 ⟶ 3,909:
procedure makeProc(A) # A Programmer-Defined Control Operation
return (@A[1],A[1])
end</
Note: The co-expression calling sequence used is Unicon specific.
{{out}}
Line 3,484 ⟶ 3,924:
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}}
<
accumulator() {
# Define a global function named $1
Line 3,501 ⟶ 3,941:
echo $r
y r -3000
echo $r</
{{out}}
<pre>$ sh accumulator.sh
Line 3,509 ⟶ 3,949:
==={{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>.
<
result @ i {
n = `{echo $n + $i | bc}
Line 3,520 ⟶ 3,960:
fn-y = <={accumulator 3}
echo <={x 2.3}
echo <={y -3000}</
== {{header|Ursalang}} ==
Ursalang has only a single number type.
<syntaxhighlight lang="ursalang">let fac = fn(n) {
fn(i) {
n := n + i
}
}
let x = fac(1)
x(5)
fac(3)
print(x(2.3))</syntaxhighlight>
=={{header|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
<
dim A
public default function acc(x)
Line 3,534 ⟶ 3,988:
accum = A
end property
end class</
;Invocation
<
set a = new accumulator
x = a( 1 )
Line 3,543 ⟶ 3,997:
set b = new accumulator
b 3
wscript.echo a(2.3)</
{{out}}
<pre>
Line 3,550 ⟶ 4,004:
=={{header|Wart}}==
<
(fn() ++n)</
Example usage:
Line 3,566 ⟶ 4,020:
=={{header|Wren}}==
<
var x = accumulator.call(1)
x.call(5)
accumulator.call(3)
System.print(x.call(2.3))</
{{out}}
Line 3,588 ⟶ 4,042:
With some extra work, floating point numbers can be incorporated, but outputting would be trickier.
<
; Accumulator factory
; Returns a function that returns the sum of all numbers ever passed in
Line 3,741 ⟶ 4,195:
output: ; Holds the output buffer
resb 11
</syntaxhighlight>
Output
Line 3,752 ⟶ 4,206:
=={{header|XLISP}}==
There are probably other ways of doing it, but this is one way.
<
(lambda (n)
(setq x (+ n x))
x ) )</
Test it in a REPL:
<pre>[1] (define f (accumulator 1))
Line 3,774 ⟶ 4,228:
=={{header|Yabasic}}==
<
local f$
Line 3,787 ⟶ 4,241:
foo$(3)
print execute(x$, 2.3)
</syntaxhighlight>
=={{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.
<
if(!is_obj(data))
return closure(accum, save(total=data));
save, data, total=data.total + n;
return data.total;
}</
Example of use (interactive session):
<pre>> x = accum(1)
Line 3,808 ⟶ 4,262:
=={{header|zkl}}==
<
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>
Line 3,822 ⟶ 4,276:
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|Commodore BASIC}}
{{omit from|C}} <!-- C's type system imcompatible with task spec -->
{{omit from|ML/I}}
{{omit from|Scratch|cannot generate functions nor pass them as arguments or values}}
|