Shlomi Fish <shlo...@iglu.org.il> writes:
> On Wednesday 28 Apr 2010 08:04:31 Daniel Pittman wrote:
>> Shlomi Fish <shlo...@iglu.org.il> 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

Reply via email to