David Garamond wrote:
sorry this is a bit philosophical, but i just wonder whether ruby can be
considered a language that treats functions and objects as “first
class”? considering you can’t pass a reference-to-a-method as an
argument to another function/method/block in a straightforward manner.
–
dave
I guess, I understand your question. In fact, Ruby is,
strictly speaking, no functional language.
BUT:
I looked at some different functioanl and equational languages in
the last years: OCAML,Haskell,Q. I have written some small test
programs in them, and I came to the conclusion that Ruby’s blocks,
proc objects and bindings offers you the same advantages and
flexibility as the “functionality” of those languages. In fact,
I think that Ruby’s syntax allows you to do the same tricks more
intuitively. The only thing which is less elegant in Ruby is the
usage of partial functions.
E.g.:
You could write in OCAML:
Hashtbl.iter (Printf.printf “%s %d”) t;;
In Ruby, you have to write:
t.each { |k,v| printf “%s %d”,[k,v] }
(Note, that you had explicitely specify the variables
k and v (key and value), whereas in OCAML,
(Printf.printf “%s %d”) is a function in two variables.)
But I think this is quite a minor issue: for me, using
explicite arguments simply makes my code more readible while using
blocks allows for the same flexibility as the ML notation
(Writing the iterated code where it belongs to). For me,
omitting arguments to construct function objects is mainly a hack:
E.g. you can’t omit the second first argument
in the CAML notation, so it only works under special cirumstances.
Example: In OCAML, if you print function needs some parameter
coming from outside, here: “postfix”, than you also have to write:
Hashtbl.iter (fun k v → Printf.printf “%s %d %s” k v postfix) t;;
which resembles the Ruby way of specifying the arguments explicitely.
Ruby’s way of allowing for naming pieces of codes
is more elegant and intuitive than the lambda calculus
while being equally powerful. If I’d be cynical, I would say :
this is “functional programming for dummies”. In fact this is
another way of looking with the same results.
Ruby allows for defining and handling of partial functions at least as
easily than the functional languages.
E.g.:
l = lambda { |x,y| f(“specialized”,x,“me too”,y) }
(Compared to the CAML syntax: let l = (fun x y → f “specialized” x “me too” y))
Specializes some arguments of the f functions easily.
Of course, you must remember to use brackets to pass the
arguments to the proc object, but this is quite a
minor issue (and has some advantages also).
Using blocks has some other benevolent psychological
and aesthetical aspect: it prevents an inflation of parenthesis.
Whatever you prefer: do … end or
{ … }, it gives valuable hints: this is a piece
of executable code, while the CAML, LISP and smalltalk
syntax is much less balanced in my eyes.
Therefore, I think that Ruby is at least as elegant
and powerful in handling functional features as the functional languges.
Regards, Christian