On Sat, Oct 22, 2016 at 2:57 PM, Chris Marshall <devel.chm...@gmail.com> wrote:
> Hi Diab-
>
> I haven't done much with subclassing from PDL but
> I have noted some warts as in PDL::Complex.
>
> For the PDL::NextGen work I would like to have an
> approach that is interoperable with Moo[se] and
> possibly other OO frameworks.  One thought was to
> make PDL-ness a Role rather than a class as that
> seemed it might work better to factor out the PDL
> computations as a cross-cutting concern.
>
> Regarding the PDLx::DetachedOject approach, I'm a
> bit confused.  Is there a reason that the PDL attribute
> was not sufficient with an appropriate initialize()?

The problem is that initialize() can only provide default attribute
initialization and for some attributes, there is no default. In an
extreme example, let's say that MyPDL uses a database backing store,
and every MyPDL object needs a (possibly unique) db handle. There's no
logical default value for that, so initialize can't handle that case.

  $p1 = MyPDL->new( dbh => $db1 );
  $p2 = MyPDL->new( dbh => $db2 );
  $p3 = $p1 + $p2; # initialize( dbh => ??? )

There's no context to the initialize call. Now, in this case I can
overload the + operator when it's working on two MyPDL objects and
maybe MyPDL can come up in a solution, but that's not always the case
due to Perl's overload rules.  For example:

  $p1 = $mypdl + $pdl;
  $p2 = $pdl + $mypdl;

the first results in a MyPDL, the second in a PDL (see below)

> The example initialize doesn't appear to do any of the
> subclass initialization/construction at all.

Exactly.  It returns a plain PDL because otherwise it would return an
incomplete object.

> How do you handle the case of the results of a PDL operation on
> a MyPDL being a PDL and not a MyPDL?

Even when using initialize() as documented, it's not straightforward
to know what the resulting type of an operation is.  Here's some test
code:

#!/usr/bin/env perl

use 5.10.0;
use strictures 2;
use PDL;

{
    package MyPDL;
    use parent 'PDL';

    sub new { bless { PDL => $_[1]->copy }, $_[0] }
    sub initialize {
        say "called MyPDL::initialize";
        return bless { PDL => PDL->null }, 'MyPDL';
    }
}

my $pdl = sequence( 10 ) + 1;
my $mypdl = MyPDL->new( $pdl );

my $idx;
for my $code (
    '$pdl + $mypdl',
    '$mypdl + $pdl',
    'sqrt($mypdl)',
    '$mypdl + 2',
) {
    say "@{[++$idx]}: $code\n";
    my $p = eval $code;
    say 'result => ', ref $p, "\n";
    say "--------";

}

And the results:

1: $pdl + $mypdl

result => PDL

--------
2: $mypdl + $pdl

called MyPDL::initialize
result => MyPDL

--------
3: sqrt($mypdl)

called MyPDL::initialize
result => PDL

--------
4: $mypdl + 2

called MyPDL::initialize
result => MyPDL

--------

So the result depends upon the order of the operands, what a function
might return, etc. For a given expression, predicting what type the
outcome might be is too complicated.  MyPDL is already being
downgraded outside to a PDL outside of its control.  I'd rather it be
consistently downgraded.


> Without knowing the details of the MyPDL I can't
> really see what the problem with initialize() would
> be.

initialize() currently must assume that object construction can be
done without any arguments to the constructor.  That's inappropriate
in some instances (as described above).

>  However, sight unseen, maybe using a the PDL
> attribute as a code ref + closure might be a way to
> work around the difficulty?

This might work if initialize() were called more consistently.

>
> I definitely would like to see PDL and PDL::NextGen
> be interoperable with the Moo[se] universe as that
> would be a direction that could be applicable to
> perl6 as well.
>
> --Chris
>
> On 10/21/2016 17:37, Diab Jerius wrote:
>> I've been having lots of fun lately creating complex classes which
>> inherit from PDL. Unfortunately, when PDL creates objects on the fly,
>> e.g. when it needs to store the result of an operation:
>>
>>    $mpdl = MyPDL->new;
>>    $npdl = $mpdl + 1;  # $npdl will be of class MyPDL
>>
>> it can't pass along any additional parameters to the constructer.
>> This can cause a problem if the object's attributes cannot be given
>> default values, as the constructed object will be incomplete.
>>
>> For example, I've got some polymorphic code which handles MyPDL's
>> differently from PDLs.  In the above example, when passed $npdl it
>> thinks it's a MyPDL object, but required attributes aren't set, and
>> things explode.
>>
>> Things would be easier if $npdl were constructed as a plain piddle.
>> The actual code to do this isn't complicated, but it may not be
>> obvious how to apply it when using one of the class frameworks (such
>> as Moo, Class::Tiny, etc.), so I've whipped up a simple distribution,
>> PDLx::DetachedObject.
>>
>> For now it's just up at github & bitbucket:
>>
>> https://github.com/djerius/PDLx-DetachedObject
>>
>> https://bitbucket.org/djerius/pdlx-detachedobject
>>
>> The module includes a more detailed writeup of what's going on; I'd
>> appreciate comments and corrections!
>>
>> Thanks,
>> Diab
>>
>> ------------------------------------------------------------------------------
>> Check out the vibrant tech community on one of the world's most
>> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
>> _______________________________________________
>> pdl-devel mailing list
>> pdl-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/pdl-devel
>
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> pdl-devel mailing list
> pdl-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/pdl-devel

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
pdl-devel mailing list
pdl-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pdl-devel

Reply via email to