Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

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

by LanX (Archbishop)
on Mar 25, 2016 at 18:47 UTC ( #1158791=note: print w/replies, xml ) Need Help??


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

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!

Replies are listed 'Best First'.
Re^3: Unifying namespaces of @name and $name to simplify dereferencing?
by Eily (Monsignor) on Mar 26, 2016 at 00:08 UTC

    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]

        I didn't think to have a block scoped switching of syntax, don't think this would be wise.
        That's block scoped the same way other pragmas are block scoped, if you want to use them on a whole file that's just fine, but if you want to be able to have a finer control over when the aliasing happens, (because you think the aliasing looks like you break the encapsulation on objects, or one of the two variables has magic that the other bypasses (once again, by magic I mostly mean ties) and you'd rather have a compile time than a run time bug) you should be able to.

        or @a should be an alias of @$a and always reflect the list form of wherever $a points.
        That's not possible, because this means that \@a would not have a constant value for the duration of the program. And you can't magic your way out of it because sometimes only the stringified ref is kept (as the key of a hash).

        As for your declaration proposition, I'll say that offering a better safety net is always a good idea. I've been bitten before because I absentmindedly used the wrong brackets for my type, like $var->{3} when really I was thinking about an array the whole time, but for some reason I confused the two, or my finger just went on typing the brackets they were told to use the X previous time in a row. So ++ for compile time types :).

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2019-11-17 11:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (86 votes). Check out past polls.

    Notices?