Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Unifying namespaces of @name and $name to simplify dereferencing?

by Eily (Monsignor)
on Mar 22, 2016 at 13:49 UTC ( [id://1158495]=note: print w/replies, xml ) Need Help??


in reply to Unifying namespaces of @name and $name to simplify dereferencing?

There would be a collision issue if you had both a hash and an array with the same name, but since this happens mostly because of a bad coding style, or as a mistake, I suppose that's only half an issue. And you could always overload the operators to make your scalar act like a reference to any other type.

In the end, your proposition is just a trick to emulate the sigil invariance of perl 6 isn't it? That's the main issue I think. It would make people coming from other languages (php would definitely be an issue) think they understand what's happening when you write my $array = ["Hello", "World"]; print $array[0];. And it would hide away most notions of list from perl because you could work with a subset of the language that only handles scalars, without any indication in the syntax that thing are not what they seem. If people coming to perl from other languages start using that feature because it makes perl "act normal", the @ sigil would mostly be understood as giving the size of the array, with bugs sometimes appearing when people use it in list context without understanding what list context is.

Maybe if the scalar associated with @array was $array_ref, or some other change that makes it clear that $array[0] is not just a shortcut for $array->[0] that would be OK, but then maybe the extra -> isn't too much pain. And even then I think associating variable on an individual basis instead of an automatic one would be better, bind (my $array_ref => my @array); if my @array; my $array_ref = \@array; is too cumbersome for you (I tried, bind my ($array_ref => @array) doesn't work with prototypes).

Edit: turned my nearly one-paragraph-long sentence into multiple ones, mostly by adding dots :)

Replies are listed 'Best First'.
Re^2: Unifying namespaces of @name and $name to simplify dereferencing?
by LanX (Saint) on Mar 25, 2016 at 18:47 UTC
    Hello Eily,

    Thanks for meditating! =)

    > There would be a collision issue if you had both a hash and an array with the same name,

    well already an immediate compile time error, just take the first two lines of Tux suggestion:

    use feature 'autoref'; my %name; my @name;

    translated to

    my %name; my $name = \%name; my @name; my $name = \@name; # <- compile time error

    and even if my $name = \%name; comes from an upper scope, one could think about emitting a warning after defining my @name in a lower scope.

    (But yes we would have overlaps from all namespaces, the title of this thread is too simplistic.)

    > In the end, your proposition is just a trick to emulate the sigil invariance of perl 6 isn't it?

    not really, it's another way to address the same question, but I'm looking for a way which does less sacrifices to Perl5 mechanisms like context and could be easily implemented.

    Perl6 does not only a complete break to backwards compatibility, but has to redesign context and other stuff completely.

    > think they understand what's happening when you write my $array = ["Hello", "World"]; print $array[0];

    well if $array is an alias of \@array they would not only think to understand what is happening, the knew what is happening, because $array[0] and $array->[0] would do the exactly same thing.

    > with bugs sometimes appearing when people use it in list context without understanding what list context is.

    I'm not trying to eliminate list context, one would still need to understand what @arr = (@arr1,@arr2) does.

    But yes,it would be much easier for beginners before getting there (e.g. when coming from JS)

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      I'm not trying to eliminate list context
      Well yes, that's not something I would suspect of you anyway ;-).

      I actually didn't think the my $array = ["Hello", "World"]; print $array[0]; example through. It might work here because of the my, which means that $array isn't already linked to another array. But if you want to redefine the content of the array without breaking the link you have to write @array = (1..4);. Because $array = [1..4]; would link $array to a brand new array, or not be consistent with "normal perl" (and $ar = $br would either alias @ar to @br, or not lead to $ar == $br, or make $ar != \@ar). So in the end you're right, this doesn't make it easy to just pretend the @ sigil doesn't exist, and this doesn't work like the perl6 sigil invariance at all. I suppose it's fine if the option is scoped correctly :

      my @outer; my $otter = [1..4]; { use autorefs; my $inner = [1..10]; print $inner[5]; # Neither $outer nor $otter[0] are legal } # @inner is obviously not allowed here

      I haven't worked much with perl6, just done a few tests and mostly read about it. I'm sure the subject must have been covered many times but your meditation just made me realize the point of keeping the @ sigil when $a = 1..4; $a[0] and @a = 1..4; @a[0]; do the same thing, and what it changed for @a to be an array and $a to be an array ref if both where just going to be passed as a single argument anyway. That's because @a = 1..4; @b = @a is "equivalent" to $a = 1..4; @b = $a (@b is a clone of the array a) but not to $a = 1..4; $b = $a; or even @a = 1..4; $b = @a ($b is a ref to the array a).

        Hi

        Hmm ... you are bringing some new aspects in, like mixing old and new syntax, instead of switching it globally for the whole file with a use feature right after use strict .

        I didn't think to have a block scoped switching of syntax, don't think this would be wise.

        (and I'm no expert of Perl6 variable syntax, I only know that plenty of stuff must change as a consequence)

        Then it obvious now that @a and $a=\@a can't be automatically combined without braking some "traditions".

        • Either $a has to be readonly, because the reference of @a is normally guaranteed to be immutable for it's lifespan.
        • or @a should be an alias of @$a and always reflect the list form of wherever $a points.
        (see also here )

        I think the latter is what people rather accept.

        Now if mixing with old code is the goal, I'd suggest a new declaration syntax for typed references by adding parens (additionally to untyped scalars)

        my $arr[] = [42,43,44]; # "typed" array ref #--- effects print $arr[0]; # => 42 (same as $arr->[0]) print $arr; # => ARRAY(0x8f4c214) print "@arr"; # => "42 43 44" (same as "@$arr") print "@arr[0,2]"; # => "41 43" (slice) #--- caught Errors (compile time): my @arr; ## @arr masks earlier declaration in same scop +e my $arr; ## $arr masks earlier declaration in same scop +e my $arr{} ## $arr{} masks earlier declaration in same sc +ope
        This "typing" references wouldn't not only facilitate syntax (by restricting the name space) but also add a lot of compile time checking.

        for instance the following is only a run time error at the moment which could be avoided otherwise at compile time.¹

        my $a_ref = [1,2,3]; # old style $a_ref->{x}; ## Not a HASH reference (run time)

        Furthermore did I follow Damian's naming convention here to mark a reference with a trailing _ref , to clearly indicate references to avoid typos, (albeit his convention doesn't distinguish types, that's why I personally prepend a_ to identifiers of arefs)

        BUT if we had such typed references we could delegate this marking (which is a poor man's form of typing! ) to the syntax highlighting of the IDE after declaration in a scope and lazily avoid adding all those markers.²

        Nota bene, the old syntax of my ($scalar, @array) wouldn't be effected and could be easily mixed

        The my ($arr[], $hash{}, $code() ) syntax is of course debatable... am open for better ideas.

        What do you think?

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

        footnotes
        ¹) and compile time means almost immidiately for users of "flymake-mode" in emacs or komodo.

        ²) emacs already supports different styles ("cperl-...-faces") for arrays, hashes and barewords

        UPDATE

        the difference to the original suggestion is that it doesn't facilitate/change the use of the classical @a=(1,2,3) or $a=[1,2,3] but blends in with new syntax. (in other words easier for Perl cracks but less comfortable for beginners)

        Since $scalars are all purpose variables it might be acceptable to still insist that references of untyped scalars are followed by a deref -> operator (?)

        Cause if a $var could hold any reference, then the extra typing of -> could make this obvious like in $var->{x} vs $var->[1]

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1158495]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-19 19:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found