Functional programming
Partial application
first = |f,x| |y| f(x,y)
second = |f,y| |x| f(x,y)
# Variadic, fix first arguments
first = |f,*a| |*b| f(*(a+b))
# Variadic, fix last arguments
last = |f,*a| |*b| f(*(b+a))
Currying
function curry(f)
n = f.argc()
a = list(0..n-1)
g = fn|x| a[n-1]=x; f(*a) end
for i in 2..n
g = fn|x| a[n-i]=x; g end
end
return g
end
curry = fn|f|
n = f.argc(); a = list(0..n-1)
return (2..n).reduce(
fn|x| a[n-1] = x; f(*a) end,
|g,i| fn|x| a[n-i] = x; g end) end
uncurry = |f| |*a| a.reduce(f,|g,x| g(x))
Fixed-point combinator
# Y-combinator
fix = |F| (|x| x(x))(|x| F(|n| x(x)(n)))
# by built-in recursion
fix = |F| fn g|n| F(g)(n) end
# without currying
fix = |F| fn g|n| F(g,n) end
# with memoization
fix = fn|F|
m = {}
return fn g|n|
if n not in m then m[n] = F(g,n) end
return m[n]
end
end
# one argument example: factorial function
fac = fix(|f| |n| 1 if n==0 else n*f(n-1))
# without currying
fac = fix(|f,n| 1 if n==0 else n*f(n-1))
# two argument example: integer power
pow = fix(|f| |[x,n]| 1 if n==0 else x*f([x,n-1]))
# without currying
pow = fix(|f,[x,n]| 1 if n==0 else x*f([x,n-1]))
for n in 0..10
print([n,fac(n)])
end
for n in 0..10
print([n,pow([2,n])])
end
Composition
Function.mpy = |g;f| |x| g(f(x))
compose = |*a| |x| a.rev().reduce(x,|y,f| f(y))
f = |x| 2*x
g = |x| x+1
print((g*f)(2))
print(compose(g,f)(2))