On Github parsonsmatt / currb
Just...
look around you!
Have you worked out what we're looking for?
invented by Moses Schönfinkel
(discovered by Hubert Kennedy)
First, you need a function
add = lambda do |x, y| x + y end add.call(5, 6)
More tersely,
add = -> x, y { x + y } add[5, 6]
Now, instead of returning the value, wrap the value in a lambda.
add = lambda do |x, y| lambda do x + y end end add.call(5, 6).call
Now, just move the argument from the outer lambda to the inner lambda!
add = lambda do |x| lambda do |y| x + y end end add.call(5).call(6)
Y'all are curry masters!
foo = lambda do |x| 2 * x + 1 end bar = lambda do |x| x ** 2 end (foo * bar).call(x) == foo.call(bar.call(x))
Ruby doesn't have a function composition operator...
... yet!!
class Proc def *(other) lambda do |x| self.call(other.call(x)) end end end
Bash pipes!
# How many classes are defined in your app? $ cat **/*.rb | grep "^class" | wc -l
# Using the * style: $ (wc -l * grep "^class" * cat)( **/*.rb ) $ wc -l ( grep "^class" ( cat ( **/*.rb ) ) )
Those Unix commands are partially applied!
$ wc -l **/*.rb $ grep "^class" **/*.rb $ cat **/*.rb
Unfortunately, Ruby doesn't have the pipe composition operator...
... yet!
class Proc def |(other) lambda do |x| other.call(self.call(x)) end end end
function update(index, item) { App.data[index] = item; } function renderItems() { return App.data.map(function (item, index) { return new Item(item, update.bind(this, index)); }); }
function update(index) { return function (item) { App.data[index] = item; } } function renderItems() { return App.data.map(function (item, index) { return new Item(item, update(index)); }); }
let update = index => item => App.data[index] = item; function renderItems() { return App.data.map( (item, index) => new Item(item, update(index)) ); }
add = -> x, y { x + y }Java
public static int add(int x, int y) { return x + y; }Haskell
add :: Int -> Int -> Int add x y = x + yMath $add : \mathbb{Z} \rightarrow \mathbb{Z} \rightarrow \mathbb{Z}$$ add(x, y) = x + y $
a transformation from something to some other thing
represented like: $$ A \rightarrow B $$
where $A$ is the type of the original thing, and $B$ is the type of the new thing, and the arrow ($\rightarrow$) represents the transformation
Ruby is Object Oriented, not Lambda or Function Oriented.
Is there an equivalence? How can we translate these ideas?
RCaaF -- startup idea!
(this is kinda out there so please stop me and ask questions if you want)
How to make a Ruby class like a function?
$$ f : A \rightarrow B $$Where:
A Duck is the methods we care about on some object.
class F attr_reader :b def initialize(object) @b = object.a end end
Objects from F have the duck b, and it's input argument has the duck a
class G attr_reader :a def initialize(object) @a = object end end
Objects from G have the duck a, and it's input argument doesn't have a duck
>> F.new( G.new( 5 ) ).b => 5
I wrote the gem Beethoven to make this sort of thing easier
The following are equivalent:
F.new(G.new(5)).b
(F * G).new(5).b
(G | F).new(5).b
[G, F].reduce(&:|).new(5)
Single argument functions are boring...
lambda do |x, y| x + y end.call(5, 6)to
lambda do |x| lambda { |y| x + y } end.call(5).call(6)
Class#new
class Add def initialize(x) @x = x end def new(y) @y = y; return self end def value @x + @y end end
>> Add.new(5).new(6).value => 11
class Map def initialize(func) @func = func end def new(object) @list = object.list; self end def list @list.map(&@func) end end
class Filter def initialize(func) @func = func end def new(object) @list = object.list; self end def list @list.filter(&@func) end end
class Reduce def initialize(func) @func = func end def new(object) @list = object.list; self end def value @list.reduce(&@func) end end
List = Struct.new(:list) list = List.new( (1..100).to_a ) Reduce.new(-> sum, next { sum + next }).new( Map.new(-> x { x + 10 }).new( Filter.new(-> x { x.even? }).new(list) ) ).value => 3050
Pipeline = Filter.new(-> x { x.even? }) | Map.new(-> x { x + 10 }) | Reduce.new(-> sum, next { sum + next }) Pipeline.new(list).value => 3050
even = -> x { x.even? } add_ten = -> x { x + 10 } add = -> x, y { x + y } Pipeline = Filter.new(even) | Map.new(add_ten) | Reduce.new(add) Pipeline.new(list).value => 3050
even = -> x { x.even? } add = -> x, y { x + y }.curry Pipeline = Filter.new(even) | Map.new(add.call(10)) | Reduce.new(add) Pipeline.new(list).value => 3050
Ruby and JavaScript @(we're they're hiring!)
Now, Haskell @ Layer 3 Communications