HaloO,

Ingo Blechschmidt wrote:
Exactly. I'd like to add that, under the proposal, you always know what
things are passed how, only by looking for a "*".

    foo $var;    # always positionally, even if $var isa Pair
    foo *$pair;  # always named

But where is the name? Is it 'pair'? Like in

      foo :pair($pair);

or dynamically through

      foo $pair.key => $pair.value;

assuming that precedence of => is tighter than foo's. As I lengthyly ranted
elsewhere in this thread the splat should just defer the structural
callability check until runtime. Well, and since everybody seems to be
happy with .$pair denoting a call through a hardref stored in $pair, I
don't understand why :$pair is not (yet) denoting a hard pairref. Both forms
beeing interpreted in the context of the term to their *immediate* left
which in turn is interpreted leftwards. And both forms fail if the
assumptions about the type of value $pair will eventually refer to
won't hold. The difference to the splat form is eagerness:

  foo :$pair; # eager
  foo *$pair; # lazy

and op versus sigil

  foo  :  $pair;  # syntax error like $ pair
  foo (:  $pair); # same
  foo:    $pair;  # labeled statement

  foo  *  $pair;  # infix
  foo (*  $pair); # prefix
 (foo  *) $pair;  # postfix, which I guess doesn't exist


If full uncertainty isn't your thing, you might instruct the type system
to make sure that $pair at least doesn't fail you on pairhood

  my Pair $pair;

  foo  $pair; # syntactically an item, thus a positional call
  foo *$pair; # guarranteed pair after splatting

But of course the call could still fail because there is no parameter
under the key of $pair. Now I think you could instruct the kind type
system also to oversee the meeting of this constraint with

  my Pair of foo $pair;

  foo  $pair; # you guessed it, positional call
  foo *$pair; # always delivers $pair.value into $pair.key
              # parameter of foo

Which might be a too sophisticated variable for your purposes if it
also oversees the values to put into $pair depending on the current
key. This might reduce usability of $pair while you are not calling
foo with it. Thus an intermediate choice could be

  my Pair where .key of foo $pair;
# my $pair is Pair where .key of foo; # same
# my Key of foo $pair; # abbreviation of same?

  foo *$pair; # name hits home, but type error is possible

If you know that all named params of foo are integers you could
oblige yourself to adhere to this with

  my $pair is Pair of Int where .key of foo;

And yes, I know that this should be written

  my $pair is Pair of Int where { .key of foo };

where the ; might be optional. Is it?


The unsigiled foo there is actually shying away from full dynamism:

  &foo *$bar;

This is almost meaningless in itself because it states: "Try to do
what &foo tells you to do with whatever you find in $bar when you try
to do so." But the code that the compiler generates is actually quite
short! E.g. a single call instruction if &foo and $bar are already in
VM registers. Only the outcome is uncertain ;)


    foo [EMAIL PROTECTED];  # always positionally

This makes perfect sense to me if you mean that the positionals
that foo requests are satisfied in the order provided by @array
without exceptions for pairs, not to mention subtypes of pairs
or things that do the Pair role etc.


    foo *%hash;   # always named (hash keys taken as parameter names)

So that shall fail at compile time if foo has *anonymous* positionals?
E.g. a sig ($,$,$) or would there be a desparate attempt to call it as

      foo %hash<0>, %hash<1>, %hash<2>;

or aiming at whatever .[Int] means on a hash:

      foo %hash[0], %hash[1], %hash[2];

BTW, I would write a keyed sig as &foo:(:x,:y,:z).


Previously, you wasn't able to know whether you passed something
positionally or by name:

    sub bar ($x) { grtz $x }
    bar 42;       # 42 passed to &grtz positionally
    bar a => 42;  # either the pair (a => 42) passed to &grtz
                  # positionally or the number 42 passed by name

Under the new proposal, "grtz $x" always passes $x positionally. You
don't need &grtz's signature, nor do you need to know $x's type (is $x
a Pair?).

Yep. But you could attempt to dispatch .key on $x in grtz:

   sub grtz ($item)
   {
      say $x.key;
   }

and get a printout of 'Undef of Key' or so and 'a' respectively.
HiHi, or a 'method not understood' exception if .key is not applicable
to 42 ;)


