Re: Best way of implementing "Walkmeth" in Moose

2010-05-09 Thread Daniel Pittman
Shlomi Fish  writes:
> On Wednesday 28 Apr 2010 08:04:31 Daniel Pittman wrote:
>> Shlomi Fish  writes:
>> > On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote:
>> >> On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote:

Sorry for taking so very long to respond to this.

[...]

>> > OK, thanks. I might create a small MooseX::AccumArray distro out of it.
>> 
>> If you do get around to looking at this, I have a couple of times played
>> with the idea of either hacking on Class::MOP[1], or writing an extension,
>> to do some more of the method combination bits that CLOS used to do.
>> 
>> Specifically, I have run across the need for:
>> 
>> 'and' and 'or' method combination[2], both with most-specific-first and
>> least-specific-first ordering — various validations like ACL-style
>> authorisation, and data validation, benefit from those.
>> 
>> The "accumulate to array" method combination you mention is also quite
>> useful, but a bit obvious right now.
>> 
>> CLOS also had min, max, and plus method combinations, for which I can see
>> some logic exposing in Moose also — and probably some of the "...write
>> your own" too.
>
> OK, now we're talking about generalising the walkmeth functionality of what
> I need. I didn't get so far into studying CLOS (I studied CL mostly from the
> book "Practical Common Lisp"), or forgot it, but I think I know what you
> mean.  Everything you describe is a sub-case of "reduce" like the one in
> List::Util, although the concept predates List::Util and Perl itself by a
> long time:

Mmmm, more or less, in the same way that the standard method combination that
Moose supports is also a sub-case of "reduce": they all take a list of
applicable methods, then apply them in a specific order, and do something to
the result.

The standard method combination is more or less the "around" or "extend" case,
where an explicit action is taken to go on to the next; the others do more
complicated things, but mostly the same.

> Now, the problem with such a reduce is that it has to know to short-circuit
> in case it's a cumulative (and...) or (or...) operation.

*nod*  The usual implementation would be something like this for the
slow-path:

sub and_method_combination {
my (@all_applicable_methods) = @_;
sub {
my ($self, @args) = @_;
for my $method (@all_applicable_methods) {
my $result = $self->$method(@args);
return $result if $result;
}
return;
}
}

That contrasts to the "standard" method combination, which calls the most
specific method, and then makes arrangements so that can call the
next-most-specific-method if it wants.

Those are, in Moose, the 'inner/augment' and 'super/override' sugar, which
wrap around the standard inheritance stuff.

(CLOS unifies them: you specify "most-specific-first" or
 "least-specific-first" in the method combination, and it then arranges for a
 generic 'call-next-method' to do what 'inner' or 'super' do in Moose.)

> And then we need to decide whether we code one distinct accumulating
> meta-method for every such operation (as accum_array, accum_and, accum_or,
> accum_min, accum_max, accum_sum, etc.) or that we implement a generic reduce
> and then implement each specific accumulator based on it (which may result
> in slower code.).

I would hope this could be part of Class::MOP, so that you can have a nice
protocol for generating "slow" path code, which is probably dynamically
generated subroutines walking arrays, and "fast" path code, which dynamically
install the appropriate methods.

This is, incidentally, roughly what the method wrapping code used for method
modifiers do — except that they don't wrap anything until you add a modifier.

> And naturally I now remember that "perfect is the enemy of good", and that
> there's a saying in Hebrew that "caught a lot - did not catch
> anything.". Oh!  Decisions, decisions.

*nod*
Daniel

-- 
✣ Daniel Pittman✉ dan...@rimspace.net☎ +61 401 155 707
   ♽ made with 100 percent post-consumer electrons



Re: Best way of implementing "Walkmeth" in Moose

2010-04-30 Thread Shlomi Fish
On Wednesday 28 Apr 2010 08:04:31 Daniel Pittman wrote:
> Shlomi Fish  writes:
> > On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote:
> >> On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote:
> >> > After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have
> >> > accumulated several questions about Moose, so I'd post each one in a
> >> > separate post to keep each thread single-topic. (I hope it's OK.)
> >> > 
> >> > The first one is how to implement a Class::Std/Perl 6-like walkmeth:
> >> > 
> >> > *
> >> > http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=2007070
> >> > 1
> >> > 
> >> > * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE).
> > 
> > [SNIP]
> > 
> >> > My question is: is there a better way to do it using Moose? (Or one of
> >> > the MooseX modules?) Instead, should I implement my own private logic
> >> > or create a new MooseX module?
> >> 
> >> No, that is pretty much how you would do it. Take a look at
> >> Moose::Object::BUILDALL, it does the same thing.
> > 
> > OK, thanks. I might create a small MooseX::AccumArray distro out of it.
> 
> If you do get around to looking at this, I have a couple of times played
> with the idea of either hacking on Class::MOP[1], or writing an extension,
> to do some more of the method combination bits that CLOS used to do.
> 
> Specifically, I have run across the need for:
> 
> 'and' and 'or' method combination[2], both with most-specific-first and
> least-specific-first ordering — various validations like ACL-style
> authorisation, and data validation, benefit from those.
> 
> The "accumulate to array" method combination you mention is also quite
> useful, but a bit obvious right now.
> 
> 
> CLOS also had min, max, and plus method combinations, for which I can see
> some logic exposing in Moose also — and probably some of the "...write
> your own" too.

