FAQ
Perl 5's references are fine, but sometimes dereferencing them is not. We end
up switching between postfix and circumfix syntax to dereference structures.

   push @{ $x->{foo}->[0]->m }, $y;

Blech.

In 5.14, an experimental feature was added to avoid this in some contexts:

   push $x->{foo}->[0]->m , $y;

In other contexts, it (obviously) can't help:

   push @y, @{ $x->{foo}->[0]->m };

   subroutine( @{ $x->{foo}->[0]->m } )

We need that circumfix deref on the right hand side of the push to indicate we
want the arrayref contents, not the arrayref. In the subroutine call, there's
really no context for picking how or whether to dereference, so we have to do
it intentionally, and that means circumfix.

There have also been questions about the ambiguity of auto-deref. I think
the current situation is not great, but it could be better by restoring some of
the initial design of autoderef. When disambiguation is needed (because we
want "each @{ $x->{foo}->[0]->object_with_deref_overloads }"), though, we're
back to circumfix.

We can add postfix syntax for dereferencing to work in *all* places that we
might dereference, creating a construct that is clearly syntactically an array
(or hash, etc.) when needed.

   push $x->{foo}->[0]->m->@*, $y;

   push @y, $x->{foo}->[0]->m->@*;

   subroutine( $x->{foo}->[0]->m->@* )

   print $delivery->{email}->body_string_ref->$*;

If we want the two forms to be really of equivalent value, we'll also need to
be concerned with:

   print "Things: $aref_of_things->@*"

...which gets into less clearly-introduceable behavior.

Finally, do we need to enable postfix slices? I think that if we can, we
should. I think the syntax is free.

   say for $href->{aref}->@[ 0, 2, 4 ];

   say for $aref->[ $h_idx ]->@{ qw(foo bar baz) };

I think we have a few options for the specific tokens to put after that last
arrow. I think $* and @* and so on work well. Replacing the splat with a
colon has been suggested as well. The point here is to provide the feature.
It's not about reducing total punctuation. This is Perl, and we must embrace
our punctuation! It's about simplifying the reading of code by allowing it to
be read and written linearly.

--
rjbs