Compare this with the old semantics:

  grtz $x;
  # $x is not a Pair? ==> $x passed positionally
  # else ==>
  #   &grtz expects a Pair as its first positional parameter?
  #     ==> $x passed positionally
  #   else ==>
  #     &grtz's signature lists a parameter named $x.key?
  #        ==> $x.value passed by name
  #     else
  #       ==> $x passed positionally


Stuart Cook wrote:
And look, if you really wanted to, you could define your own
splat-style operator that works exactly as you describe.  But I don't
think it should be the default.

I think that is difficult *without* parser support because
a purely prefix thingy doesn't get the coderef the flattened
array goes to. Well, and it can't be infix either because it
first of all conflicts with numeric multiplication and would
require the coderef beeing non-bare syntactically.

  foo * @array;  # multiply retval of foo with arity of @array or so

  &foo * @array; # &infix:<*>:(Code,Array)(&foo,@array);

BTW, I parse the construct in the last comment as

  1) there is a &infix code multitude
  2) constrain that to the ones with identifier '*'
  3) further constrain it to the ones that take a Code and an Array
  4) then dispatch on the actual types of &foo and @array

In a certain way I would hope that

  &foo &infix @array, :<*> :(Code,Array); # note the comma!

and

  &foo &infix :<*> :(Code,Array) @array; # note: no comma

mean the same. Well and it should be writeable with fat comma, too

  &foo ((Code,Array) => (* => &infix)) @array;


Right. Under the proposal, you can -- *if you want to* -- use pairs
stuffed in arrays as named arguments:

    foo *hash(@array_of_pairs);
      # @array_of_pairs's pairs used as named args

This hash function there is hardly the same as the one from S06, that
takes every other pair from @array_of_pairs, converts *the pair*
to a key---which might preserve the key actually---and combines it
with the next entry from the array as value?

  @AoP = (a => 'a', b => 'b', c => 'c', d => 'd');
  %hash = hash @AoP;
  #     = (AoP[0] => AoP[1], AoP[2] => AoP[3]);
  #     = (     a => 'b'   ,      c => 'd'   );

  +%hash == 2; # true?

  foo *%hash; # foo( a => 'b', c => 'd')

    foo [EMAIL PROTECTED];
      # @array_of_pairs's pairs used positionally

But if we made [EMAIL PROTECTED] mean that...

* [EMAIL PROTECTED]'s pairs are always taken as named arguments,
  there wouldn't be a simple way to pass pairs positionally.

* [EMAIL PROTECTED]'s pairs are always taken as pairs,
  there wouldn't be a simple way to use the pairs as named arguments.

I might not sure that I get your idea correctly but haven't you shifted
the magical pair filtering into your hash function? And the syntax
you've picked is also counter-intuitive at least to my arguably strange
intuition. That is, foo should be an argument to the pair filter:

   # sub, multi form
   pair_filter_call( &foo, @array_of_pairs );

   # listop form
   pair_filter_call &foo, @array_of_pairs;

   # named arg forms
   pair_filter_call code => &foo, data => @array_of_pairs;
   pair_filter_call:code(&foo):data(@array_of_pairs);

   # method forms
   &foo.pair_filter_call( @array_of_pairs );
   @array_of_pairs.pair_filter_call( &foo );
   ( &foo, @array_of_pairs ).pair_filter_call;

Since *% as an operator name isn't taken you could

   &infix:<*%> ::= &pair_filter_call;

and get

   &foo *% @array;


* [EMAIL PROTECTED]'s pairs are taken as pairs or named arguments,
  depending on the called subroutine (does it accept named params?
  Do some parameters specifically want a Pair? etc.), we'd introduce
  non-local non-determinism to a quite important part of the language.

It is *NOT* non-determinism! It is under-constraint behaviour.
But that is considered a feature by the Perl 6 community, isn't it?
Given the exact same &foo and @array_of_pairs a call

  foo [EMAIL PROTECTED];

in a fixed environment should give the same result---always.

After all you have to know something about foo's signature to call
it relieably! Late binding is cool, but some expect the arguments
to parameters binding to be performed before the program stops running.
But lazyness ultimately means binding args in the time after a successfull
run of a particular invocation of the program. And prefix:<*> is the
lazyness operator if I remember correctly :)
--
$TSa.greeting := "HaloO"; # mind the echo!

Reply via email to