From: Christian Szegedy Date: 2002-09-23T22:29:01+09:00 Subject: Re: are functions/methods "first class objects"? 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