Higher order ruby


#1

foo = lambda {|x| lambda {|y| return x+y}}

foo.call(3)(4)

Why this doesn’t work? I expected lamdas to behave like in SML.


#2

On Wed, Jan 14, 2009 at 11:09 AM, zslevi removed_email_address@domain.invalid wrote:

foo = lambda {|x| lambda {|y| return x+y}}

foo.call(3)(4)

Why this doesn’t work? I expected lamdas to behave like in SML.

When you call foo, or apply it with [], you get another lambda in
return.
To call that lambda you have to use call again, or []:

irb(main):001:0> foo = lambda {|x| lambda {|y| return x+y}}
=> #Proc:0xb7bb5f28@:1(irb)
irb(main):002:0> foo[3][4]
=> 7
irb(main):003:0> foo.call(3).call(4)
=> 7

Jesus.


#3

foo.call(3).call(4) should work

blambeau


#4

I even tried

foo = lambda {|x| lambda return {|x,y| return x+y}}

(foo.call(3)).call(4)

But it doesn’t work either.


#5

zslevi wrote:

foo = lambda {|x|
return lambda {|y| return x+y}}

puts (foo.call(3)).call(4)

It works finally, but it’s just too verbose.
Can anyone suggest a shorter, programmer friendlier way of writing
this?

foo[3][4] as shown above. And you don’t need ‘return’ inside the lambda.

foo = lambda {|x| lambda {|y| x+y}}
foo[3][4]


#6

foo = lambda {|x|
return lambda {|y| return x+y}}

puts (foo.call(3)).call(4)

It works finally, but it’s just too verbose.
Can anyone suggest a shorter, programmer friendlier way of writing
this?


#7

On Wed, Jan 14, 2009 at 11:14 AM, zslevi removed_email_address@domain.invalid wrote:

foo = lambda {|x|
return lambda {|y| return x+y}}

puts (foo.call(3)).call(4)

It works finally, but it’s just too verbose.
Can anyone suggest a shorter, programmer friendlier way of writing
this?

As said before you don’t need the returns, and you don’t need so many
parentheses.
Can you let us know if this works for you?

irb(main):004:0> foo = lambda {|x| lambda {|y| x + y}}
=> #Proc:0xb7b9c758@:4(irb)
irb(main):005:0> foo.call(3).call(4)
=> 7
irb(main):006:0> puts foo.call(3).call(4)
7
=> nil
irb(main):007:0> puts foo[3][4]
7
=> nil

Jesus.


#8

zslevi removed_email_address@domain.invalid writes:

foo = lambda {|x|
return lambda {|y| return x+y}}

puts (foo.call(3)).call(4)

It works finally, but it’s just too verbose.
Can anyone suggest a shorter, programmer friendlier way of writing
this?

What about:

irb(main):038:0> (foo = (lambda {|x| (lambda {|y| (x + y)})}))
#Proc:0x00007f797ea420f0@:38(irb)
irb(main):039:0> (funcall (funcall foo,3),4)
7

(See the “functional programming” thread).

or you could write:

(def uncurry(f,arg)
   (funcall f,arg)
end)

and then:

(uncurry (uncurry foo,3),4)

#9

zslevi wrote:

foo = lambda {|x|
return lambda {|y| return x+y}}

puts (foo.call(3)).call(4)

It works finally, but it’s just too verbose.
Can anyone suggest a shorter, programmer friendlier way of writing
this?

Can you see that “proc” is shorter than “lambda”?

foo = proc{|x| proc{|y| x+y}}
==>#Proc:0x02824eb4@:20(irb)
foo[3][4]
==>7


#10

On Jan 14, 11:09 am, zslevi removed_email_address@domain.invalid wrote:

foo = lambda {|x| lambda {|y| return x+y}}

foo.call(3)(4)

In ruby 1.9, you could also do:
foo.(3).(4)

You also have a curry method:

bar = lambda {|x,y| x + y}
bar.curry[3].(4)

-tom


#11

William J. schrieb:

Can you see that “proc” is shorter than “lambda”?

foo = proc{|x| proc{|y| x+y}}
==>#Proc:0x02824eb4@:20(irb)
foo[3][4]
==>7

Javascript:
3+4

Andr


#12

Gregory B. wrote:

But also not the same thing on Ruby 1.9, so it’s important to be
careful about this generally, even if it works fine with either in the
above example.

Yep, it’s best to avoid proc{} entirely, since in ruby 1.8 it’s an alias
for lambda{}, but in ruby 1.9 it has changed to be an alias for
Proc.new{}.

For the full gory details see
http://innig.net/software/ruby/closures-in-ruby.rb


#13

On Thu, Jan 15, 2009 at 5:54 AM, William J. removed_email_address@domain.invalid
wrote:

Can you see that “proc” is shorter than “lambda”?

foo = proc{|x| proc{|y| x+y}}
==>#Proc:0x02824eb4@:20(irb)
foo[3][4]
==>7

But also not the same thing on Ruby 1.9, so it’s important to be
careful about this generally, even if it works fine with either in the
above example.

def foo
proc { return }.call
puts “Never gets printed”
end
=> nil

foo
=> nil

def bar
lambda { return }.call
puts “Gets Printed”
end
=> nil

bar
Gets Printed
=> nil

RUBY_VERSION
=> “1.9.1”