From: Robert Klemme Date: 2004-08-04T21:26:30+09:00 Subject: Re: Macros in Ruby Just some minor remark... "Joel VanderWerf" schrieb im Newsbeitrag news:41103008.7030107@path.berkeley.edu... > Jesse Jones wrote: > >>Your statement implies that Ruby blocks are > >>equivalent to LISP closures, which is untrue. > > > > > > As far as I can tell Lisp lambda functions (ie closures) do everything > > that Ruby blocks and proc objects do but with cleaner semantics and > > fewer artifical distinctions. > > What are some of the differences? I've been away from lisp for a while.... > > >>>>From what I can tell macros offer three benefits: 1) They allow you to > >>>extend the syntax of the language to directly support your problem > >>>domain. For example, if you work with finite-state machines you can > >>>write a macro that allows you to declaratively define FSMs. > >> > >>I bet it's easy to declaritively define FSMs in Ruby. > > > > > > I'm not so sure, I experimented with defining FSMs in a dynamic > > language with good support for anonymous functions/closures and the > > macro based solution was a whole lot nicer to use. > > I've found ruby blocks to be fairly good for defining declarative > constructs. For example, I based the syntax for a declarative language > for hybrid automata (~ FSMs + ODEs) on this technique. Here's a sample: > > class Vehicle < Component > state :SpeedUp, :SlowDown > > default do > self.x = 0 > self.xDot = 20 > start SlowDown > end You could get rid of the "self" if you defined a method that receives a hash along the lines of: default do values( :x => 0, :xDot => 20 ) start SlowDown end Or even remove the values setting from the block. Since I don't know the inner workings I don't know whether there are other factors that prevent this solution. Just an idea. > setup do > @timer = create(Timer) > end > > flow SpeedUp, SlowDown do > diff "xDot' = xDDot" > diff "x' = xDot" > end > > flow SpeedUp do > alg "xDDot = 3" > end > > flow SlowDown do > alg "xDDot = -3" > end > > transition SpeedUp => SlowDown, SlowDown => SpeedUp do > guard {@timer.tick} > action {puts "Tick!"} > end > end > > (The parsing of all these blocks--using instance_eval plus manual > parsing of the differential/algebraic equations--happens at load time, > then there is a compile stage which generates a dynamic lib and loads > it, and at run time it's mostly native code executing, with an > occasional call to a ruby proc or method.) So you create C code and compile it? > The one respect in which ruby was less than perfectly suitable to this > syntactical problem is having to use "self.x = ..." all the time, but > there are good reasons for that in the bigger picture. See above. Regards robert