Search Discussions

  • Nicholas Clark at Jul 2, 2013 at 11:12 am

    On Wed, Jun 26, 2013 at 09:59:02PM -0400, Ricardo Signes wrote:
    We can add postfix syntax for dereferencing to work in *all* places that we
    might dereference, creating a construct that is clearly syntactically an array
    (or hash, etc.) when needed.

    push $x->{foo}->[0]->m->@*, $y;

    push @y, $x->{foo}->[0]->m->@*;

    subroutine( $x->{foo}->[0]->m->@* )

    print $delivery->{email}->body_string_ref->$*;
    I would be pleased to have a syntax that can be used anywhere that a
    circumfix can be used. It avoids learning/remembering a special case about
    where it works, and where it doesn't.

    I'm going to assume that the wording defining prototypes would need to be
    carefully re-written to find a clear terse way to say that

        sub foo(\@@);
        foo $x->{foo}->[0]->m->@*, $y;

    is considered to have an @ at the front of that first argument, so that
    the above code is legal.
    If we want the two forms to be really of equivalent value, we'll also need to
    be concerned with:

    print "Things: $aref_of_things->@*"

    ...which gets into less clearly-introduceable behavior.
    This is "less clear" because right now that parses as

    print 'Things: ' . $aref_of_things . '->@*'

    not as a syntax error? ie we're changing the meaning of something valid.
    Finally, do we need to enable postfix slices? I think that if we can, we
    should. I think the syntax is free.

    say for $href->{aref}->@[ 0, 2, 4 ];

    say for $aref->[ $h_idx ]->@{ qw(foo bar baz) };

    I think we have a few options for the specific tokens to put after that last
    arrow. I think $* and @* and so on work well. Replacing the splat with a
    colon has been suggested as well. The point here is to provide the feature.
    It's not about reducing total punctuation. This is Perl, and we must embrace
    our punctuation! It's about simplifying the reading of code by allowing it to
    be read and written linearly.
    Are there parsing ambiguities with a colon? Particularly, if a colon is
    expected because the opening '?' of a ternary has been seen, does this
    confuse things? Perl 6 initially doubled the symbols of '?' and ':' to enable
    ':' to be used in a lot more places. (and then changed '::' to '!!' I think
    to further reduce ambiguities)

    I'm not sure that ':' is equal to '*'. Whilst both are currently valid for
    a scalar splat syntax:

    $ perl -le '$a = bless []; *{""} = sub {warn "Hi!"}; print $a->$*'
    $* is no longer supported at -e line 1.
    Hi! at -e line 1.
    1
    $ perl -le '$a = bless []; *{" \n-"} = sub {warn "Hi!"}; print $a->$:'
    Hi! at -e line 1.
    1

    Existing code that uses $* warns. $: doesn't.

    Nicholas Clark
  • Ricardo Signes at Jul 2, 2013 at 12:34 pm
    * Nicholas Clark [2013-07-02T07:12:36]
    print "Things: $aref_of_things->@*"

    ...which gets into less clearly-introduceable behavior.
    This is "less clear" because right now that parses as

    print 'Things: ' . $aref_of_things . '->@*'

    not as a syntax error? ie we're changing the meaning of something valid. Correct.
    Are there parsing ambiguities with a colon? Particularly, if a colon is
    expected because the opening '?' of a ternary has been seen, does this
    confuse things?
    Colon was another suggestion that had been made, specifically $x->:@

    I don't believe it's likely to be ambiguous, because the -> can't dangle in
    front of a ternary's colon.

    --
    rjbs
  • Rafael Garcia-Suarez at Jul 2, 2013 at 11:41 am

    On 27 June 2013 03:59, Ricardo Signes wrote:
    We can add postfix syntax for dereferencing to work in *all* places that we
    might dereference, creating a construct that is clearly syntactically an array
    (or hash, etc.) when needed.

    push $x->{foo}->[0]->m->@*, $y;

    push @y, $x->{foo}->[0]->m->@*;

    subroutine( $x->{foo}->[0]->m->@* )

    print $delivery->{email}->body_string_ref->$*;

    Also $href->%* I suppose.
    Can we talk about failure modes a bit?
    A common idiom is to write @{ $foo || [] } in case $foo might be undefined.
    Do you remember the conditional-dereference operator that was
    bikeshedded to oblivion? ($foo?->bar() was one of the proposed
    syntaxes). Can we have this, plus ->@*, plus ?->@* that would expand
    to an empty list if its argument is undef?
    If we want the two forms to be really of equivalent value, we'll also need to
    be concerned with:

    print "Things: $aref_of_things->@*"

    ...which gets into less clearly-introduceable behavior.

    $foo and @foo are interpolated in strings, but not %foo. I suppose
    ->%* would not either? or maybe just exclude those constructs from
    interpolation whatsoever?
    Finally, do we need to enable postfix slices? I think that if we can, we
    should. I think the syntax is free.

    say for $href->{aref}->@[ 0, 2, 4 ];

    say for $aref->[ $h_idx ]->@{ qw(foo bar baz) };

    I think we have a few options for the specific tokens to put after that last
    arrow. I think $* and @* and so on work well. Replacing the splat with a
    colon has been suggested as well. The point here is to provide the feature.
    It's not about reducing total punctuation. This is Perl, and we must embrace
    our punctuation! It's about simplifying the reading of code by allowing it to
    be read and written linearly.

    --
    rjbs
  • Nicholas Clark at Jul 2, 2013 at 11:48 am

    On Tue, Jul 02, 2013 at 01:41:20PM +0200, Rafael Garcia-Suarez wrote:
    On 27 June 2013 03:59, Ricardo Signes wrote:
    Also $href->%* I suppose.
    Can we talk about failure modes a bit?
    A common idiom is to write @{ $foo || [] } in case $foo might be undefined.
    Do you remember the conditional-dereference operator that was
    bikeshedded to oblivion? ($foo?->bar() was one of the proposed
    syntaxes). Can we have this, plus ->@*, plus ?->@* that would expand
    to an empty list if its argument is undef?
    Ultimately it wasn't bikeshedded to oblivion.

    rjbs attempted to restart things, asking questions about how it was supposed
    to work, independent of its spelling, in certain unconsidered situations,
    such as LVALUE context.

    No-one answered.

    And that question is actually relevant. What would this do for undefined
    $foo?

         $foo->@* = @bar;
         @bar = $foo->@*;


    Presumably for what you're suggesting, in LVALUE context, $foo autovifies.
    In RVALUE context it does not (but does not error either)

    Nicholas Clark
  • Rafael Garcia-Suarez at Jul 2, 2013 at 12:00 pm

    On 2 July 2013 13:47, Nicholas Clark wrote:
    On Tue, Jul 02, 2013 at 01:41:20PM +0200, Rafael Garcia-Suarez wrote:
    On 27 June 2013 03:59, Ricardo Signes wrote:
    Also $href->%* I suppose.
    Can we talk about failure modes a bit?
    A common idiom is to write @{ $foo || [] } in case $foo might be undefined.
    Do you remember the conditional-dereference operator that was
    bikeshedded to oblivion? ($foo?->bar() was one of the proposed
    syntaxes). Can we have this, plus ->@*, plus ?->@* that would expand
    to an empty list if its argument is undef?
    Ultimately it wasn't bikeshedded to oblivion.

    rjbs attempted to restart things, asking questions about how it was supposed
    to work, independent of its spelling, in certain unconsidered situations,
    such as LVALUE context.
    Fair enough, I forgot about that episode. It was warnocked into oblivion then :)
    No-one answered.

    And that question is actually relevant. What would this do for undefined
    $foo?

    $foo->@* = @bar;
    @bar = $foo->@*;


    Presumably for what you're suggesting, in LVALUE context, $foo autovifies.
    In RVALUE context it does not (but does not error either)
    @$foo autovivifies in LVALUE context, but errors in RVALUE context (if
    $foo is undef). I don't think ->@* should have different semantics. Or
    did you mean to ask the question about ?->@* ?
  • Ricardo Signes at Jul 2, 2013 at 2:29 pm
    * Rafael Garcia-Suarez [2013-07-02T07:41:20]
    Also $href->%* I suppose.
    Yeah. And ->&* and ->** (!?)
    Can we talk about failure modes a bit? Please!
    A common idiom is to write @{ $foo || [] } in case $foo might be undefined.
    Do you remember the conditional-dereference operator that was
    bikeshedded to oblivion? ($foo?->bar() was one of the proposed
    syntaxes). Can we have this, plus ->@*, plus ?->@* that would expand
    to an empty list if its argument is undef?
    I brought up that operator some time ago, and basically said something like
    this:

    There were a bunch of edge cases when it first came up, and it wasn't clear how
    the patch we had would behave, or how it should behave. I was happy to pursue
    the patch if we could show that it was going to make sense, and I thought the
    most useful way to do it was to get the patch applying cleanly on blead to see
    how it *did* behave. Nobody stepped up to do that.

    I think that *if it can work sanely* a ?-> operator, it is a force multiplier
    for this syntax. If we can't, I think this syntax still has value. In other
    words: I think they have value independent of each other, but even more
    together. This, to me, is a good sign for both. :)
    $foo and @foo are interpolated in strings, but not %foo. I suppose
    ->%* would not either? or maybe just exclude those constructs from
    interpolation whatsoever?
    Yeah, we'd only interpolate, at most, ->$* and ->@*. If we want a way to
    stringize hashes, interpolating it, I think, will belong under a future
    proposal.

    --
    rjbs
  • Demerphq at Jul 2, 2013 at 12:51 pm

    On 27 June 2013 03:59, Ricardo Signes wrote:
    Perl 5's references are fine, but sometimes dereferencing them is not. We end
    up switching between postfix and circumfix syntax to dereference structures.

    push @{ $x->{foo}->[0]->m }, $y;

    Blech.

    In 5.14, an experimental feature was added to avoid this in some contexts:

    push $x->{foo}->[0]->m , $y;

    In other contexts, it (obviously) can't help:

    push @y, @{ $x->{foo}->[0]->m };

    subroutine( @{ $x->{foo}->[0]->m } )
    I'm not convinced this is a problem we should solve (on the other hand
    I'm not convinced it is not.)

    I would consider this code bug-prone and probably in maintenance mode
    rewrite it as:

    my $array= $x->{foo}->[0]->m;
    push @y, @$array if $array;

    Raphael raises similar points.

    Yves


    --
    perl -Mre=debug -e "/just|another|perl|hacker/"
  • David Golden at Jul 2, 2013 at 5:36 pm

    On Wed, Jun 26, 2013 at 9:59 PM, Ricardo Signes wrote:
    If we want the two forms to be really of equivalent value, we'll also need to
    be concerned with:

    print "Things: $aref_of_things->@*"

    ...which gets into less clearly-introduceable behavior.
    Quoting has so many special rules anyway that I see no reason to
    insist that postfix dereferencing work in quotes. I'd leave it as is.
    Finally, do we need to enable postfix slices? I think that if we can, we
    should. Agree.
    I think we have a few options for the specific tokens to put after that last
    arrow.
    Do you want that bikeshed argument now or later?

    What are you looking for? General reaction? Edge cases? Volunteers?
      Your OP reads a bit more like a "meditation" with only an implicit
    "What do you think?"

    ## Re other replies:
    [prototypes]
    Grudgingly, I agree: \@ should accept a postfix dereference. I'm not
    sure how ugly that is to implement. Presumably, if we check after
    parsing and just make sure the next op is a deref of the appropriate
    type, that might work. (It might shift when a prototype error is
    thrown, though.)
    [failure modes and conditional deref]
    I agree with your later statement that they are nice to have together
    but not required to have together. On conditional arrow itself, I
    must have missed the restarted discussion. Frankly, I think the way
    out of the edge cases is to define it as syntactically equivalent to
    something else that has known properties (much as you're doing for
    postfix deref being equivalent to circumfix deref) and reason from
    there.
    [do we need it or not & use of temporary variables]
    I think creating temporary variables ( @$array vs @{ ... long thing
    ... } ) as a workaround for visual simplicity is at least arguably
    undesirable. (Cue aliasing feature argument...). This means it will
    come down to a matter of style and personal preference. As long as
    "enough" people think postfix dereference is visually cleaner to read,
    then I think it adds value to *them* and is worth adding to the
    language.

    ## More considerations

    (1) Code references? Do we want consistency and allow $coderef->&*?
    Would it have semantics like $coderef->() or &$coderef (passing
    through @_)?

    (2) Glob references?

    For consistency only, since I think it would be rarely used.
    Personally, I'd say "no", but you should be explicit in the design
    decision about it.

    (4) Comparison to existing code deref syntax?

    The subroutine postfix deref "looks" like a subroutine call. The
    proposed "@*" or whatever looks like a variable. Would it be clearer
    if it looked more like existing dereference?

         $coderef->()
         $array->@* vs something like $array->[] or $array->@[]

    This gets confusing with postfix slices since these wouldn't be equivalent:

         deref: $array->@[]
         slice: $array->@[ @empty_list ]

    (4) Comparison with slice syntax?

         $array->@*
         $array->@[ 1..3 ]

    Leaving aside #3, do we want "all" vs "slice" to have some visual
    affordance? Splat sort of does that, but other syntax (e.g. colon)
    might not.

    (5) Will chaining work?

         ( ...expression... )->$*->$*; # ${ ${ ... expression ... } }

    Should it have a more compact syntax? I cringe to put this forward,
    but for example:

         ( ...expression...)->$** # deref twice?

    (6) Versus more of an autobox approach

    Does it have to be punctuation?

         $array->flatten

    This could get tricky just like auto-deref if objects with overloading
    are also to be supported (which I would just say "no" to). But I do
    wonder how much circumfix deref would go away in practice with
    autoboxing-style methods:

         $array->push( $other_array->flatten );
         $array->map( sub { ... } );
         $hash->keys;

    David

    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Kent Fredric at Jul 3, 2013 at 6:02 am

    On 3 July 2013 05:35, David Golden wrote:

    (6) Versus more of an autobox approach

    Does it have to be punctuation?

    $array->flatten

    This could get tricky just like auto-deref if objects with overloading
    are also to be supported (which I would just say "no" to). But I do
    wonder how much circumfix deref would go away in practice with
    autoboxing-style methods:

    $array->push( $other_array->flatten );
    $array->map( sub { ... } );
    $hash->keys;
    I would myself much rather the more autobox style interface than extra
    punctuation-based magic.

    Mostly, because when I see things like

        $foo->$*

    Being discussed, it interferes with how I visually parse things, and it
    makes me think that its a permutation of

         $foo->$bar

    And hence, without knowing of the special deref syntax, I would go looking
    for the variable in the same scope called

         $*

    And then get confused when I couldn't find it.

    Similar happens when I see

        $foo->@*

    My brain is already looking for the "variable" part of "@variable" and is
    just getting confused, and it doesn't make sense why somebody would try to
    call a method on some kind of invocant with an array as a list of methods
    to call, or something like that.

    I'd be far more in favour of a more IO::Handle approach, where basic types
    have autobox style methods on them.

    Hell, I'd even like a minimalist deref syntax like

        push $foo->list, 'value';

    which is much more intuitive to me, and works on my present mental model of
    Perl. Much more so than

        push $foo->@*, 'value';

    Which my mental model just goes "SYNTAX ERROR".

    Granted, you can freely add this feature and I don't have to use it.

    But I'd rather never have to use it, and I don't really see what value this
    particular syntax offers, and it just strikes me that this particular
    choice of syntax is covered with weird parsing edge cases that result from
    sharing tokens with other significant syntax features.

    There's only two downsides I presently see of doing it via a 'method' style
    deref:

    1. If $foo is a bless, $foo->list would invoke (blessed $object)->list, not
    ARRAY->list , which meant you'd have to use a different syntax if you were
    inside a class definition.

    2. ->@ could be imagined to be easily overloaded for, so bless()'d objects
    that **arent** arrays could still implement list deref overloads, so that
    they'd still work as arrays with things that need them to.

    In essence,

    my $foo = bless('SOMECLASS',{});
    push $foo->list # would have to bypass SOMECLASS::list if it existed to
    call the overloaded '@{}'
    push $foo->@ # no such problem


    --
    Kent
  • David Golden at Jul 3, 2013 at 8:39 am
    [Since insomnia is kicking my ass]
    On Wed, Jul 3, 2013 at 2:02 AM, Kent Fredric wrote:
    1. If $foo is a bless, $foo->list would invoke (blessed $object)->list, not
    ARRAY->list , which meant you'd have to use a different syntax if you were
    inside a class definition.
    Ugly option: do it with an upper case method, since those are
    reserved. But, frankly, I'd hate that, since my capslock is now a
    control key and the uc typing overhead would annoy me more than
    circumfix does.
    2. ->@ could be imagined to be easily overloaded for, so bless()'d objects
    that *arent* arrays could still implement list deref overloads, so that
    they'd still work as arrays with things that need them to.
    Assuming that it's implemented such that the resulting optree is an
    ordinary array deref op, then the existing "@{}" overloading will
    still work as it does now.

    David

    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Ricardo Signes at Jul 3, 2013 at 9:08 pm
    This is sort of a general reply to the whole set of replies. I just picked
    David's post to reply to because it seemed like I might quote it the most.

    I was going to apologize for the long dely in replying, but these posts were
    just yesterday? Boy, time drags on when you're debugging SSL.

    Some of the replies that already happened recreated some of the trains of
    thought I'd explored, and reasons to reject them, and seeing them happen
    outside my head was good, because I got to reflect on them some more. Then
    again, I don't think it changed what I'm thinking too much.
    Do you want that bikeshed argument now or later?
    I want us to discuss the design only as much as is required to prove that it
    can be done well. If it's "->@:" versus "->@*" because one looks prettier, I
    will tell people to go away. If it's that "->@*" can't possibly fit the
    grammar but "->:@" can, I think it's important to figure out.
    What are you looking for? General reaction? Edge cases? Volunteers?
    Edge cases so that we can confidently turn it over to a volunteer (or
    conscript).
    Your OP reads a bit more like a "meditation" with only an implicit
    "What do you think?"
    Man, if I ever thought an *explicit* request for opinions was needed on p5p,
    I'd check my prescription. ;)
    [prototypes]
    Grudgingly, I agree: \@ should accept a postfix dereference.
    Agreed, except not grudgingly. Postfix dereference needs to be a first class
    dereference. Every exception we have to document is another sign of failure.
    That's why I agree so much with:
    [failure modes and conditional deref]
    I agree with your later statement that they are nice to have together
    but not required to have together. On conditional arrow itself, I
    must have missed the restarted discussion. Frankly, I think the way
    out of the edge cases is to define it as syntactically equivalent to
    something else that has known properties (much as you're doing for
    postfix deref being equivalent to circumfix deref) and reason from
    there.
    (1) Code references? Do we want consistency and allow $coderef->&*?
    Would it have semantics like $coderef->() or &$coderef (passing
    through @_)?
    Yes, and like the ampersand form.
    (2) Glob references? Yes.
    deref: $array->@[]
    slice: $array->@[ @empty_list ]
    I don't know whether I can cope with that, which is why I didn't suggest it to
    begin with. If we do that, do %h{} and @a[] become equivalent to %h and @a?
    ("No" is fine, but the question seems worth raising.)

    In the past, I also suggested:

       $aref->@{}
       $href->%{}
       $cref->&{}
       $gref->*{}
       $sref->${}

    ...because these mirror the names of the overloads for these derefs.

    So far, I continue to feel most comfortable with ->@[1,3,5] and ->@* and so on.
    The ->@* is like ->@[*] if we had a p6 "whatever."

    As was suggested elsewhere (by Aristotle?) a whatever star would allow us to
    just say ->@[*], but I don't want to talk about introducing such a thing that's
    useful in so few contexts. Also, ->${*}? ->&{*}? No, I don't think it holds
    together.
    (5) Will chaining work?
    Yes, absolutely, it must.

       $sref->$*->@* # the array referenced by the scalar referenced by $sref
    Should it have a more compact syntax? I cringe to put this forward,
    but for example:

    ( ...expression...)->$** # deref twice?
    I think the long form is fine. It's not that long, either! :)
    (6) Versus more of an autobox approach
    No, I think this needs to be distinct from any future autoboxing proposal.

    I think I've replied to everything I needed to, but may reply more later. Time
    to go stock up before the holiday.

    --
    rjbs
  • D Perrett at Jul 3, 2013 at 9:51 pm
    perldoc perlvar says "$* was a variable that you could use to enable
    multiline matching.", removed in 5.10.0.

    Is it ok to remove a punctuation variable in and then use the ASCII
    space for something else?

    "Does it have to be punctuation? $array->flatten"

    I was already wondering about this: It seems we increasingly want to
    treat variables or references as objects and do method calls on them
    but have no way of doing so without polluting the 'namespace' of
    object methods. Would we be better with a syntax for builtin methods?

       $arrayRef->>flatten;
       $hashRef->>flatten;

    And why stop there...

       $arrayRef->>push($newItem);
       $couldBeUndef->>isa('IO::File'); # so we don't have to check if it's
    an object first!

    The question is then whether we open the gates to metaobject stuff in
    there so that when use /Mo.*/; adds ->>around and frees up ->around.

    Daniel
    On 3 July 2013 22:08, Ricardo Signes wrote:

    This is sort of a general reply to the whole set of replies. I just picked
    David's post to reply to because it seemed like I might quote it the most.

    I was going to apologize for the long dely in replying, but these posts were
    just yesterday? Boy, time drags on when you're debugging SSL.

    Some of the replies that already happened recreated some of the trains of
    thought I'd explored, and reasons to reject them, and seeing them happen
    outside my head was good, because I got to reflect on them some more. Then
    again, I don't think it changed what I'm thinking too much.
    Do you want that bikeshed argument now or later?
    I want us to discuss the design only as much as is required to prove that it
    can be done well. If it's "->@:" versus "->@*" because one looks prettier, I
    will tell people to go away. If it's that "->@*" can't possibly fit the
    grammar but "->:@" can, I think it's important to figure out.
    What are you looking for? General reaction? Edge cases? Volunteers?
    Edge cases so that we can confidently turn it over to a volunteer (or
    conscript).
    Your OP reads a bit more like a "meditation" with only an implicit
    "What do you think?"
    Man, if I ever thought an *explicit* request for opinions was needed on p5p,
    I'd check my prescription. ;)
    [prototypes]
    Grudgingly, I agree: \@ should accept a postfix dereference.
    Agreed, except not grudgingly. Postfix dereference needs to be a first class
    dereference. Every exception we have to document is another sign of failure.
    That's why I agree so much with:
    [failure modes and conditional deref]
    I agree with your later statement that they are nice to have together
    but not required to have together. On conditional arrow itself, I
    must have missed the restarted discussion. Frankly, I think the way
    out of the edge cases is to define it as syntactically equivalent to
    something else that has known properties (much as you're doing for
    postfix deref being equivalent to circumfix deref) and reason from
    there.
    (1) Code references? Do we want consistency and allow $coderef->&*?
    Would it have semantics like $coderef->() or &$coderef (passing
    through @_)?
    Yes, and like the ampersand form.
    (2) Glob references? Yes.
    deref: $array->@[]
    slice: $array->@[ @empty_list ]
    I don't know whether I can cope with that, which is why I didn't suggest it to
    begin with. If we do that, do %h{} and @a[] become equivalent to %h and @a?
    ("No" is fine, but the question seems worth raising.)

    In the past, I also suggested:

    $aref->@{}
    $href->%{}
    $cref->&{}
    $gref->*{}
    $sref->${}

    ...because these mirror the names of the overloads for these derefs.

    So far, I continue to feel most comfortable with ->@[1,3,5] and ->@* and so on.
    The ->@* is like ->@[*] if we had a p6 "whatever."

    As was suggested elsewhere (by Aristotle?) a whatever star would allow us to
    just say ->@[*], but I don't want to talk about introducing such a thing that's
    useful in so few contexts. Also, ->${*}? ->&{*}? No, I don't think it holds
    together.
    (5) Will chaining work?
    Yes, absolutely, it must.

    $sref->$*->@* # the array referenced by the scalar referenced by $sref
    Should it have a more compact syntax? I cringe to put this forward,
    but for example:

    ( ...expression...)->$** # deref twice?
    I think the long form is fine. It's not that long, either! :)
    (6) Versus more of an autobox approach
    No, I think this needs to be distinct from any future autoboxing proposal.

    I think I've replied to everything I needed to, but may reply more later. Time
    to go stock up before the holiday.

    --
    rjbs
  • David Golden at Jul 3, 2013 at 10:17 pm

    On Wed, Jul 3, 2013 at 5:51 PM, D Perrett wrote:
    object methods. Would we be better with a syntax for builtin methods?

    $arrayRef->>flatten;
    $hashRef->>flatten;
    Rik said "no autoboxing" anyway, but just to complete the thought, I
    think that "methods on references" and "methods on objects" could
    coexist. If a programmer doesn't know whether they have a reference or
    an object, it's up to them to sort it out. Objects should be opaque.

    Rather than ->> I'd prefer to just see it done with CORE, if that
    could be made to work, so it's similar to ordinary superclass method
    calling.

        $maybe_object->CORE::flatten;

    If we had core classes for containers and if references were objects
    this would all be a lot easier, but that ship has probably sailed.

    David

    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Brad Gilbert at Jul 4, 2013 at 2:54 am

    On Wed, Jul 3, 2013 at 5:17 PM, David Golden wrote:
    On Wed, Jul 3, 2013 at 5:51 PM, D Perrett wrote:

    object methods. Would we be better with a syntax for builtin methods?

    $arrayRef->>flatten;
    $hashRef->>flatten;
    Rik said "no autoboxing" anyway, but just to complete the thought, I
    think that "methods on references" and "methods on objects" could
    coexist. If a programmer doesn't know whether they have a reference or
    an object, it's up to them to sort it out. Objects should be opaque.

    Rather than ->> I'd prefer to just see it done with CORE, if that
    could be made to work, so it's similar to ordinary superclass method
    calling.

    $maybe_object->CORE::flatten;

    If we had core classes for containers and if references were objects
    this would all be a lot easier, but that ship has probably sailed.
    Actually how about ->^

         my %h = ( map{ $_, uc $_ } 'a'..'z' );
         my $h = \%h;
         my @a = ( 'a'..'z' );
         my $a = \@a;

         say for $h->^keys->^sort;
         say for $a->^keys;

         say for %h->^keys->^sort;
         say for %a->^keys;

         package Simple { sub new{bless {}} }

         my $obj = Simple->new;
         say for $obj->keys; # defers to ->^keys

         package Complex {
           our @ISA = 'Simple';
           sub keys{
             my ($self) = @_;
             sort keys %$self;
           }
         }

         $obj = Complex->new;
         say for $obj->keys; # sorted
         say for $obj->^keys; # unsorted

         $h->^keys->^sort->^say;

         push $a->^@, 1..9;
         $a->^push( 1..9 );

         my @letters = $a->map(sub{ /\A\w\z/ });

    We could even add to ^sort to make it effectively
    do a Schwartzian transform for us.

         @sorted = @unsorted->^sort(
           sub{ $a <=> $b }, # use numeric comparison
           sub{ length($_) } # but sort by the length of the string
         );

    I would like to point out that P6 uses .^ to call methods on
    an objects meta object.
    Which means that these return the same thing in Perl6:

         say @a.^sort;
         say @a.HOW;
         say @a.HOW.sort;

    So this may interfere with using ->^ for meta object
    programming.
    I think it may still be possible to use it for both
    purposes though.
  • Ricardo Signes at Jul 4, 2013 at 1:40 pm
    * Brad Gilbert [2013-07-03T22:54:05]
    Actually how about ->^
    […]
    say for $h->^keys->^sort;
    say for $a->^keys;
    This has gotten well off the topic at hand.

    --
    rjbs
  • David Nicol at Jul 4, 2013 at 5:29 am

    On Wed, Jul 3, 2013 at 4:08 PM, Ricardo Signes wrote:

    In the past, I also suggested:

    $aref->@{}
    $href->%{}
    $cref->&{}
    $gref->*{}
    $sref->${}

    ...because these mirror the names of the overloads for these derefs.
    Right now, circumfix dereference is

                 S{expr}

    for all sygills S.

    Are there any syntax collisions if this is simply allowed postfix,
    with empty braces, and
    all the slicing and so on remains the same?


             expr->S{} # new-style S{expr}


             $HoHoA->{abc}{def}@{}[1,2,3] # new-style @{$HoHoA->{abc}{def}}[1,2,3]
             $HoHoA->{abc}{def}${}[2] # new-style ${$HoHoA->{abc}{def}}[2]
  • Ricardo Signes at Jul 6, 2013 at 11:28 pm
    * David Nicol [2013-07-04T01:29:42]
    Are there any syntax collisions if this is simply allowed postfix,
    with empty braces, and
    all the slicing and so on remains the same?
    […]
    $HoHoA->{abc}{def}@{}[1,2,3] # new-style @{$HoHoA->{abc}{def}}[1,2,3]
    $HoHoA->{abc}{def}${}[2] # new-style ${$HoHoA->{abc}{def}}[2]
    I don't think so.

    --
    rjbs
  • Dr.Ruud at Jul 7, 2013 at 12:16 am

    On 04/07/2013 07:29, David Nicol wrote:

    $HoHoA->{abc}{def}${}[2] # new-style ${$HoHoA->{abc}{def}}[2]
    Which I assume is basically the same as $HoHoA->{abc}{def}[2].


    perl -MData::Dumper -e'
        ${$HoHoA->{abc}{def}}[2];
        print Dumper( $HoHoA );

        ${$HoHoA->{abc}{def}}[2] = "test";
        print Dumper( $HoHoA );

        $v = ${$HoHoA->{abc}{def}}[2];
        print Dumper( $v );

        $v = $HoHoA->{abc}{def}[2];
        print Dumper( $v );
    '

    $VAR1 = {
                'abc' => {
                           'def' => []
                         }
              };

    $VAR1 = {
                'abc' => {
                           'def' => [
                                      undef,
                                      undef,
                                      'test'
                                    ]
                         }
              };

    $VAR1 = 'test';

    $VAR1 = 'test';

    --
    Ruud
  • David E. Wheeler at Jul 4, 2013 at 9:44 am

    On Jul 3, 2013, at 11:08 PM, Ricardo Signes wrote:

    Your OP reads a bit more like a "meditation" with only an implicit
    "What do you think?"
    Man, if I ever thought an *explicit* request for opinions was needed on p5p,
    I'd check my prescription. ;)
    Literally LOLed. Almost lost my coffee.

    David
  • Father Chrysostomos at Jul 5, 2013 at 3:24 pm

    rjbs:
    Edge cases
    If foo->@* means @foo, then does foo->@*[0] mean @foo[0]? That is
    useless if we have foo->@[0].

    If we have foo->@[0] and extend it to all sigils, we end up with:

    $_->*{foo} # means *$_{foo}
    $_->${foo} # means $$_{foo} (i.e., $_->{foo})
    $_->&(foo) # means $&_{foo} (i.e., $_->(foo))

    The last two are useless. The dollar form steals existing syntax.
    so that we can confidently turn it over to a volunteer (or
    conscript).
    See sprout/postderef. Caveat: It was late when I wrote it.
  • David Nicol at Jul 5, 2013 at 7:10 pm

    On Fri, Jul 5, 2013 at 10:24 AM, Father Chrysostomos wrote:
    rjbs:
    Edge cases
    If foo->@* means @foo, then does foo->@*[0] mean @foo[0]? That is
    useless if we have foo->@[0].

    If we have foo->@[0] and extend it to all sigils, we end up with:
    the advantage of simply allowing postfix in addition to circumfix with
    the same symbols
    is, there are no other complications.

        @{foo} would be allowed to be written as foo@{}, and the other
    accesses into it would remain the same. foo@{}[0] is a slice with a
    single element, foo${}[0] is an element access


    $_->*{foo} # means *$_{foo}
    the glob referred to by the globref in $_ is considered as a hash and
    we access the value in the slot named "foo" Adding the implied curlies
    gives *{$_}{foo} and in simple postfix syntax that would be $_*{}{foo}

    $_->${foo} # means $$_{foo} (i.e., $_->{foo})
    $_->&(foo) # means $&_{foo} (i.e., $_->(foo))

    The last two are useless. The dollar form steals existing syntax.
    First one: $_ contains a hashref and we want to look up the thing in
    the foo slot. We have the skinny arrow postfix syntax for this
    already; simple postfix brackets would give yet another
    way to fully spell it out: in addition to ${$_}{foo} and $_->{foo}
    there would be $_${}{foo}

    Second one: if we're trying to call the coderef in $_ with an argument
    of foo, &{$_}(foo), the circumfix ampersand dereference could become
    postfix as $_&{}(foo).



    if the empty curlies become optional, that would give a tight-binding
    prefix sigil, a loose-binding postfix sigil, and circumfix (prefix
    plus curlies) for when you need an intermediate grouping.


    @foo and foo@ would mean the same thing. @foo@ would continue to be nonsense.
    $foo[0] could get written foo$[0].


    *$_{foo}
       could be written as $_*{foo}

    $_->{foo}
       could be written as $_${foo}

    $_->(foo)
       could be written as $_&(foo)
  • Ricardo Signes at Jul 6, 2013 at 11:43 pm
    * Father Chrysostomos [2013-07-05T11:24:19]
    rjbs:
    Edge cases
    If foo->@* means @foo, then does foo->@*[0] mean @foo[0]? That is
    useless if we have foo->@[0].

    If we have foo->@[0] and extend it to all sigils, we end up with:

    $_->*{foo} # means *$_{foo}
    $_->${foo} # means $$_{foo} (i.e., $_->{foo})
    $_->&(foo) # means $&_{foo} (i.e., $_->(foo))

    The last two are useless. The dollar form steals existing syntax.
    I agree with what I think your assessment is. That is: foo->@*[0] is not
    @foo[0]. ->&() is not needed. ->*{foo}, I'm not sure. I think it may be
    needed to get a purely-postfix entry out of a typeglob reference, but it's
    something I've done so rarely that I'm not sure and I am writing this message
    as I walk out the door. I'd rather hit send than test.

    If nothing else, it can wait!
    See sprout/postderef. Caveat: It was late when I wrote it.
    I am excited to test it. Hopefully tomorrow, more likely Tuesday.

    Thanks, though!

    --
    rjbs
  • Ricardo Signes at Jul 16, 2013 at 3:03 pm
    * Ricardo Signes [2013-07-06T19:43:09]
    * Father Chrysostomos [2013-07-05T11:24:19]
    See sprout/postderef. Caveat: It was late when I wrote it.
    I am excited to test it. Hopefully tomorrow, more likely Tuesday.
    "I didn't say which Tuesday."

    Last night and this morning, I built and installed this branch and I updated a
    branch of Dist-Zilla to use this syntax:

       https://github.com/rjbs/Dist-Zilla/commit/f48dcea
       https://github.com/rjbs/Dist-Zilla/commit/67a06a1

    When I started, I was wondering whether ->@[] wouldn't have been better after
    all. By the time I was finishing, trying both syntaxes, I felt very good about
    ->@*.

    All tests successful.

    That said, although the code base is largish, the usages are not highly varied.
    I'll try some more extensive testing soon.

    --
    rjbs
  • Ricardo Signes at Aug 10, 2013 at 1:53 am
    * Ricardo Signes [2013-07-16T11:03:20]
    * Ricardo Signes [2013-07-06T19:43:09]
    * Father Chrysostomos [2013-07-05T11:24:19]
    See sprout/postderef. Caveat: It was late when I wrote it.
    I am excited to test it. Hopefully tomorrow, more likely Tuesday.
    All tests successful.
    I would like to move forward with this.

    Clear to-dos:

    1. document things to be improved or implemented (including bugs)
    2. document the new syntax
    3. write tests
    4. improve or implement the items from (1)

    I have listed those in the order in which I feel comfortable doing work.

    What kind of tests do we want for this feature? It will be quite easy to do a
    lot of this testing with string evals, assuming we're not concerned about
    trying to treat this like a very low-level test which, in some ways, it would
    be.

    Who else wants to kick in? :)

    --
    rjbs
  • Father Chrysostomos at Aug 10, 2013 at 2:23 am
    What kind of tests do we want for this feature?
    Suggestion: Duplicate t/op/ref.t. Delete tests that do not apply.
    Convert those that do.
    Who else wants to kick in? :)
    Well, I am still cleaning up my work on constants and copy-on-write
    (and the 80 or so bugs I am finding in auditing existing code for
    handling the latter) and getting the regexp engine to work on long
    strings. Once I finish those things, if nobody has done them yet, I
    might work on the tests. :-)
  • Dave Mitchell at Jul 3, 2013 at 2:23 pm

    On Wed, Jun 26, 2013 at 09:59:02PM -0400, Ricardo Signes wrote:
    push @y, $x->{foo}->[0]->m->@*;
    If we want the two forms to be really of equivalent value, we'll also need to
    be concerned with:

    print "Things: $aref_of_things->@*"

    ...which gets into less clearly-introduceable behavior.

    Alternatively, what about instead of expr->@*, we use

         expr->[]?

    This is currently a syntax error. It has the mnemonic of a list slice
    that contains all elements. Ditto expr->{}.

    It's also currently a syntax error in quoted strings, so can easily be used
    there too:

         print "$a->{}bar"

    It could conceivably be expanded to indicate slicing, such as

         $a->[1,5,7]

    *except* that this is currently valid syntax, where the list of indices is
    evaluated in scalar context, which discards all but the last element. So
    the above is currently equivalent to

         $a->[7]

    Potentially we could deprecate the current behaviour, then (if it turns
    out not to be commonly used), repurpose it. This would also allow slices
    in strings, e.g. "$a->[1,5,7]", which also currently evaluates to
    "$a->[7]".

    --
    I thought I was wrong once, but I was mistaken.
  • David Golden at Jul 3, 2013 at 3:03 pm

    On Wed, Jul 3, 2013 at 10:23 AM, Dave Mitchell wrote:
    expr->[]
    $a->[1,5,7]
    This is even more attractive to me when considered together with
    normal element access:

         $array->[]; # dereference
         $array->[$i]; # single element
         $array->[@list]; # array slice

         $hash->{}; # dereference
         $hash->{$n}; # single element
         $hash->{@list}; # hash slice

    It bugs me slightly that [] and {} look "empty" when in fact they
    return everything, but I like the parallelism more than I fear that
    visual confusion. That table above is easy to teach and easy to
    remember.

    Would we allow whitespace between [] and {}? Or would we treat them
    like a type of operator and insist that they be without a space?

    David

    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Mark Allen at Jul 3, 2013 at 3:13 pm
    +1 from the peanut gallery, for whatever that's worth.


    ________________________________
      From: David Golden <xdg@xdg.me>
    To: Dave Mitchell <davem@iabyn.com>
    Cc: Ricardo Signes <perl.p5p@rjbs.manxome.org>; p5p <perl5-porters@perl.org>
    Sent: Wednesday, July 3, 2013 10:02 AM
    Subject: Re: postfix dereference syntax

    On Wed, Jul 3, 2013 at 10:23 AM, Dave Mitchell wrote:
    expr->[]
    $a->[1,5,7]
    This is even more attractive to me when considered together with
    normal element access:

        $array->[]; # dereference
        $array->[$i]; # single element
        $array->[@list]; # array slice

        $hash->{}; # dereference
        $hash->{$n}; # single element
        $hash->{@list}; # hash slice

    It bugs me slightly that [] and {} look "empty" when in fact they
    return everything, but I like the parallelism more than I fear that
    visual confusion.  That table above is easy to teach and easy to
    remember.

    Would we allow whitespace between [] and {}?  Or would we treat them
    like a type of operator and insist that they be without a space?

    David

    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Eric Brine at Jul 4, 2013 at 1:40 pm

    On Wed, Jul 3, 2013 at 11:02 AM, David Golden wrote:
    On Wed, Jul 3, 2013 at 10:23 AM, Dave Mitchell wrote:
    expr->[]
    $a->[1,5,7]
    This is even more attractive to me when considered together with
    normal element access:

    $array->[]; # dereference
    $array->[$i]; # single element
    $array->[@list]; # array slice

    $hash->{}; # dereference
    $hash->{$n}; # single element
    $hash->{@list}; # hash slice
    What's the output of

    sub f { say wantarray || 0 }
    $array->[ f() ]
    $hash->{ f() }

    Right now, it's 0 0, so the following aren't backwards compatible:

    $array->[@list]
    $hash->{@list}

    It bugs me slightly that [] and {} look "empty" when in fact they
    >
    return everything


    Is ->[*] available?
  • Aristotle Pagaltzis at Jul 3, 2013 at 3:09 pm

    * Dave Mitchell [2013-07-03 16:25]:
    Alternatively, what about instead of expr->@*, we use

    expr->[]?

    This is currently a syntax error. It has the mnemonic of
    a list slice that contains all elements. Ditto expr->{}.
    The same occurred to me just after reading Kent’s mail.
    It's also currently a syntax error in quoted strings, so can easily be
    used there too:

    print "$a->{}bar"
    Beautiful!

    It’s fine to say that quoting already has a lot of special cases, in the
    long run I don’t think it’s something that could be gotten away with.
    But I expected calls for support in interpolation to happen as soon as
    people started using postfix deref, and if I was right on that, then it
    was going to be added eventually, regardless of argument, so I chose to
    make none, and leave this to play itself out.

    But I did worry about the need to change the meaning of unlikely but
    valid code when that happened.

    That this syntax avoids this problem to start with is great.

    Except…
    It could conceivably be expanded to indicate slicing, such as

    $a->[1,5,7]

    *except* that this is currently valid syntax, where the list of
    indices is evaluated in scalar context, which discards all but the
    last element. So the above is currently equivalent to

    $a->[7]

    Potentially we could deprecate the current behaviour, then (if it turns
    out not to be commonly used), repurpose it. This would also allow slices
    in strings, e.g. "$a->[1,5,7]", which also currently evaluates to
    "$a->[7]".
    … here again I *am* worried. Because this isn’t the worst of it. If it
    was just array slices, this wouldn’t be too bad. If push came to shove
    it would be possible to say “we’re not doing slices (yet, at least)”,
    and they *could* be written like this:

         ( $foo->bar->baz->[] )[1,5,7]

    Obviously you might as well write that the old way:

         @{ $foo->bar->baz }[1,5,7]

    The first even looks slightly less punctualicious (it omits the array
    sigil and the parens are less noisy than the curlies).

    So, not great, but it’s all liveable.


    However… *this* runs into big trouble:

         $foo->bar->baz->{qw( foo bar baz )}

    That’s not a hash slice… that already means a faux multidimensional
    array. And if you try to punt?

         ( $foo->bar->baz->{} ){ # … sorry, Dave, I’m afraid I can’t do that

    Woops. Ain’t no way but the old one:

         @{ $foo->bar->baz }{qw( foo bar baz )}


    And then there is another puzzle: suppose that was solved somehow. (I
    have an idea. But now is not the time.) Fine.

    Then how to integrate Ruslan’s new hash slices with this syntax? It
    doesn’t really have room to accommodate more than one type of slice.

    And then it dawns on me that this problem extends further: what syntax
    do you use to postfix-deref scalars in this proposal? (Or subs… or uh,
    typeglobs, yeah I know.)

    And now I sit here with a sinking feeling. I don’t think this is doable…

    I’d *LOVE* if someone had a bright idea to address all that. I really
    think this is the right syntax for the part of postfix-deref that can be
    covered with this syntax.


    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>
  • David Golden at Jul 3, 2013 at 3:22 pm

    On Wed, Jul 3, 2013 at 11:09 AM, Aristotle Pagaltzis wrote:
    However… *this* runs into big trouble:

    $foo->bar->baz->{qw( foo bar baz )}
    Damn. I forgot about that in my excitement about parallelism.

    I think echoing current slice syntax could be the way out of the
    general conundrum, even if string interpolation doesn't work easily:

         $array->@[ qw/foo bar baz/ ]
         $hash->@{ qw/foo bar baz/ }

    The latter could be ->%{ @list } I suppose, but that's a question for
    whether mirroring existing syntax is better than introducing sigil
    invariance but only for postfix.

    David


    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Aristotle Pagaltzis at Jul 3, 2013 at 3:48 pm

    * David Golden [2013-07-03 17:25]:
    Damn. I forgot about that in my excitement about parallelism.
    Personally I wouldn’t mind this Perl4ism getting rooted out eventually.
    It’s an ugly feature from an era past – ugly even in its time, when it
    had necessity going for it.
    I think echoing current slice syntax could be the way out of the
    general conundrum, even if string interpolation doesn't work easily:

    $array->@[ qw/foo bar baz/ ]
    $hash->@{ qw/foo bar baz/ }
    … aaaand that’s essentially back to what RJBS proposed.

    Which will do, in a pinch, but is _*noisy*_ – I’d not be super happy if
    there was no better alternative, even though that would still be better
    than nothing.

    I think the way out of this conundrum is to weigh the options slowly and
    carefully rather than just toss out the first thing that seems like it
    should work… so personally I don’t want to make any counterproposal yet.
    This is a big feature in very little space, and an important one.

    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>
  • Kent Fredric at Jul 3, 2013 at 3:47 pm

    On 4 July 2013 03:09, Aristotle Pagaltzis wrote:
    * Dave Mitchell [2013-07-03 16:25]:
    Alternatively, what about instead of expr->@*, we use

    expr->[]?

    This is currently a syntax error. It has the mnemonic of
    a list slice that contains all elements. Ditto expr->{}.
    The same occurred to me just after reading Kent’s mail.
    It's also currently a syntax error in quoted strings, so can easily be
    used there too:

    print "$a->{}bar"
    Beautiful!
    I like it more and more already. '->[ ]' says far more to me about
    dereffing the invocant than ->@ does.

    I was thinking that because of the implict bounding of this notation (
    the [ ] parens ), you could probably get away with more "weird" syntax
    within the [].

    And you could possibly entertain the idea of a "*" component inside
    it, or something, as a shorthand for a regex-like slicer.

    ie:

      ->[] == ->[*] == ->[qr/.*/]

    Which would be intuitive enough for the most part.

      $arry->[*] = @list implies @{$array} = @list
      $arry->[1] = @list implies ( $arry->[1], ) = @list
      $arry->[1,2,3] = @list implies ( $arry->[1], $arry->[2],$arry->[3],) = @list

    etc.
    And same for hashes

    ->{} == ->{*} == ->{qr/.*/} == ->{ grep qr/.*/ keys %$invocant }

    Though I don't like special casing too much, ... it could be seen we
    could solve this dereferencing problem simply by extending the slice
    operators to do our bidding.

    --
    Kent
  • Aristotle Pagaltzis at Jul 3, 2013 at 4:19 pm

    * Kent Fredric [2013-07-03 17:50]:
    I like it more and more already. '->[ ]' says far more to me about
    dereffing the invocant than ->@ does.
    Yes, and for that reason I would like to find some solution for its
    problems… rather than starting to come up with new features for it
    already. :-)

    If a Perl 6-ish “whatever” is added to Perl 5 – and the idea has come up
    in various ways at various times so even if I’d rather table it now, it
    seems to be worth thinking about eventually –, I would like for it to
    follow some sort of syntactical model that fits elsewhere, rather than
    just be a one-off special syntax only within one special form of the
    deref syntax. That’s… ugly. That’s template engine language style.

    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>
  • Kent Fredric at Jul 3, 2013 at 3:56 pm

    On 4 July 2013 03:09, Aristotle Pagaltzis wrote:
    $foo->bar->baz->{qw( foo bar baz )}
    Well, assuming you turned on the ability to use

    - new deref syntax
    - new slice syntax

    If they eventually arrived together as one feature ( which I see it
    possible of doing ), you could control their scope with a lexical
    pragma, a lexical pragma that disabled multidimensional arrays at the
    same time.

    And there is already a cpan module that does the latter =).

    https://metacpan.org/module/multidimensional # ilmari++



    --
    Kent
  • Aristotle Pagaltzis at Jul 3, 2013 at 4:20 pm

    * Kent Fredric [2013-07-03 18:00]:
    On 4 July 2013 03:09, Aristotle Pagaltzis wrote:
    $foo->bar->baz->{qw( foo bar baz )}
    Well, assuming you turned on the ability to use

    - new deref syntax
    - new slice syntax

    If they eventually arrived together as one feature ( which I see it
    possible of doing ), you could control their scope with a lexical
    pragma, a lexical pragma that disabled multidimensional arrays at the
    same time.

    And there is already a cpan module that does the latter =).

    https://metacpan.org/module/multidimensional # ilmari++
    That is precisely where my thoughts were going. :-) Just, as I said,
    there are a lot more problems that need contemplation first.

    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>
  • David Golden at Jul 3, 2013 at 5:20 pm

    On Wed, Jul 3, 2013 at 11:55 AM, Kent Fredric wrote:
    If they eventually arrived together as one feature ( which I see it
    possible of doing ), you could control their scope with a lexical
    pragma, a lexical pragma that disabled multidimensional arrays at the
    same time.
    There's a big difference between 'turn on this feature' and 'turn off
    this mis-feature' type lexical pragmas and 'swap this syntax for that
    syntax' pragmas.

    Much like "use dots", the lexical change you describe would offer yet
    another dialect of Perl 5, and I think that's a bigger Perl 5 language
    design decision that needs to be made independent of any particular
    feature.

    David



    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Aristotle Pagaltzis at Jul 3, 2013 at 5:50 pm

    * David Golden [2013-07-03 19:25]:
    On Wed, Jul 3, 2013 at 11:55 AM, Kent Fredric wrote:
    If they eventually arrived together as one feature ( which I see it
    possible of doing ), you could control their scope with a lexical
    pragma, a lexical pragma that disabled multidimensional arrays at the
    same time.
    There's a big difference between 'turn on this feature' and 'turn off
    this mis-feature' type lexical pragmas and 'swap this syntax for that
    syntax' pragmas.

    Much like "use dots", the lexical change you describe would offer yet
    another dialect of Perl 5, and I think that's a bigger Perl 5 language
    design decision that needs to be made independent of any particular
    feature.
    You bring up some sound principles, but are they applicable here? Are
    these features orthogonal? E.g. if you do *not* disable the misfeature,
    but *do* enable the new feature – what that combination do? Does its
    behaviour follow from the composition of the individual features, or is
    there a conflict? If there is a conflict, it will have either have to be
    explicitly resolved in a design decision, or it will have to be prevent
    by forbidding this combination.

    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>
  • David Golden at Jul 3, 2013 at 7:56 pm

    On Wed, Jul 3, 2013 at 1:50 PM, Aristotle Pagaltzis wrote:
    You bring up some sound principles, but are they applicable here? Are
    these features orthogonal? E.g. if you do *not* disable the misfeature,
    but *do* enable the new feature – what that combination do? Does its
    behaviour follow from the composition of the individual features, or is
    there a conflict? If there is a conflict, it will have either have to be
    explicitly resolved in a design decision, or it will have to be prevent
    by forbidding this combination.
    I meant in general, not suggesting that implementation of this or any
    other feature should be decomposed into "on" and "off" pieces. The
    fact that "no multidimensional" exists already is sort of a side issue
    to the point I was making.

    "use feature 'foo'" is a "turn on this syntax" option. Those are
    orthogonal -- they make an illegal syntax legal. Likewise, "no
    indirect" is a "turn off this syntax" option -- it makes a legal
    syntax into an error. Whereas "use dots" is a "change the meaning of
    this legal syntax to something else" option.

    Generally, I think the p5p approach has been to deprecated (and then
    remove) unwanted syntax to make it available for other use.

    I see a trend (recent? not sure) of people advocating "dialect"
    pragmas -- when we can't just deprecate an old syntax, some people who
    prefer something else would rather just replace it lexically.

    That's what I mean is a broader design decision than any one feature.
    Do we want "dialects" of Perl 5 or not? It's a way out of the
    back-compatibility box [ironic to say, given your post about it], but
    I think it comes at a cost that we shouldn't trivialize.

    David


    --
    David Golden <xdg@xdg.me>
    Take back your inbox! → http://www.bunchmail.com/
    Twitter/IRC: @xdg
  • Aristotle Pagaltzis at Jul 3, 2013 at 9:37 pm

    * David Golden [2013-07-03 22:00]:
    I meant in general, not suggesting that implementation of this or any
    other feature should be decomposed into "on" and "off" pieces. The
    fact that "no multidimensional" exists already is sort of a side issue
    to the point I was making.

    "use feature 'foo'" is a "turn on this syntax" option. Those are
    orthogonal -- they make an illegal syntax legal. Likewise, "no
    indirect" is a "turn off this syntax" option -- it makes a legal
    syntax into an error. Whereas "use dots" is a "change the meaning of
    this legal syntax to something else" option.

    Generally, I think the p5p approach has been to deprecated (and then
    remove) unwanted syntax to make it available for other use.

    I see a trend (recent? not sure) of people advocating "dialect"
    pragmas -- when we can't just deprecate an old syntax, some people who
    prefer something else would rather just replace it lexically.

    That's what I mean is a broader design decision than any one feature.
    Do we want "dialects" of Perl 5 or not? It's a way out of the
    back-compatibility box [ironic to say, given your post about it], but
    I think it comes at a cost that we shouldn't trivialize.
    My game plan would be not `use dots` but `use feature 'postderef'` and
    have it enabled by `use 5.20` or whichever. You can then either use
    faux-multidim hashes or postfix deref, but not both, and when you’re
    writing new code then it’s clear which one p5p would prefer you to use.
    Then some time down the road we can start the process of deprecating
    multidim hashes altogether, which is where I’d like this to go.

    I’m not interested in a dialect.

    But these faux-multidim hashes have been an advertised feature of Perl
    forever, and I expect the deprecation to run afoul of plenty of legacy
    Perl. Not mountains, but not insignificant, and stuff that doesn’t get
    touched much, i.e. precisely the kind of code that requires the longest
    deprecation phases. So I’d prefer the leeway to make this deprecation
    a long one.

    Which means that if we were to postpone postfix deref until the syntax
    is actually really safely free, who knows if it’ll be non-experimental
    by 5.30.

    I’m not interested in waiting that long.

    So I’m fine with a dialect-like state in the meantime, in a realpolitik
    kind of way. We’re talking about faux-multidim hashes anyway, not the
    arrow op that appears on something like every second line of Perl code.
    Some dialects are more… dialectical than others.

    Regards,
    --
    Aristotle Pagaltzis // <http://plasmasturm.org/>
  • Leon Timmermans at Jul 3, 2013 at 9:40 pm

    On Wed, Jul 3, 2013 at 9:55 PM, David Golden wrote:
    I see a trend (recent? not sure) of people advocating "dialect"
    pragmas -- when we can't just deprecate an old syntax, some people who
    prefer something else would rather just replace it lexically.

    That's what I mean is a broader design decision than any one feature.
    Do we want "dialects" of Perl 5 or not? It's a way out of the
    back-compatibility box [ironic to say, given your post about it], but
    I think it comes at a cost that we shouldn't trivialize.
    I'm all for dialect pragmas on CPAN, but I don't think it should in
    core. In core, the only dialects should be 5.16, 5.18, 5.20. YMMV.

    Leon
  • Father Chrysostomos at Aug 14, 2013 at 4:03 pm

    Ricardo Signes wrote:
    « $x->@* acts exactly like @$x » is the rule. "Except in interpolation" would
    be the exception.
    So we allow "$x->@*" and "$$x->@*" and "$x->$*->@*".

    What about the brace forms? How far does the equivalance of "@{...}"
    and "...->@*" hold?

    "@{$foo}" --> "$foo->@*"
    "@{$foo[0]}" --> "$foo[0]->@*"
    "@{*$foo}" ???
    "@{$foo->**}" --> "$foo->**->@*"
    "@{$foo->()}" --> "$foo->()->@*"
    "@{$foo++}" --> "$foo++->@*"
    "@{$foo ? bar() : []}" => "$foo ? bar() : []->@*"
  • Johan Vromans at Aug 14, 2013 at 6:22 pm

    Father Chrysostomos writes:

    Ricardo Signes wrote:
    « $x->@* acts exactly like @$x » is the rule. "Except in interpolation" would
    be the exception.
    So we allow "$x->@*" and "$$x->@*" and "$x->$*->@*".

    What about the brace forms? How far does the equivalance of "@{...}"
    and "...->@*" hold?

    "@{$foo}" --> "$foo->@*"
    "@{$foo[0]}" --> "$foo[0]->@*"
    "@{*$foo}" ???
    "@{$foo->**}" --> "$foo->**->@*"
    "@{$foo->()}" --> "$foo->()->@*"
    "@{$foo++}" --> "$foo++->@*"
    "@{$foo ? bar() : []}" => "$foo ? bar() : []->@*"
    Which makes me think, once more, do we actualle *need* postfix
    dereference? Does it provide anything we cannot do already, albeit at
    the cost of an extra pair of braces? In other words: is it worth the
    effort?

    -- Johan
  • Demerphq at Aug 14, 2013 at 6:39 pm

    On 14 August 2013 20:22, Johan Vromans wrote:
    Father Chrysostomos <sprout@cpan.org> writes:
    Ricardo Signes wrote:
    « $x->@* acts exactly like @$x » is the rule. "Except in interpolation" would
    be the exception.
    So we allow "$x->@*" and "$$x->@*" and "$x->$*->@*".

    What about the brace forms? How far does the equivalance of "@{...}"
    and "...->@*" hold?

    "@{$foo}" --> "$foo->@*"
    "@{$foo[0]}" --> "$foo[0]->@*"
    "@{*$foo}" ???
    "@{$foo->**}" --> "$foo->**->@*"
    "@{$foo->()}" --> "$foo->()->@*"
    "@{$foo++}" --> "$foo++->@*"
    "@{$foo ? bar() : []}" => "$foo ? bar() : []->@*"
    Which makes me think, once more, do we actualle *need* postfix
    dereference? Does it provide anything we cannot do already, albeit at
    the cost of an extra pair of braces? In other words: is it worth the
    effort?
    I think it complicates an already complex subject without adding that
    much benefit.

    Yves


    --
    perl -Mre=debug -e "/just|another|perl|hacker/"
  • Brad Baxter at Aug 14, 2013 at 8:44 pm

    On Wed, Aug 14, 2013 at 2:22 PM, Johan Vromans wrote:

    Father Chrysostomos <sprout@cpan.org> writes:
    Ricardo Signes wrote:
    « $x->@* acts exactly like @$x » is the rule. "Except in
    interpolation" would
    be the exception.
    So we allow "$x->@*" and "$$x->@*" and "$x->$*->@*".

    What about the brace forms? How far does the equivalance of "@{...}"
    and "...->@*" hold?

    "@{$foo}" --> "$foo->@*"
    "@{$foo[0]}" --> "$foo[0]->@*"
    "@{*$foo}" ???
    "@{$foo->**}" --> "$foo->**->@*"
    "@{$foo->()}" --> "$foo->()->@*"
    "@{$foo++}" --> "$foo++->@*"
    "@{$foo ? bar() : []}" => "$foo ? bar() : []->@*"
    Which makes me think, once more, do we actualle *need* postfix
    dereference? Does it provide anything we cannot do already, albeit at
    the cost of an extra pair of braces? In other words: is it worth the
    effort?

    -- Johan

    FWIW, I would never use (this incarnation of) postfix dereference. I'm
    sorry, but to my eye $foo->@* is not prettier than @{$foo}. And I
    understand the latter.

    That is to say, with the latter, I know exactly where the entity being
    dereferenced begins and ends. With the former--phew--you got me.

    Regards,

    Brad
    ​​
  • David Nicol at Aug 14, 2013 at 9:31 pm
    it's not about $foo->@*
    it's about $foo->{bar}->baz(27, flurg => gnar_now())->[4]->@*

    at the end of a long chain of stuff eventually yielding a reference,
    sometimes you want to get the whole array, or a slice of it, and currently
    you need to back up and enclose the whole thing.

    What we've just set up is the filling of the holes left in the current
    incomplete postfix dereference syntax, which allows only scalar element
    accesses.

  • Johan Vromans at Aug 15, 2013 at 7:44 am

    David Nicol writes:

    it's not about $foo->@*
    it's about $foo->{bar}->baz(27, flurg => gnar_now())->[4]->@*
    at the end of a long chain of stuff eventually yielding a reference,
    sometimes you want to get the whole array, or a slice of it, and currently
    you need to back up and enclose the whole thing.
    Yes, that is quite a burden, assuming you still use butterflies :)

    Seriously, this is a strong indication of strictly left-to-right code
    writing, not knowing beforehand what you want to do with that big
    expression. Makes me frown.
    What we've just set up is the filling of the holes left in the current
    incomplete postfix dereference syntax, which allows only scalar element
    accesses.
    Unbiased opinion: I do not doubt it fits in somewhere, my question was
    whether it is worth the efforts given that it seems to add to
    implementation and maintenance complexity, and potential user confusion.

    Personal opinion: Since we have $aref->[1], $aref->[] makes sense to
    mean the whole array. Likewise, $href->{foo}, $href->{}. But all other
    examples I've seen of postfix dereference syntax seem rather contrived
    to me. Why would you ever write $$foo->$* instead of $$$foo or ${$$foo}?
    How often would you need $foo->\*? blah->&*?

    -- Johan
  • Darin McBride at Aug 15, 2013 at 4:13 pm

    On Wednesday August 14 2013 4:44:31 PM Brad Baxter wrote:

    FWIW, I would never use (this incarnation of) postfix dereference. I'm
    sorry, but to my eye $foo->@* is not prettier than @{$foo}. And I
    understand the latter.

    That is to say, with the latter, I know exactly where the entity being
    dereferenced begins and ends. With the former--phew--you got me.
    I think this says more about your comfort level than the usefulness, or lack
    thereof, of this functionality. I know a lot of people who would never use
    perl 5 syntax because it's no prettier to them than perl 4 syntax, and they
    understand the latter.

    To me, the proposed new syntax will take a bit of learning, but will be hugely
    beneficial and make my code both easier to write as well as clearer in meaning
    as the flow will be more natural.
    On Thursday August 15 2013 9:44:26 AM Johan Vromans wrote:
    David Nicol <davidnicol@gmail.com> writes:
    it's not about $foo->@*
    it's about $foo->{bar}->baz(27, flurg => gnar_now())->[4]->@*
    at the end of a long chain of stuff eventually yielding a reference,
    sometimes you want to get the whole array, or a slice of it, and currently
    you need to back up and enclose the whole thing.
    Yes, that is quite a burden, assuming you still use butterflies :)

    Seriously, this is a strong indication of strictly left-to-right code
    writing, not knowing beforehand what you want to do with that big
    expression. Makes me frown.
    I know what I want to do with that big expression. However, I have concocted
    it in order of what is going to happen.

    I'm taking the %$foo hash. Looking up the key bar. I expect that to be an
    object. I'll call its baz method. It will return an array ref, which I will
    take the fifth element of, and THAT will be an array ref, which I will
    completely dereference.

    There's nothing unique about this new syntax other than the syntax itself.
    What it's doing is exactly what we did with everything else - take one value
    and extract something from it. From left to right. The @{...} syntax forces
    me to mentally go back to the beginning (or mentally note what's at the
    beginning) just to figure out what's going on.

    Generally, I've avoided that syntax. I find it too unwieldy. I end up using
    more temporary variables just to avoid the braces.
    What we've just set up is the filling of the holes left in the current
    incomplete postfix dereference syntax, which allows only scalar element
    accesses.
    Unbiased opinion: I do not doubt it fits in somewhere, my question was
    whether it is worth the efforts given that it seems to add to
    implementation and maintenance complexity, and potential user confusion.
    That's a fair question. I think it's worth a lot, but I'm not the one eating
    the complexity, I'm consuming its sugar.
    Personal opinion: Since we have $aref->[1], $aref->[] makes sense to
    mean the whole array. Likewise, $href->{foo}, $href->{}. But all other
    examples I've seen of postfix dereference syntax seem rather contrived
    to me. Why would you ever write $$foo->$* instead of $$$foo or ${$$foo}?
    Again, when you simplify the LHS to a single variable, none of this makes any
    difference. It's only when the LHS is something complex that this makes
    sense. And it makes even more sense when we have conditional dereferencing:

    $foo->?{bar}->?baz(27, flurg => gnar_now())->?[4]->?@*

    If $foo is not a hash ref, return undef. Otherwise grab the value associated
    with its bar key. If that's not an object, return undef. Otherwise call its
    baz method. If that doesn't return an array ref, return undef. Otherwise
    grab its fifth element. If that's not an array ref, return undef. Otherwise
    dereference it.

    Compare to:

    @{$foo->?{bar}->?baz(27, flurg => gnar_now())->?[4]}

    If anything inside the braces fail, it returns undef, and gets derefenced.
    Instant death. Maybe there'd have to be:

    @?{$foo->?{bar}->?baz(27, flurg => gnar_now())->?[4]}

    just to get the same end.
    How often would you need $foo->\*? blah->&*?
    Personally, I almost never use the prefix form of these, so I'm not sure I'd
    use the postfix form, either. However, again, when you have a hash of objects
    whose baz methods return array refs of code refs, then having the ->&* bit at
    the end may come in handy.
  • Demerphq at Aug 15, 2013 at 5:05 pm

    On 15 August 2013 18:12, Darin McBride wrote:
    The @{...} syntax forces
    me to mentally go back to the beginning (or mentally note what's at the
    beginning) just to figure out what's going on.
    I could turn your argument on its head. When I am assigning I want the
    type of return (scalar or list) to be as close to the assignment
    operator as possible so it is obvious what is being returned from the
    expression (a list or a scalar). If the @* is at the end of the line,
    then it is as far as possible from the place I will be looking at.
    Now, you could argue that

       $foo->@* = (1,2,3,4);

    puts the @* in the right place, and that

       @{$foo} = (1,2,3,4);

    puts the @ in the wrong place (at the start of the expression) instead
    of next to the assignment operator.

    But you could equally argue that

       $thing= @$foo;

    puts the @ in the right place, and that

       $thing= $foo->@*;

    puts it in the wrong place.

    My point with this is any argument about the "rightness" of the @
    being at one end of the expression or the other will fall down in as
    many places as it stands up, and if I switch which end, ill reverse
    the places where it falls down or stands up. So there is no right
    answer here. Sometimes a postfix operator would make more sense than a
    prefix operator sometimes not. (It has not escaped me that this is
    decent argument for allowing both forms.)

    This aside I think there is a real problem with this proposal. It
    breaks the original model of sigils completely. IMO sigils are hard
    enough that completely breaking the original intent is not helpful, no
    matter how sweet your tooth is for the syntactic sugar it offers.

    My understanding of the Perl5 sigils is that they are meant to denote
    the type of result that will be _returned_*.

    We write:

        $thing= $foo[1];

    and not

        $thing= @foo[1];

    because the former tells us we are getting back a scalar. The latter
    says we are getting back a list.

    From this point of view you could argue that the postfix form disrupts
    this pattern:

    my @things= $foo->@*;

    So, now, the $ no longer can be relied to refer to a "scalar", it
    might be a scalar, it might not.

    This IMO is a real stumbling block for this proposal. It break well
    established and documented expectations for what seems to be little
    benefit.

    cheers,
    Yves
    * I looked for documentation to back this up, and the best I could
    find was in perlfaq4. I suspect that it is better documented in one of
    the Perl books by Larry.

    perlfaq4: What is the difference between $array[1] and @array[1]?

    The difference is the sigil, that special character in front of the
    array name. The C<$> sigil means "exactly one item", while the C<@>
    sigil means "zero or more items". The C<$> gets you a single scalar,
    while the C<@> gets you a list.

    The confusion arises because people incorrectly assume that the sigil
    denotes the variable type.
  • Johan Vromans at Aug 15, 2013 at 6:11 pm

    demerphq writes:

    This aside I think there is a real problem with this proposal. It
    breaks the original model of sigils completely. IMO sigils are hard
    enough that completely breaking the original intent is not helpful, no
    matter how sweet your tooth is for the syntactic sugar it offers.

    My understanding of the Perl5 sigils is that they are meant to denote
    the type of result that will be _returned_*.

    We write:

    $thing= $foo[1];

    and not

    $thing= @foo[1];

    because the former tells us we are getting back a scalar. The latter
    says we are getting back a list.
    [...]
    * I looked for documentation to back this up, and the best I could
    find was in perlfaq4. I suspect that it is better documented in one of
    the Perl books by Larry.
    From the first Camel:

       You'll note that we didn't have to tell Perl what kind of variable
       $answer is. That's because the $ character itself tells Perl that
       $answer can hold a single value, which can be either a string or a
       number. We call this a scalar variable.

    Also:

       We use the $ in $ARRAY[SCALAR] to indicate that we are selecting a
       scalar value even though it's coming from an array that is named
       @ARRAY. That will be confusing to you until you discover that you can
       use @ in @ARRAY[LIST] as the notation for array slices, and you figure
       out that the $ or @ is controlling the context of the subscript.

    Camel I didn't mention sigils, it called them "funny characters":

       Some consider that having the variables all start with funny
       characters makes Perl an ugly language. [...]

    Camel IV was the first book to call them "sigils".

       Note that we do not have to be very specific about kind of variable
       $phrase is. The $ character tells Perl that phrase is a scalar
       variable, that is, one con- taining a singular value. An array
       variable, by contrast, would start with an @ character. [...] Perl has
       some other variable types, with unlikely names like “hash”, “handle”,
       and “typeglob”. Like scalars and arrays, these types of variables are
       also preceded by funny characters, commonly known as sigils.

    Also, from Camel IV:

       Array subscripts are enclosed in square brackets [like this], so if
       you want to select an individual array element, you would refer to it
       as $home[n], where n is the subscript (one less than the element
       number) you want. See the example that follows. Since the element you
       are dealing with is a scalar, you always precede it with a $.

    Note the last sentence. This is fundamental to Perl as we know it, and
    also one of the fundamental differences between Perl and Perl6.

    -- Johan

Related Discussions

People

Translate

site design / logo © 2021 Grokbase