Accumulator in Four Languages
The Problem
Implementing accumulator using closure.
The Solutions
Common Lisp
As strongly influenced by Lambda Calculus, it's straight forward in Lisp family.
1 ; No. 1 2 (defun accumulator (n) 3 (lambda (i) 4 (setf n (+ n i)))) 5 6 ; No. 2 7 (defun accumulator (n) 8 (lambda (i) (incf n i)))
Haskell
As a pure-functional language, changing data in place in Haskell needs more work and Monad's, it's usually not recommended.
1 import Data.IORef 2 3 accumulator :: Num a => a -> IO (a -> IO a) 4 accumulator n = do 5 s <- newIORef n 6 return (\i -> do 7 modifyIORef s (i+) 8 readIORef s) 9 10 main :: IO () 11 main = do 12 a <- accumulator 10 13 a 12 14 sum <- a 20 15 print sum
Python
In Python 2, Without the help of nonlocal
, changing immutable free
variable inside a closure needs some hack.
Changing immutable free variable is such a contradictory, horrible phrase, while technically correct, "rebinding a name (inside a closure)" maybe more understandable to Python users.
1 # python 3.x 2 def accumulator(n): 3 def acc(i): 4 nonlocal n 5 n += i 6 return n 7 return acc 8 9 # python 2.x, No. 1 10 def accumulator(n): 11 def acc(i): 12 acc.s += i 13 return acc.s 14 acc.s = n 15 return acc 16 17 # python 2.x, No. 2 18 def accumulator(n): 19 def acc(i, n=[n]): 20 n[0] += i 21 return n[0] 22 return acc 23 24 # python 2.x, No. 3 25 def accumulator(n): 26 s = [n] 27 def acc(i): 28 s[0] += i 29 return s[0] 30 return acc
Vala
Including output to stdout, just for fun.
1 delegate int AccuFunc(int i); 2 3 AccuFunc accumulator(int n) { 4 return (i) => n += i; 5 } 6 7 void main() { 8 int[] numbers = {2, 3, 4, 5, 8, 20}; 9 var a = accumulator(0); 10 foreach (var i in numbers) 11 stdout.printf("%2d + %2d = %2d\n", a(0), i, a(i)); 12 stdout.printf("The Ultimate Answer is %d.\n", a(0)); 13 }
The sole purpose of this post is for testing the capability of syntax highlighting of Pygments.