develooper Front page | perl.perl5.porters | Postings from June 2009

language design of := operator for Perl 5

Thread Next
From:
Chip Salzenberg
Date:
June 28, 2009 14:43
Subject:
language design of := operator for Perl 5
Message ID:
20090628214322.GF26701@tytlal.topaz.cx
Background:

    Perl 5.12 needs good function signatures.  'Good' to me implies the ability to
    do all that Perl6::Subs does, plus aliasing.  It also implies an implementation
    more elegant than either Perl6::Subs or Devel::Declare.  (Although the plugin
    model of Devel::Declare is a promising  if the core can reduce the kludge level
    required.)
    
    Aliases come in two flavors: writeable, and read-only (a.k.a. "views", my
    term).  I've already got done about half of the core work for view support.

    Latest news: my view patch ("SVt_BIND" type support) turns out not to break
    anything in existing Perl.  So that's promising.

When we introduce aliasing support, we don't want to make it available only in
function signatures; people will end up writing little functions just to establish
aliases, and that's goofy.  And a calling to an XS module is not acceptable because
we don't want to impose that penalty on every other function call that happens to
use parameters.

Perl 6 solves this by allowing all of the feautures of a function signature to be
used anywhere in the code, on the left side of a := (bind) oeprator.  Attempting to
mimic Perl 6 signatures slavishly would be doo out of place in a Perl 5 program,
but of course it would be stupid to be different for no reason; when something is
like Perl 6 it wouldn't hurt to look like Perl 6 if that works out, but still it
must fit naturally into Perl 5.

NOTE: I TOTALLY DO want to make mutable grammar practical for Perl 5 coders, and
there are several projects to help with that, such as Larry's recent work.  But
Perl 5.12 really needs a workable aliasing syntax, and we don't want to gate the
basic ability to name function parameters in a standard way (!! (!!!!)) on the
introdution of a deep and difficult feature like mutable grammars.


THE REACTIONARY PATH: STANDARD NAMED OPERATORS

This has the advantage of working the most like Perl 5, not requiring any
really new syntax (well almost none), and still providing most of the
features.  For example:

   use features qw(alias view);
   ...
   aliss $a, $b;          # $a++ modifies $b;             \$a == \$b
   aliss $a, view($b);    # $a++ throws an exception      \$a == \$b
   alias @a, @b;          # push(@a...) modifies @b;      \@a == \@b
   alias @a, view(@b);    # push(@a...) throws exception; \@a == \@b
   alias %a, %b;          # $a{foo}++ modifies $b{foo};   \%a == \%b
   alias %a, view(%b);    # $a{foo}++ throws exception;   \%a == \%b

MISSING FEATURES:

 1. This syntax doesn't lend itself well to mass operations because list
    operators only take one list, not two.  This is the primary problem with
    this approach.  I suppose we could do alternation, but then we would have
    a hard time expressing mass aliasing.

 2. Do we want one opcode per aliased parameter on every function call?  It
    may be cheaper than what we have now but it's not very good.

 3. Compactness.  Hey, this is Perl, that counts for something (if only a little).


THE REVOLUTIONARY PATH: A NEW OPERATOR := MODELED ON PERL 6

   use features qw(view);

   $a := $b;       # $a++ modifies $b;             \$a == \$b
   $a := view($b); # $a++ throws an exception      \$a == \$b
   @a := @b;       # push(@a...) modifies @b;      \@a == \@b
   @a := view(@b); # push(@a...) throws exception; \@a == \@b
   %a := %b;       # $a{foo}++ modifies $b{foo};   \%a == \%b
   %a := view(%b); # $a{foo}++ throws exception;   \%a == \%b


2(a): HOW TO INDICATE READ-ONLY ALIASING

I'd like a better syntax than view() but Perl 5 doesn't allow attributes on
arbitrary expressions, and the Perl 6 "is" syntax seems a bit foreign:

   $a is ro := $b; # PERL6 ONLY; I think, if I spelled it right

I'm open to a suggestion that doesn't do violence to Perl5 syntax.  I suppose we
could extend attribute syntax so it's available in other expressions, but colons
have other uses; introducing random ":foo" into expressions will at the very least
require extra parenthesizing, which is bad news in Perl 5 where parens can be
semantically important.

Maybe the "is" syntax, with some adjustments for the Perl 5 dialect, is the best
choice after all...


2(b): LIST ALIASING

List aliasing with := presents some interesting challenges.

Easy:
   ($a,$b) := ($c, view($d));  # $a is mutable $c, $b is immutable $d

Hard:
   ($a,@b) := @_;        #<<<<<<<<<<<<<<<<<<<< DANGER WILL ROBINSON

Observe: Now that we're doing aliasing we have a problem with the automatic Perl 5
flattening of arrays into lists.  What we really want is the Perl6 distinction
between @foo and *@foo, i.e. a flatten operator.  But in Perl5 flattening is the
default.  So we need an unflatten operator.  In the specific case of aliasing, I
think we can use \ for that.  It's cheating a bit, but I think it will work, and my
shame-o-meter is only twitching a little.

We definitely want this case to work:

   ($a,$b,@c) := @_;  # $a aliases $_[0], $b aliases $_[1], @c aliases @_[2 .. $#_]

So I suggest these also work:

   ($a,@b,@c) := ($x, @y, @z)  # $a aliases $x, @b aliases (@y[0..$#y], @z[0..$#z]), @c is empty
   ($a,@b,@c) := ($x,\@y,\@z)  # $a aliases $x, @b aliases @y, @c aliases @z



-- 
Chip Salzenberg

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About