From: Mauricio Fernandez Date: 2007-05-30T19:00:59+09:00 Subject: Re: Ruby & OCaml (was Re: Underscore) On Wed, May 30, 2007 at 11:10:21AM +0900, Jon Harrop wrote: > Mauricio Fernandez wrote: > > Actually, in Ruby 1..n is a Range object which responds to the #inject > > message without creating an intermediate array, > > Laziness, yep. > > > ... > > class ... > > You wouldn't use objects to do this in OCaml though. If you wanted to fold > over a data structure you'd just write: > > let nest n f x = fold (fun x _ -> f x) x {1 .. n} Indeed; I was just illustrating a part of Ruby's object model (mixins) with OCaml code. BTW, is {1.. n} a F# range comprehension or have you written some camlp4 extension that looks like that (or is it only pseudocode)? > > # >> user system total real > > # >> each 0.610000 0.000000 0.610000 ( 0.618960) > > # >> inject 1.800000 0.020000 1.820000 ( 1.850604) > > (yes, it really is that slow) > > > > Also, Ruby doesn't optimize tail calls, so you cannot write the sort of > > recursive functions OCaml excels at. OTOH, the core classes provide much > > more functionality, and more often than not the existing higher-order > > functions will fit the bill. > > I think this is equivalent: [...] > # time (loop 100 (fun a -> Array.fold_left (+) 0 a)) a;; > Time: 0.203969 > - : unit = () > > So the interpreted OCaml bytecode is ~6x faster and compiled OCaml is ~260x > faster. On a rather old box, ocaml runs that in 0.28s (vs. Ruby's 0.61s with #each, #1.8s with inject), and an imperative expansion (with for and a ref) in 0.17s, so the ratios are fold_left/inject 6.4X imperative 3.6X HOFs in Ruby are often more expensive than they would be in OCaml because method and especially block (anonymous function) calls are quite slow. However, on Ruby 1.9, still under development and expected to be released by xmas 2007: $ ruby19 -v bm.rb ruby 1.9.0 (2007-02-07 patchlevel 0) [i686-linux] user system total real each 0.230000 0.000000 0.230000 ( 0.228493) inject 0.310000 0.000000 0.310000 ( 0.313735) making it comparable to OCaml's bytecode, which is hardly surprising since they are both stack machines with threaded code/computed gotos. -- Mauricio Fernandez - http://eigenclass.org - singular Ruby