Front page | perl.perl5.porters |
Postings from August 2009
Re: A complete design for := (bind)
Thread Previous
|
Thread Next
From:
Daniel Ruoso
Date:
August 21, 2009 08:48
Subject:
Re: A complete design for := (bind)
Message ID:
1250869805.3971.23.camel@cajueiro
Em Qui, 2009-08-20 às 22:44 -0700, Chip Salzenberg escreveu:
> Not long ago, I posted a patch that began implementing the ':=' bind
> (sometimes also called "alias") operator. That patch implemented the
> seemingly obvious cases:
> my $x := <any_scalar_value>;
> my @x := @any_array;
> my %y := %any_hash;
As someone who recently got a syntax error for inconscient use of := in
perl5 I very much like this idea ;)
> Subsequent discussion revealed that _list_ binding raised much more thorny
> language issues than the above. I asked Patrick Michaud how Perl 6 does it
> (FSVO "does"), and got this summary (paraphrased):
> The LHS of := must be a Signature object, and the RHS must be a Capture
> (whether the Capture is an object, I am not clear). The syntax of a Capture
> is C<\LIST>. There is some thought being given to making the syntax of
> Signatures C<:LIST>. Finally, the semantics of ":=" and function
> parameter binding are identical, except that parameters default to
> readonly while ":=" does not.
Let me try to help you there...
A Capture is an Object just because everything is an object in Perl 6,
so that not necessarly maps well on Perl 5, and it's probably a good
idea to consider the Capture an "abstract concept".
The syntax for a capture actually changed a bit, you don't need the
\LIST anymore. you can do a simple
my @a := 1,2,3
because 1,2,3 builds a Parcel which can be converted (and in this
specific case is, at compile time) to a Capture, which is then bound to
the array.
There is one problem, however, that you didn't take into account. Perl 6
has a very strong distinction between the value and the container. For
instance:
my $a = 1;
In Perl 5 that stores a Scalar value of 1 in the glob "a" of the current
lexpad.
In Perl 6, on the other hand, that stores a Scalar object in the entry
"$a" of the lexpad and stores the Integer 1 inside it's "cell".
That's a fundamental difference, because when you do
my $a := 1;
you're actually storing the Integer 1 directly inside the entry "$a" of
the lexpad, which means that when someone, later, tries to do:
$a = 2;
it will fail with "method STORE not implemented in Integer". but
probably something more clever as "cannot assign to a read-only value"
The same applies to lists...
my @a := 1,2,3;
In this case we're storing the Parcel into the entry '@a' of the lexpad,
which means that
@a.push(4)
will fail, because the Parcel is an immutable value.
Considering that in perl5, it's just an AV* stored in the lexpad anyway,
I'm not sure how much semantics it will be able to provide.
> :($a, @b, %c) := ...
This will expect three "positional" elements in the incoming Capture,
that's because Perl 6 provides the notion of "positional" vs "named"
arguments. OTOH...
> :($a, *@b, *%c) := ...
This will bind the first "positional" element of the capture to $a, the
rest of the positional elements to @b and all the "named" elements to %c
It would be super-cool to have named arguments in Perl 5, but I'm not
sure it's doable.
> :(@a, @b, @c) := (\@x, \@y, \@z);
Just to clarify... in Perl 6 that "\" is no longer required, lists don't
flatten immediatly so the bind will work just fine.
> WHAT ABOUT THE REALLY SIMPLE BIND SYNTAX THAT I ALREADY IMPLEMENTED?
> I see no need for it. It doesn't give us any substantial convenience; Occam
> suggests that it should go unless it can defend itself; and while binding
> will be very frequent, the explicit := operator will be quite rare. Saving a
> few parentheses isn't worth the effort.
As I said above, the bind syntax can't add much semantics to perl5
because it doesn't separate container from value, as Perl 6 does in
which case
my $a = 1; # and
my $a := 1;
would have the exact same meaning.
OTOH, there's one interesting use of bind that would make Perl 5 code
prettier...
my $a = 1;
my $b := $a;
$a = 2;
say $b; # 2
This would avoid the ugly glob manipulation syntax, and would already be
of interest, I think... It would probably make sense to warn
my $a := 1;
with "useless use of bind", since it would have no actual effect.
daniel
Thread Previous
|
Thread Next