OK, now we're talking about generalising the walkmeth functionality of what I 
need. I didn't get so far into studying CLOS (I studied CL mostly from the 
book "Practical Common Lisp"), or forgot it, but I think I know what you mean. 
Everything you describe is a sub-case of "reduce" like the one in List::Util, 
although the concept predates List::Util and Perl itself by a long time:

http://search.cpan.org/perldoc?List::Util

Now, the problem with such a reduce is that it has to know to short-circuit in 
case it's a cumulative (and...) or (or...) operation. And then we need to 
decide whether we code one distinct accumulating meta-method for every such 
operation (as accum_array, accum_and, accum_or, accum_min, accum_max, 
accum_sum, etc.) or that we implement a generic reduce and then implement each 
specific accumulator based on it (which may result in slower code.).

And naturally I now remember that "perfect is the enemy of good", and that 
there's a saying in Hebrew that "caught a lot - did not catch anything.". Oh! 
Decisions, decisions.

Regards,

Shlomi Fish

> Daniel
> 
> 
> Footnotes:
> [1]  This embeds the "standard" method combination inside
>  Class::MOP::Method::Wrapped as a private method internally; it doesn't
>  look terribly hard to extend to either use external method combination
>  classes, or to support non-standard (eg: not before, after, around)
>  decorators ... which makes me think I have missed something in my
>  look-but-not-touch investigation so far.
> 
> [2]  I suspect that Perl users would like a "and-true" and "and-defined"
>  variant of both of these, that short-circuit when the value is false
> and undefined respectively, where CLOS users didn't.

-- 
-
Shlomi Fish   http://www.shlomifish.org/
http://www.shlomifish.org/humour/ways_to_do_it.html

God considered inflicting XSLT as the tenth plague of Egypt, but then
decided against it because he thought it would be too evil.

Please reply to list if it's a mailing list post - http://shlom.in/reply .


Re: Best way of implementing "Walkmeth" in Moose

2010-04-27 Thread Daniel Pittman
Shlomi Fish  writes:
> On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote:
>> On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote:
>> >
>> > After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have
>> > accumulated several questions about Moose, so I'd post each one in a
>> > separate post to keep each thread single-topic. (I hope it's OK.)
>> > 
>> > The first one is how to implement a Class::Std/Perl 6-like walkmeth:
>> > 
>> > * http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701
>> > 
>> > * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE).
>> > 
> [SNIP]
>> > My question is: is there a better way to do it using Moose? (Or one of
>> > the MooseX modules?) Instead, should I implement my own private logic or
>> > create a new MooseX module?
>> 
>> No, that is pretty much how you would do it. Take a look at
>> Moose::Object::BUILDALL, it does the same thing.
>
> OK, thanks. I might create a small MooseX::AccumArray distro out of it.

If you do get around to looking at this, I have a couple of times played with
the idea of either hacking on Class::MOP[1], or writing an extension, to do some
more of the method combination bits that CLOS used to do.

Specifically, I have run across the need for:

'and' and 'or' method combination[2], both with most-specific-first and
least-specific-first ordering — various validations like ACL-style
authorisation, and data validation, benefit from those.

The "accumulate to array" method combination you mention is also quite useful,
but a bit obvious right now.


CLOS also had min, max, and plus method combinations, for which I can see some
logic exposing in Moose also — and probably some of the "...write your own"
too.
Daniel


Footnotes: 
[1]  This embeds the "standard" method combination inside
 Class::MOP::Method::Wrapped as a private method internally; it doesn't
 look terribly hard to extend to either use external method combination
 classes, or to support non-standard (eg: not before, after, around)
 decorators ... which makes me think I have missed something in my
 look-but-not-touch investigation so far.

[2]  I suspect that Perl users would like a "and-true" and "and-defined"
 variant of both of these, that short-circuit when the value is false and
 undefined respectively, where CLOS users didn't.

-- 
✣ Daniel Pittman✉ dan...@rimspace.net☎ +61 401 155 707
   ♽ made with 100 percent post-consumer electrons



Re: Best way of implementing "Walkmeth" in Moose

