Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^4: Unifying namespaces of @name and $name to simplify dereferencing? (declaration of typed references)

by LanX (Archbishop)
on Mar 27, 2016 at 17:05 UTC ( #1158885=note: print w/replies, xml ) Need Help??


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

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]

  • Comment on Re^4: Unifying namespaces of @name and $name to simplify dereferencing? (declaration of typed references)
  • Select or Download Code

Replies are listed 'Best First'.
Re^5: Unifying namespaces of @name and $name to simplify dereferencing? (declaration of typed references)
by Eily (Monsignor) on Mar 27, 2016 at 20:20 UTC

    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 :).

      > That's not possible, because this means that \@a would not have a constant value for the duration of the program. 

      With a tied array it should be feasable to always access @$ref. ( well quite slow but good enough for a showcase.)

      > And you can't magic your way out of it 

      These variables are scoped and easy to identify (at least lexicals) you can just replace every @arr with @$are at compile time or in a macro substitution.

      >  because sometimes only the stringified ref is kept (as the key of a hash).

      I doubt that's documented or guaranteed behavior.

      At least with stash variables you are free to change the reference by aliasing.

      Just try *a=\@b; and see what \@a returns. :)

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

      update

      furthermore this allows changing the underlying reference.

      use 5.22.0; use feature qw/say refaliasing/; no warnings "experimental::refaliasing"; my @a=(1,2,3); my @b=(3,2,1); say \@a; \@a=\@b; say \@a;

        I doubt that's documented or guaranteed behavior.
        It's present in the Inside Out objects documentation at least. And the perlref doc states
        Using a reference as a string produces [...] the numeric address expressed in hex.
        Which is used to see if the two references refer to the same location. There's nothing that explictly states that a lexical variable will have a constant address for the duration of its scope though. And I didn't know that this was already broken by the experimental refaliasing, because I would expect that CPAN modules use constructs like process(@a) unless $processed{\@a}; which would break if the address is not constant. At least refaliasing makes it explicit that you are "overwriting the reference", because \@a=\@b; is not valid in "classic perl", so you're either going to guess what it does, or think it's a syntax error. Same goes with your declaration proposition. The declaration syntax wouldn't just be about type security, but rather about new features being a syntax error if used outside their scope.

        I didn't mention globs because while they make it easy to have an array always be the thing a references refers to, they can't be used with lexicals alone. Once again though, this was for lack of knowledge that aliasing is possible between lexicals. I now know that your proposition can be implemented (or at least emulated) using existing features.

        I still like $array being read-only better though, because it would make it possible to have a reference bound to your array for ease of use, without the side effects, or even misleading perl newcomers into believing that $array = [1..3]; overwrites the values of the array instead of creating a brand new one.

        Edit: tr/$/&/ in html escape :)

      > So ++ for compile time types :).

      And do you think this would improve the usability of Perl for beginners? (I do)

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

        Could rather than would. I'm sure a significant portion of them would avoid a syntax that looks like additional effort (because who doesn't know that error messages are more effort than debugging blindly and getting confusing behaviour?) as they already avoid strict which is just one line and not "extra noise".

Log In?
Username:
Password:

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

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



    Results (80 votes). Check out past polls.

    Notices?