TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote:
Now my question: could slice context be a runtime feature that acts
before the dispatch to &postcircumfix:<[ ]> by retrieving the shape
of the @array and handing it over to &foo as context, capture the
shape of the slice returned and hand over the remaining shape as
context to &bar? Since relying on the order of &foo and &bar in the
source is bad, an even more elaborate scheme can be used that queries
&foo and &bar before the actual call which slots they intend to fill
in the pending slice operation.
The plot thickens!
Consider the user-defined index translation functions, or the
differential indexing feature. Both use * inside the subscript.
If you have
the * has to know to map to a function to retrieve the length of the
proper dimension. If it can't count semicolons at compile-time, it
can't rely on parser magic and it has to call a function at run time.
Forget the funny syntax, and what we're really looking at is:
@array[ $a ; dimlen() - 2 ; $c ]
Even if you want to be charitable and say the parser actually expanded
the * to
(without re-evaluating the expression if the array is not a simple
variable name), then it still doesn't know what position it is in.
Just off the cuff, I think it might use the array target and index
position as context variables, or to save the overhead of always setting
those, another magic syntax inside the subscript could be used to
indicate its own position. So, the * expands to:
dimlen (@array, $?SLICEPOS)
and this makes it clear how to call your own functions thusly. So you
@array[ @@(foo(42)) ; bar(@?SLICETARGET, $?SLICEPOS) ; $baz ]
and it would supply the proper value after knowing how many dimensions
were returned from foo in slice context. The use of @?SLICETARGET
allows you to refer to the @array even if it is the result of an
expression, without re-evaluating it, or worse if it is a return value
or temporary object. It would be handy to have when writing a macro.
Hopefully, the grammar for implementing * in subscripts is clean enough
that you could write a macro that did something similar for your own
construct. There should be no magic that is not available to the
programmer as well.