Re: MethodMaker techniques in Perl 6
On Sun, Apr 25, 2004 at 08:16:30PM -0700, Dave Whipp wrote: Abhijit A. Mahabal wrote: *{Foo::name1} = - $a { $a-{name1} }; If I read A12 correctly, this could be written as: Foo::$name1 := - $a {$a.name1}; Could be; that sounds somewhat right, but could you point out where in A12 because a search for := revelaed nothing relevant to me. Sorry, the assignment part came from A6 (and, rechecking, it seems to use ::= when assigning to a sub). It all depends on what you mean. := is run-time aliasing, ::= is compile-time aliasing. So, if it really were Foo::name1, then ::= would be fine, but if it were Foo::$name then it probably needs to be := (I'd guess that if perl knew what $name was by the time that it got to compiling Foo::$name, then ::= would work just fine) The ability to say pkg::$name came from A12. I'm fairly sure that you have to parenthesize interpolated things, so all of those above should look like this: Foo::($name) := - $a { $a.name1 }; See http://dev.perl.org/perl6/apocalypse/A12.html#Class_Name_Semantics (Or was there someplace that said simple scalars need not be parenthesized?) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
MethodMaker techniques in Perl 6
Based on the default accessors and encapsulation thread, it seems like a Perl 6 equivalent of Class::MethodMaker will be still be useful in our (or at least my) Brave New World. I've been pondering the best way to create such a beast in Perl 6. The most common two Perl 5 techniques are: 1. Use a string eval: build up a big string that looks the code for the method that I would have typed myself if I wasn't so lazy, then eval the string and assign the resulting code ref to the appropriate typeglob. Example: $attr = 'baz'; *{Foo::$attr} = eval qq(sub { \$_[0]-{'$attr'} }); This technique seems to have the best runtime performance in Perl 5 (by a small margin), but it's also much more expensive (not to mention tedious and persnickety) to create the method in the first place. For whatever reason, it's always just struck me as wrong (sort of like source filtering where code is just seen as a giant string--something that Perl 6 blessedly saves us from :) 2. Use a closure: build a method by assigning what would normally be constant values to a set of variables, then capturing their state in a closure. Example: $attr = 'baz'; *{Foo::$attr} = sub { $_[0]-{$attr} }; Making the method this way has always seemed cleaner to me, but it bothers me that $attr a full blown variable that has to be read from every time the method is run. Really, it should be a constant, which is probably why the string eval version has a speed edge at runtime. Obviously, simple get methods like the above wouldn't have to be written at all in Perl 6. Instead, I'd just use a public, read-only attribute (has $.baz) and be done with it. (As far as I can tell, the user of my class wouldn't be able to determine (or care) how $o.baz is implemented--whether as method baz() { ... } or as has $.baz. Correct me if I'm wrong :) Set methods, OTOH, will still have to be either written manually or auto-generated if, like me, you are not inclined to accept the contract implied by has $.foo is rw Perl 6 attributes. But beyond simple get/set methods, there's a whole world of increasingly more complex kinds of generic methods to be made. Just look at Perl 5's Class::MakeMethods::* for some examples. So finally, getting back to my original point, I'm wondering how best to create a good MethodMaker in Perl 6. The two Perl 5 techniques still seem like they will work (albeit with different syntax), but I'm sure there are better ways...perhaps something involving macros? The ideal solution has the strengths of both Perl 5 techniques, but none of their weaknesses. Creation should be fast and clean, and there should be no wasted overhead when calling the generated methods. It should be just as if I wrote the methods myself. I haven't retained enough Perl 6 syntax to have any idea what this would look like, so I'm looking for suggestions. Which Perl 6 features are best suited to creating a good Perl 6 MethodMaker? Anyone want to post some simple examples? -John
Re: MethodMaker techniques in Perl 6
On Sat, 24 Apr 2004, John Siracusa wrote: Based on the default accessors and encapsulation thread, it seems like a Perl 6 equivalent of Class::MethodMaker will be still be useful in our (or at least my) Brave New World. I've been pondering the best way to create such a beast in Perl 6. Yes, I agree. As you point out below, Class::Makemethods does lots of crazy stuff. Much of that (like pre- and post-hooks) will be easier to write in P6, but there is still lots of stuff that won't be in the core. The most common two Perl 5 techniques are: 1. Use a string eval: build up a big string that looks the code for the method that I would have typed myself if I wasn't so lazy, then eval the string and assign the resulting code ref to the appropriate typeglob. Example: $attr = 'baz'; *{Foo::$attr} = eval qq(sub { \$_[0]-{'$attr'} }); This technique seems to have the best runtime performance in Perl 5 (by a small margin), but it's also much more expensive (not to mention tedious and persnickety) to create the method in the first place. For whatever reason, it's always just struck me as wrong (sort of like source filtering where code is just seen as a giant string--something that Perl 6 blessedly saves us from :) 2. Use a closure: build a method by assigning what would normally be constant values to a set of variables, then capturing their state in a closure. Example: $attr = 'baz'; *{Foo::$attr} = sub { $_[0]-{$attr} }; Symbol tables and typeglobs and such belong to A10... and the * has been stolen... so I'll just speculate in pseudocode. Blocks-are-subroutines makes life easier, and in pseudocode that can be just: *{Foo::name1} = - $a { $a-{name1} }; OR: for @names - $name { my $private_scalar = $name; *{Foo::$name} = - $a {$a-{$private_scalar}}; } Making the method this way has always seemed cleaner to me, but it bothers me that $attr a full blown variable that has to be read from every time the method is run. Really, it should be a constant, which is probably why the string eval version has a speed edge at runtime. That is something the compiler may be able to deal with. I don't know much about compilers, but here is something from the camel book, 3rd ed, page 229 about inlining functions: BEGIN { my $prod = 1; for (1..10) { $prod *= $_; } sub NFACT () { $prod } } Here, NFACT is inlined because the compiler sees that $prod can never change. So maybe the $private_scalar above can also be inlined. (There is a new $private_scalar each time through the loop because of the my, and $name is also implicitly my). For that code I did not need to introduce $private_scalar, but I put it there to stand for more complex calculations if you need there. Maybe there should be a way to give hints to the compiler that inlining maybe possible. The two Perl 5 techniques still seem like they will work (albeit with different syntax), but I'm sure there are better ways...perhaps something involving macros? The ideal solution has the strengths of both Perl 5 techniques, but none of their weaknesses. Creation should be fast and clean, and there should be no wasted overhead when calling the generated methods. It should be just as if I wrote the methods myself. I haven't retained enough Perl 6 syntax to have any idea what this would look like, so I'm looking for suggestions. Which Perl 6 features are best suited to creating a good Perl 6 MethodMaker? Anyone want to post some simple examples? Wicked Traits come to mind. They seem to be all about warping class behaviors... role methodmaker{ method trait_auxillary:install( : Class $container, $method_semantics, [EMAIL PROTECTED]){ given $method_semantics { when semantics1 { for @names - $name { ... my $method = - $arg {...}; $container.install($name, $method); } for @names - $name { my $method = $container.get_method($name); $method.i_wont_change___inline_variables_if_possible; } } } } } # And in our class: class Dog{ install some_semantics, bark howl whine; } Or perhaps you want to put the install in a BEGIN{} if you want to have the body of the class see these (especially their signatures). class Dog{ BEGIN{ install some_semantics, bark howl whine } } -John --abhijit
Re: MethodMaker techniques in Perl 6
Abhijit A. Mahabal [EMAIL PROTECTED] wrote: Symbol tables and typeglobs and such belong to A10... and the * has been stolen... so I'll just speculate in pseudocode. Blocks-are-subroutines makes life easier, and in pseudocode that can be just: *{Foo::name1} = - $a { $a-{name1} }; If I read A12 correctly, this could be written as: Foo::$name1 := - $a {$a.name1}; Dave.
Re: MethodMaker techniques in Perl 6
On Sun, 25 Apr 2004, Dave Whipp wrote: Abhijit A. Mahabal [EMAIL PROTECTED] wrote: Symbol tables and typeglobs and such belong to A10... and the * has been stolen... so I'll just speculate in pseudocode. Blocks-are-subroutines makes life easier, and in pseudocode that can be just: *{Foo::name1} = - $a { $a-{name1} }; If I read A12 correctly, this could be written as: Foo::$name1 := - $a {$a.name1}; Could be; that sounds somewhat right, but could you point out where in A12 because a search for := revelaed nothing relevant to me. In any case, I should have written that as: *{Foo::name1} = - $a { $a.name1 }; Oscillating between using P5 and P6 is occasionally frustrating, though working at a stretch in either is a pleasure... The issue for P6 is more complicated than in P5 because you cannot just assign to the typeglob: you will somehow have to take signatures in consideration while populating the symbol table. Dave. --abhijit
Re: MethodMaker techniques in Perl 6
Abhijit A. Mahabal wrote: *{Foo::name1} = - $a { $a-{name1} }; If I read A12 correctly, this could be written as: Foo::$name1 := - $a {$a.name1}; Could be; that sounds somewhat right, but could you point out where in A12 because a search for := revelaed nothing relevant to me. Sorry, the assignment part came from A6 (and, rechecking, it seems to use ::= when assigning to a sub). The ability to say pkg::$name came from A12.