Dan Sugalski <[EMAIL PROTECTED]> wrote:
I'm drawing the distinction between an operation on the container and an operation on all the container's contents here. I think it's the right distinction.
Sure. But the prefix C<hyper> just is the distinction. PerlArray's add, add_int, bitwise whatever vtable slots are all unused. There isn't any usage for these except throwing an exception or being overloaded as an C<hyper> operation.
Although, I would think that "@ary += 1" would extend the length of the array by one. That is, I can think of logical uses for the currently-unimplemented arithmetic ops on PerlArray.
The C<hyper> prefix could look at the vtable and if it's overloaded just
call it. If it's not overloaded a loop like that in my proof of concepts
is run which (for PMCs) calls the aggregates member's vtable.
So are you saying, have separate vtable slots for the hyper operations, but then you only have to fill in the vtable->hyper_add() slot _if_ you want it to do something other than applying vtable->add() in a loop (otherwise, do what your proof-of-concept did)? If so, that makes a lot of sense to me.
On the other hand, from what's been said it sounds like Perl6 may not intend to allow you to override a hyper op independently. If so, we don't need the separate slots, it seems, but we do need a vtable->hyper() which somehow takes an op as a parameter, since only the PMC itself know how to get at its "logical contents" as a container.
....time passes....
The more I think about it, the more it doesn't make sense to me to allow >>+<< to be overridden independently of +. Conceptually (in general, and based on what Luke says), this:
@a »+« 1;
doesn't read as "apply hyper-add to...", but rather as "hyper-apply 'add' to...". That is, if the syntax had been something like:
array.appleToEachElement(&add, 1); or array.appleToEachElement(+, 1);
then there wouldn't be any temptation to think of >>+<< as a separate operator.
FWIW, there's an ObjC add-on framework which defines an "each" method, to allow you to do things such as:
[[array each] increment];
to increment each element of an array, rather than the "default" way, which would be:
[array makeObjectsPerformSelector:@selector(increment)];
Just mentioning this, because it brings up the idea of doing something like:
new P0, .PerlArray # fill it.... hyper P1, P0 # P1 is now a wrapper object, which holds a reference to P0 add P1, 1 # applying an op to the wrapper really hyper-applies it to P0
That is, have a "hyper-wrapper" PMC, which knows how to hyper-apply any op to the PMC it's wrapping.
This would let us avoid a bytecode syntax in which either an op modifies the meaning of an op later in the stream, or an op needs to take another op as a parameter. This hyper-wrapper PMC would then be the only thing which needs to know about hyper-ness (I think), including encapsulating the knowledge about what to do when applying ops to containers of unequal length (since some ops might treat this as extending the shorter one with 1's, other ops may fill with 0's, etc.).
It would also avoid adding any vtable operations, or any ops. (The "hyper" op I used above could be replaced by a simple "new" + "set" sequence.)
Hmm, I'm actually liking the idea of that approach.
JEff