Arity Makes Good Curry #
kig just dropped this snip in the comments of the pipes discussion, which had morphed into a discussion about functional programming.
class Fun < Proc def call(*args) if args.size < arity.abs and arity != -1 Fun.new{|*a| call(*(args+a)) } else super end end alias_method :[], :call end def fun &block Fun.new &block end f = fun{|a, b, c| a * b / c } f[10, 20, 30] == f[10][20][30] #=> true
You can sort of curry methods with this, like so:
class Turtle def draw *args fun { |x, y| ... }.call(*args) end end
But you will need to use the bracket syntax on the function returned by the method.
Dave Burt
I predict that the thread below will contain an improved recipe for method currying, so stay tuned!
kig
Oho, good point with -arity. Another thing would be handling block arguments, any idea with that? E.g.
Dave Burt
Exactly what you posted will work in Ruby 1.9, but procs can’t take blocks in 1.8.
Danno
Pardon, but where is arity defined?
Dave Burt
arity is a method of Proc and Method and UnboundMethod.
Ian
Here’s arity in Programming Ruby’s online reference if you want to be specific about it.
kig
thoughtcode experiments, how about mixing Enumerables and Procs?kig
trans
On Suby we discussed a bit we picked up from Nemerle:
Apply it too lambdas just as well. Would be a cool feature.
MenTaLguY
Okay, so we’ve got:
Any other “scary” functional programming things left to do in Ruby? Because I feel like we are running out.
I mean, I suppose we could always do the old “Ruby Objects are really just functions” routine.
Y’know, because they are. They’re closures over their instance variables. Their first parameter is a method name.
MenTaLguY
(Once we’re done here I think I’m going to make a raskell.rb with all this stuff in. Just for kicks.)
MenTaLguY
Incidentally, once you see that objects are functions, it’s apparent that
Object#method
simply curries in the first argument.kig
Hindley-Milner type inference? I kid, I kid.
The Objects as functions -trick made me giggle with glee, good job.
I found the following amusing:
jo
Haskell-style datatype.rb still seems to have room for improvement(cvs.m17n.org/viewcvs/ruby/).
nuro
Here is a functional-style one-liner to create n-dim arrays:
md = lambda {|*ds| Array::new(ds.shift || 0).map {md[ds] unless ds.empty? }}; nar = md.call(8, 3, 5); puts nar.inspect
nuro
correction: ... md[*ds] ...
t
Yes!! Please.
Comments are closed for this entry.