From: Alexander Schofield Date: 2001-10-28T09:16:16+09:00 Subject: [ruby-talk:23654] Re: Ruby macros Leo wrote: > Hi Ruby experts, I make no such claim, but I'm going to respond anyways. Robert Feldt wrote: > However, to me it seems as a potential drawback would be that you're effectively changing the programming language so that a future maintainer will have to learn your Ruby dialect before understanding whats happening. Or is this countered by the fact that the dialect is closer to the problem domain? In ANSI CL, "changing the programming language" is *exactly* what macros do. They are, "programs that write programs", or functions that allow controlled evaluation of their arguments. When combined with all of CL's other features (let was mentioned also labels and gensyms-- in other words arbitrary scoping and uninterned symbols-- so even nested macro's will work fine, far beyond the capabilities of a mere preprocesser) a macro can effectively change the language, although in CL this is almost always taken to mean that you keep the S-expression syntax but just bring it closer to the problem domain. There are small exceptions to even this though, many of the looping constructs in CL interpret a lone symbol to signify a point of execution (for ugly goto's, generally only used as primitives for more advanced looping constructs). But I'm rambling. Basically though macros as in CL are nothing to fear, but something to embrace and revel in. A few changes to a language are nothing to fear as long as the behavior of the new mini-language (or not so mini) is well documented and dramatically simplifies the problem, they are much more than a clumsy hack for lazy evaluation (contrary to whatever some Haskellers will tell you). Someone mentioned an S-expression syntax for Ruby, I'd be very interested in that. But if you are willing to give up the elegant Ruby syntax, it seems to me that it would be far easier to write a Ruby OO system in CL (as CL's own CLOS is, maybe you could call it the Ruby Object System, or ROS?) than it would be to try and force an S-expression syntax on Ruby. The possibilities opened up by this would be fascinating, since you would get all of CL's goodies for free, including packages, which would effectively take the place of namespaces opened up on the most recent Eckel thread, to say nothing of an elegant macro system, which would certainly be what the majority of ROS would be, just like CLOS. As long as everyone else gets to post their own Lisp-wishlist, I have something that's been festering in me for a long time. Why not take a portion of CLOS's multi-methods and apply it in Ruby? Specifically, I'm ambivalent about auxilliary methods (before, after, and around), but like the part about generic functions. For those of you who aren't Lisp fans, generic functions are 'functions'-- though even in CLOS 'methods', might be a better name-- that are made up of one or more methods whose parameters are 'specialized'-- or have optional type declaration. when a generic function is called it examines its parameters and chooses the most specialized method. This is a little like what C++ and Java call function and method overloading, but it is far more flexible, providing all (performance aside) benefits of so-called static-typing, while in fact being perfectly compatible with Ruby's dynamic philosophy. For those who think this is somehow just static typing in disguise go ask in comp.lang.lisp or comp.lang.clos. If you are a Java fan you could program using generic functions as if it was just static typing, but in fact it allows you to do much more. I have no idea how this would be implemented under the hood, or how difficult it would be, but from a pure OO standpoint it would be quite straightforward. You could have a MultiMethod (subclass of Method) take the place of Method in an object whenever necessary, and choose the correct code to execute by examining the type of the arguments passed to it against the types of the specified execution branches and choose the most specialized one (I say execution branches because I'm not sure how it would be implemented, since you couldn't have the execution branches as attributes of the MultiMethod object, because the idea is to write them just like normal methods of the class, able to access all instance and class methods and attributes normally). Enough. Opinions anyone?