Basically, one of the goals of Perl6 was to allow for you to implement any perl construct, in perl. None of the operators were to use any special features that could not be done by regular subroutines. And personally, I don't see how we're going to be able to do all this lazy evaluation of parameters (and, if/else, etc), different lexical scopes for passed coderefs (foreach), and so on. Lisp macros provide the ability to implement the semantics of every single one of these constructs, but unfortunately, has the horribly monotonous syntax. And so my goal is to provide those same semantics to Perl, with the wonderfully appropriate and concise syntax. I'm not sure whether such a goal is achievable, however.
> Ok, ignoring the fact ${ $body } seems to be wildly non-intuitive syntax > for a single-interpolation, I don't see the value of manipulating macros > as string at all. We have eval for that (eval+anon subs+closures is 99% > of what LISP macros are, and I think that's what you're modeling this > after). Fine, I agree that manipulating macros as strings isn't a great idea. But it's the closest way to perform the perl equivalent to the lisp original. > Macros could add something to Perl, but I don't see why having a macro > return a string instead of looking and acting like a subroutine would be > a bad thing. In fact, as I pointed out before, you can do almost all of > the scoping stuff that you would want out of a macro in Perl with the > existing subroutine/code ref syntax and a special property. I disagree here. How would I define foreach as a macro (assuming the following, simplified syntax). foreach $each, @array, { print $each; }; Since $each is being passed to the foreach macro, the macro needs to create a lexical scoping for $each, and place the third argument as a loop body, within the context of the scoping it just defined. One could argue that you could do: foreach my $each, ... And that parameters passing variables with 'my' prefixed get lexically scoped at the caller, and so the subroutine would be within it. But that's not really consistent, and is actually confusing. It also begs the question, how does $_ get scoped? > sub uvula($cond,$body) is macro { > while($cond.()) { > $body.(); > } > } > uvula cond => sub{$_ = $fh.getlines() }, body => sub{ print; }; Ugliness aside, it's only advantage is that it could inline the contents of the macro sub, and that could be better done with simple inlined functions, and don't require the complexity of macros. Macros are better suited to things that *cannot* be done with functions. Stealing from "On Lisp", macros have the following advantages (pages 107-109 to be precise): - Transformation: they can look inside the structure of their arguments. pow($a,$b) can be optimized if the second argument is constant. This can be done with a macro which checks whether the second parameter to it is an expression, or a constant, and perform the appropriate logic. - Binding: I've already explained this one to death. "Any operator which is to alter the lexical bindings of its arguments must be written as a macro." - Conditional evaluation: how would you write 'if' or 'and' using functions? - Multiple evaluation: this can be emulated by receiving coderefs, and calling them multiple times. But it requires the caller format them *as* a coderef. - Using the calling environment: I believe Damian likes this one for Exporter, and flexibility, and Dan doesn't for optimization reasons. Macros give the BOBW. - Saving function calls: A minor one, which can be emulated with inlined functions > If labels are lexically scoped, There's no problem here. Of course, you > need to "promote" all labels to the beginning of the enclosing block, > but that's compiler magic, and doesn't violate lexical scoping. If they're lexically scoped, yes. But this doesn't solve all the problems. For example, what if, in this macro, I pass the 'jumpto' label to another macro I'm calling. There's no guarantee that the inner macro, when it uses the label I passed it, will work, since it could accidentally re-scope the macro name itself for its own purposes. Thus, the problems with variable capture, and the reasons for gensym. Since macros are using a function-similar syntax, and functions are necessarily prefix-based, it means macros are unable to express curtain Perl constructs. For example 'A if B' type syntax is difficult to implement with macros, which requires the macro name be seen before it can process the code as a macro. Unless macros get further perlized in some manner in some way. I feel like this is a two-person debate, and the volume of text is going to alienate other contributors. So I'll shut up on this topic, and wait to see what Larry/Damian thinks of the 'good'ness of the idea before I try and flesh out more ideas on the implementation. Mike Lambert