Re: MethodMaker techniques in Perl 6

2004-04-26 Thread Jonathan Scott Duff
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

2004-04-25 Thread John Siracusa
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

2004-04-25 Thread Abhijit A. Mahabal

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

2004-04-25 Thread Dave Whipp

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

2004-04-25 Thread Abhijit A. Mahabal

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

2004-04-25 Thread Dave Whipp
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.