Ken Fox asked:

    sub part ($classifier, *@list) {
....

        return @parts;
    }

Given the original example

  (@foo,@bar,@zap) := part [ /foo/, /bar/, /zap/ ] @source;

this binds the contents of @parts to (@foo,@bar,@zap)?
Yes.


The array refs in @parts are not flattened though.
Correct. Each array ref is bound to the corresponding array name.

>
Is it correct
to think of flattening context as a lexical flattening? i.e.
only terms written with @ are flattened and the types of
the terms can be ignored?
I'm not sure I understand this question.


BTW, if part were declared as an array method, the syntax
becomes

  @source.part [ /foo/, /bar/, /zap/ ]
Nearly. The parens are not optional on this form of method call, I believe.
So that would be:

    @source.part([ /foo/, /bar/, /zap/ ]);

or

  part @source: [ /foo/, /bar/, /zap/ ]
Yes.


Can part be a multi-method defined in the array class
Multimethods don't belong to any particular class.
Does it *need* to be a method or multimethod???



                for @classifiers.kv -> $index, &test {
An array::kv method? Very useful for sparse arrays, but
is this preferred for all arrays? An explicit index counter
seems simpler in this case.
Depends on your definition of simpler, I guess. Depending on what you mean by
"explicit index counter", that would have to be:

	for [EMAIL PROTECTED] ¦ @classifiers -> $index, &test {
	    ...
	}

Or (heaven forefend!):

	loop (my $index=0; $index<@classifiers; $index++) {
	    my &test := @classifiers[$index];
	    ...
	}

I really think an C<Array::kv> method nicely meets the very common need of
iterating the indices and values of an array in parallel, with a minimum
of syntax and a maximum of maintainability.



my @indices = map { defined .key()($nextval) ?? .value :: () } %classifiers;

That map body looks like a syntax error,  but it isn't.
> Can I add extra syntax like
  map { defined(.key.($nextval)) ?? .value :: () }

to emphasize the fact that .key is returning a code ref?
Yes, indeed.


Last, but not least, the Hash case returns a junction (most
likely of a single value). Junctions don't collapse like
superpositions, so I'm wondering what really happens.

Can you describe the evaluation?
Sure. Suppose that the classifier closure returns the junction C<any(1)>.
Then, within C<part>, the C<$index> variable stores that junction (i.e. junctions
survive both a copy-on-return and an assignment). The next statement is:

	push @parts[$index], $nextval;

The use of a junction as an index causes the array look-up to return a junction
of aliases to the array elements selected by the various states of the index.
So C<@parts[$index]> is a disjunction of a single alias (i.e. to C<@parts[1]>).
Pushing the next value onto that alias causes it to autovivify as an array ref
(if necessary), and then push onto that nested array.

Suppose instead that the classifier closure returns the junction C<any(0,1)>.
Then, within C<part>, the C<$index> variable stores that junction, and its use
as an index causes the array look-up to return a junction
of aliases to the array elements selected by the two states of the index.
So C<@parts[$index]> is, in this second case, a disjunction of two aliases
(i.e. to C<@parts[0]> and C<@parts[1]>). Pushing the next value onto that
disjunctive alias causes it to autovivify both elements as array refs
(if necessary), and then -- in parallel -- push the value onto each nested array.

I'm really interested in how
long the junction lasts (how quickly it turns into an integer
index),
It never turns into an integer index. Using a junction as an index is the
same as passing it to the C<Array::operator:[]> method, which causes the
call to the method to be distributed over each state in the junction. So, just
as:

	foo(1|2|3)

is the same as:

	foo(1) | foo(2) | foo(3)

so:

	@array[1|2|3]

is the same as:

	@array[1] | @array[2] | @array[3]

And:

	@array[1|2|3] = "str";

is the same as:

	(@array[1] | @array[2] | @array[3]) = "str"

which the same as:

	(@array[1] = "str") | (@array[2] = "str") | (@array[3]) = "str")


 and what happens with a duplicate (ambiguous?) index.

Can't happen. As Luke has expounded, junctions are a form of set,
and have no duplicate states.



Perhaps the part method can be implemented as a mix-in module that
extends array without subclassing it?
And I'm suggesting that C<part>ing is such sweet sorrow that everyone
will want to do it all the time. Or at least often enough that dragging
it in from a module with rapidly become a PITA. Just as it in Perl 5
to use C<List::Utils::reduce> or C<List::Utils::max>.

Manipulating a core data type in commonly useful ways ought to be via
core operations (or, at worst, operations that are invisibly non-core),
so that JAPHs are encouraged to code what they mean explicitly:

	$sum = reduce {$^a+$^b} @nums;
	$max = max @nums;

rather than emergently:

	my ($max, $sum) = (-Inf, -Inf);
	for @nums {
	    $max = $_ if $max < $_;
	    $sum += $_;
	}


AUTOLOAD can do that now
for packages. Are classes sealed or will they use AUTOLOAD too?
There will certainly be a mechanism akin to AUTOLOAD in Perl 6.
How it will work has yet to be decided.

Damian

Reply via email to