2010-04-27 Thread Shlomi Fish
On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote:
> On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote:
> > Hi all!
> > 
> > After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have
> > accumulated several questions about Moose, so I'd post each one in a
> > separate
> > post to keep each thread single-topic. (I hope it's OK.)
> > 
> > The first one is how to implement a Class::Std/Perl 6-like walkmeth:
> > 
> > * http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701
> > 
> > * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE).
> > 
[SNIP]
> > My question is: is there a better way to do it using Moose? (Or one
> > of the
> > MooseX modules?) Instead, should I implement my own private logic or
> > create a
> > new MooseX module?
> 
> No, that is pretty much how you would do it. Take a look at
> Moose::Object::BUILDALL, it does the same thing.

OK, thanks. I might create a small MooseX::AccumArray distro out of it.

Regards,

Shlomi Fish

-- 
-
Shlomi Fish   http://www.shlomifish.org/
Parody on "The Fountainhead" - http://shlom.in/towtf

God considered inflicting XSLT as the tenth plague of Egypt, but then
decided against it because he thought it would be too evil.

Please reply to list if it's a mailing list post - http://shlom.in/reply .


Re: Best way of implementing "Walkmeth" in Moose

2010-04-27 Thread Stevan Little


On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote:

Hi all!

After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have
accumulated several questions about Moose, so I'd post each one in a  
separate

post to keep each thread single-topic. (I hope it's OK.)

The first one is how to implement a Class::Std/Perl 6-like walkmeth:

* http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701

* http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE).

What it does is that in each class out of the various inheritance  
tree of the

module, there is a method, and one accumulates their results so if:

[pseudo-code]
package Base1;

sub a1
{
return [qw(foo)];
}

package Base2;

sub a1
{
return [qw(bar)];
}

package Class;

extends('Base1', 'Base2');

sub a1
{
return [qw(quux)];
}
[/p-code]

Then accumulating a1 will yield [qw(foo bar quux)].

I've implemented something similar in Test-Run:

http://svn.berlios.de/svnroot/repos/web-cpan/Test-Harness-
NG/trunk/modules/Test-Run/lib/Test/Run/Base.pm

(short URL - http://xrl.us/bhjhgt ).

Quoting from it:

[code]
sub accum_array
{
   my ($self, $args) = @_;

   my $method_name = $args->{method};

   # my $class = ((ref($self) eq "") ? $self : ref($self));

   my @results;
   foreach my $isa_class (
   $self->meta->find_all_methods_by_name($method_name)
   )
   {
   my $body = $isa_class->{code}->body();
   push @results, @{ $self->$body() };
   }

   return \...@results;
}
[/code]

My question is: is there a better way to do it using Moose? (Or one  
of the
MooseX modules?) Instead, should I implement my own private logic or  
create a

new MooseX module?


No, that is pretty much how you would do it. Take a look at  
Moose::Object::BUILDALL, it does the same thing.


- Stevan






Best way of implementing "Walkmeth" in Moose

2010-04-27 Thread Shlomi Fish
Hi all!

After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have 
accumulated several questions about Moose, so I'd post each one in a separate 
post to keep each thread single-topic. (I hope it's OK.)

The first one is how to implement a Class::Std/Perl 6-like walkmeth:

* http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701

* http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE).

What it does is that in each class out of the various inheritance tree of the 
module, there is a method, and one accumulates their results so if:

[pseudo-code]
package Base1;

sub a1
{
return [qw(foo)];
}

package Base2;

sub a1
{
return [qw(bar)];
}

package Class;

extends('Base1', 'Base2');

sub a1
{
return [qw(quux)];
}
[/p-code]

Then accumulating a1 will yield [qw(foo bar quux)].

I've implemented something similar in Test-Run:

http://svn.berlios.de/svnroot/repos/web-cpan/Test-Harness-
NG/trunk/modules/Test-Run/lib/Test/Run/Base.pm

(short URL - http://xrl.us/bhjhgt ).

Quoting from it:

[code]
sub accum_array
{
my ($self, $args) = @_;

my $method_name = $args->{method};

# my $class = ((ref($self) eq "") ? $self : ref($self));   

my @results;
foreach my $isa_class (
$self->meta->find_all_methods_by_name($method_name)
)
{
my $body = $isa_class->{code}->body();
push @results, @{ $self->$body() };
}

return \...@results;
}
[/code]

My question is: is there a better way to do it using Moose? (Or one of the 
MooseX modules?) Instead, should I implement my own private logic or create a 
new MooseX module?

Regards,

Shlomi Fish

-- 
-
Shlomi Fish   http://www.shlomifish.org/
http://www.shlomifish.org/humour/ways_to_do_it.html

God considered inflicting XSLT as the tenth plague of Egypt, but then
decided against it because he thought it would be too evil.

Please reply to list if it's a mailing list post - http://shlom.in/reply .