The perversity of traditional Perl 5 dereferencing syntax

I wrote this article almost a year ago as part of an omnibus reply to a bunch of different posts from a perl5-porters thread. I never finished all parts of the reply and thus never sent this part either, but in contrast to the other parts of this stillborn mail, I think this one is worth reading. So asked Johan Vromans:

It still escapes me why @* was chosen instead of the much more logical []:

$h{a}[0]->[]

The reason is that there are a number of problems to solve with any new deref syntax:

  1. Backcompat. We’d like to be able to write slices in this new syntax, and $foo->[1,2,3] and $foo->{1,2,3} already mean something, even if neither of them useful.

  2. How do you generalise it to specify the type of slice once we have Ruslan’s hash slices? (I.e. e.g. %hash{'foo','bar'} will yield a list like ('foo', 1, 'bar', 1).)

  3. How do you generalise to other forms of (de)reference outside of just arrays and hashes?

The thing is that when combined with a slice, a deref actually doesn’t denote the type of the reference:

${ $foo }[       1       ]
${ $foo }{     'foo'     }
@{ $foo }[ 1, 2, 3, 4, 5 ]
@{ $foo }{ 'foo', 'quux' }
%{ $foo }[ 1, 2, 3, 4, 5 ]
%{ $foo }{ 'foo', 'quux' }

^        ^               ^
:        :.··············´
:        :
:        ` What type must the (input) *reference* be? (Array or hash?)
:
` What kind of *slice* (output) will be returned?
  (Single scalar, value list, or key/value list)?

It’s kinda perverse, i’n’it? The slice circumfix operator on the right denotes the type of the reference expected from the expression inside the braces on the left – while the deref prefix sigil on the left denotes the kind of slice produced from the index list expression inside the brackets on the right.

But then for types that cannot be sliced, there is no right side, so the sigil on the left implies both decisions:

${ $foo }
&{ $foo }
*{ $foo }
         ^
^        :
:        ` If nothing goes here…
:
`  …then this is both the type of reference expected
    and the type of value produced.

And the task is to invent syntax that holds up in all of those cases, or at least a cross-cutting subset of those cases.

I guess I can see why Larry jettisoned sigil variance in Perl 6!

But since we’re stuck with it in Perl 5, the post-deref syntax we got seems to be the best we could do.

About Aristotle

user-pic Waxing philosophical