From: James Tucker Date: 2007-05-27T16:09:14+09:00 Subject: Re: Developing cross-platform web/GUI applications Jon Harrop wrote: > M. Edward (Ed) Borasky wrote: >> Well, I wouldn't call Ruby a "functional" programming language in the >> same sense as Lisp/Scheme, Haskell and Erlang define themselves as >> functional programming languages. > > Ok. I'm from an OCaml/F# background. May I just ask if anyone can translate > the following OCaml one-liner into Ruby: > > let rec nest ?(n=2) f x = if n=0 then x else nest ~n:(n-1) f (f x) > > it nests "n" applications of "f" to "x" with "n" defaulting to 2 if it isn't > specified, e.g. "nest ~n:3 f x" gives f(f(f(x))). > > This trivial example encapsulates much of what I love about OCaml and it > doesn't translate well into any other language that I know. > If I understood your description, and the code correctly, this should work: n ||=2; if n == 0; x else n.times do x = f x; end end or should that be: n ||=2; f ( x = if n == 0; x; else; n.times do x = f x; end; x; end ) of course, you could recurse using a temporary value rather than x, if you wanted to. initialize an example with: def f x; 2 * x; end; x = 2 I'm sure there's probably a more 'functional' way also. If I do have your example correct, I should think a generic recursor function would not be hard to implement in ruby. In fact: def recurse func, depth, *initials working = initials depth.times do working = func.call *working end working end Initialize like so: def f x, y [2 * x, 1 * y] end x,y=2,10 Use like so: recurse method(:f), 2, x, y n.b. this should work for arbitrary argument lengths provided the called function returns an array of arguments for itself. Does this satisfy? Oh, I thought I'd add a block version too, just for all those people that love blocks (and because it may be useful in this context): def recurse_blk depth, *initials, &blk working = initials depth.times do working = yield(*working) end working end example: recurse_blk(2, x, y) do |a,b| f(a,b) end Enjoy.