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 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.) 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. >>>2) Macros allow you to evaluate arguments zero or more times whereas >>>functions and blocks normally eagerly evaluate arguments once. >> >>Yes, nice idea. My very limited understanding is that this is >>typically used to implement control structures commonly found in other >>languages. > > > Yeah, that's one common application. Hm? Blocks can be used to defer evaluation, using the &block or Proc.new constructs. Or do you mean something else? > I actually come at this from a Dylan POV, not from a Lisp one and Dylan I still wish Dylan hadn't been left to wither...