Optional binding

1 view
Skip to first unread message

Luke Palmer

unread,
Mar 6, 2005, 4:13:09 AM3/6/05
to Language List
What is output:

sub foo($x, ?$y, *@z) {
say "x = $x; y = $y; z = @z[]";
}

my @a = (1,2,3);
foo($x, @a);

Thanks,
Luke

Brent 'Dax' Royal-Gordon

unread,
Mar 6, 2005, 5:17:21 AM3/6/05
to Luke Palmer, Language List
Luke Palmer <lu...@luqui.org> wrote:
> What is output:
>
> sub foo($x, ?$y, *@z) {
> say "x = $x; y = $y; z = @z[]";
> }
>
> my @a = (1,2,3);
> foo($x, @a);

IANALarry, but I'd think

x = ($x's value); y = 1 2 3; z =

The $y is implicitly typed Any, and Ref of Array (or maybe just Array)
is consistent with Any; hence $y receives \@a.

--
Brent 'Dax' Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker

"I used to have a life, but I liked mail-reading so much better."

Yuval Kogman

unread,
Mar 6, 2005, 8:03:08 PM3/6/05
to Luke Palmer, Language List
On Sun, Mar 06, 2005 at 02:13:09 -0700, Luke Palmer wrote:
> What is output:
>
> sub foo($x, ?$y, *@z) {
> say "x = $x; y = $y; z = @z[]";
> }
>
> my @a = (1,2,3);
> foo($x, @a);

And is

$a ==> foo $x;

The same?

--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &
/\ kung foo master: /me groks YAML like the grasshopper: neeyah!!!!!!

Larry Wall

unread,
Mar 7, 2005, 2:58:43 AM3/7/05
to Language List
On Sun, Mar 06, 2005 at 02:13:09AM -0700, Luke Palmer wrote:
: What is output:

:
: sub foo($x, ?$y, *@z) {
: say "x = $x; y = $y; z = @z[]";
: }
:
: my @a = (1,2,3);
: foo($x, @a);

I think it should say something like:

Use of undefined value at foo line 2
x = ; y = 1 2 3; z =

Optional parameters are greedy, and @a means \@a in a scalar context.

Larry

Larry Wall

unread,
Mar 7, 2005, 3:02:29 AM3/7/05
to Language List
On Mon, Mar 07, 2005 at 03:03:08AM +0200, Yuval Kogman wrote:

: On Sun, Mar 06, 2005 at 02:13:09 -0700, Luke Palmer wrote:
: > What is output:
: >
: > sub foo($x, ?$y, *@z) {
: > say "x = $x; y = $y; z = @z[]";
: > }
: >
: > my @a = (1,2,3);
: > foo($x, @a);
:
: And is
:
: $a ==> foo $x;
:
: The same?

Nope, that's part of why we came up with pipes in the first place,
You example (assuming you meant @a there) is equivalent to

foo($x, undef, @a);

or
foo $x <== @a;

or

foo $x, z => [@a]

Larry

Aldo Calpini

unread,
Mar 7, 2005, 11:36:08 AM3/7/05
to David Storrs, Language List
David Storrs wrote:
> Urk. I, for one, will definitely find this surprising. I would have
> expected:
>
> x = <whatever>; $y = 1; z = 2 3

to obtain what you have expected, you need to explicitly treat the array
as a list of values with the unary splat:

foo($x, *@a);

> But I suppose it's all a question of learning to love the Brave New
> World in which arrays are actually objects (sort of).

more to the point, arrays are automagically referenced in scalar context:

@a = @b; # same as perl5
$a = @b; # means $a = \@b in perl5
$a = *@b; # means $a = @b in perl5 (more or less)

another thing that may surprise you (it still surprises me, somehow):

sub bar($x, $y, $z) { ... }
# ^ note x is scalar here!

my @coords = (1.0, 3.0, 5.0);
bar(@coords); # wrong
# x => \@coords, y => undef, z => undef

bar(*@coords); # ok

but then, you could define:

multi sub bar($x, $y, $z) { ... }
multi sub bar(@coords is shape(3)) {
my($x, $y, $z) = @coords;
return bar($x, $y, $z);
}

bar(@coords); # ok now

cheers,
Aldo

David Storrs

unread,
Mar 7, 2005, 11:13:19 AM3/7/05
to Language List

Urk. I, for one, will definitely find this surprising. I would have
expected:

x = <whatever>; $y = 1; z = 2 3

But I suppose it's all a question of learning to love the Brave New


World in which arrays are actually objects (sort of).

--Dks

--
dst...@dstorrs.com

Larry Wall

unread,
Mar 7, 2005, 11:55:14 AM3/7/05
to Language List
On Mon, Mar 07, 2005 at 05:36:08PM +0100, Aldo Calpini wrote:
: but then, you could define:

:
: multi sub bar($x, $y, $z) { ... }
: multi sub bar(@coords is shape(3)) {
: my($x, $y, $z) = @coords;
: return bar($x, $y, $z);
: }
:
: bar(@coords); # ok now

Or, assuming you might want to generalize to N dimensions someday, just

sub bar (*@coords) {...}

and deal with it as in Perl 5 as a variadic list. I suppose one could say

sub bar (*@coords is shape(3)) {...}

and get checking on the argument count.

Larry

Larry Wall

unread,
Mar 7, 2005, 7:58:29 PM3/7/05
to Language List
On Mon, Mar 07, 2005 at 10:29:58PM +0100, Aldo Calpini wrote:
: Larry Wall wrote:
: >Or, assuming you might want to generalize to N dimensions someday, just

: >
: > sub bar (*@coords) {...}
: >
: >and deal with it as in Perl 5 as a variadic list. I suppose one could say
: >
: > sub bar (*@coords is shape(3)) {...}
: >
: >and get checking on the argument count.
:
: if I understand correctly, without using multi subs:
:
: sub bar(@coords is shape(3)) { ... }
:
: bar(@xyz); # ok
: bar( [$x, $y, $z] ); # ok
: bar($x, $y, $z); # compile-time error

Yes.

: while:
:
: sub bar(*@coords is shape(3)) { ... }
:
: bar(@xyz); # ok
: bar( [$x, $y, $z] ); # ok
: bar($x, $y, $z); # ok
: bar <== $x, $y, $z; # still ok
:
: am I right?

The second one might fail, I think. The declaration says that @coords
as a whole has shape(3), not each individual element. On the other
hand, if you interpret the shape size as a maximum and not an exact match,
then you could end up with a value of [[$x,$y$z],undef,undef], though
of course, that would fail if you had declared it to be an array of int.

In fact, we really haven't specified what happens when you say

my Int @a is shape(3) := [1,2];
my Int @b is shape(3) := [1,2,3,4];

A strict interpretation requires both to be errors, but I can warp my
brain around to thinking either or both is okay. The first is kinda
okay because @a[2] can represent undef, and the array as a whole
successfully holds the whole value. The second is kinda okay
because the @b presents a view into a portion of the bound value,
and there aren't any parts of it that map onto nothingness.

But I also have this nagging feeling that the user wouldn't have
specified shape(3) unless they actually meant it. The question is
what they meant. It could be argued that shape(3) is just a storage
directive saying that we'll emulate the more general array semantics
with 3 elements. But I suspect that in the typical case, they really
do want a 3-element vector, nothing more, nothing less.

Our notation doesn't differentiate those intents, however. Let's
assume the strict intent, and if a different strategy is intended with
looser binding semantics, we can always use a different trait name.
I think a strict interpretation of shape gives a lot more information
to the optimizer.

Larry

Larry Wall

unread,
Mar 7, 2005, 8:15:14 PM3/7/05
to Language List
On Mon, Mar 07, 2005 at 02:20:47PM -0800, David Storrs wrote:
: Yes, I know. That's what I meant by "...arrays are objects...(sort
: of)." They are objects in the sense that they are sort of references
: and sort of not and that they have behavior built into them
: (e.g. C<.length>). They won't actually have a class (I don't
: think...type Array is not the same as a hypothetical class Array,
: right?), but otherwise they quack awfully much like an object.

No, they're real objects. (Though it's .elems rather than .length, since
we've banished the "l" word from our vocabulary.)

: > another thing that may surprise you (it still surprises me, somehow):


: >
: > sub bar($x, $y, $z) { ... }
: > # ^ note x is scalar here!
: >
: > my @coords = (1.0, 3.0, 5.0);
: > bar(@coords); # wrong
: > # x => \@coords, y => undef, z => undef
: >
: > bar(*@coords); # ok

:
:
: Yep, I am pretty sure that's going to trip me up endlessly for the
: first 6 months or so.
:
:
: To be perfectly honest, there are steadily more things I don't like
: about the way Perl 6 is going, especially when it comes to signatures.
: They are excessively verbose, they lead to (what I think is, and what
: I suspect most Perl 5 programmers will think is) weird behavior like
: that described above, and the type system feels like a straitjacket.
: I know all these features are optional, but they WILL be used, which
: means I have to know them so that I can maintain other people's code.
: Essentially, it feels like we're turning our beautiful language into
: something that has all the fun of Java but without Sun's marketing
: budget.
:
:
: But, every time I find myself thinking these things I take a deep
: breath, put my faith in Larry, and assume that it will work out--I
: really do have an amazing degree of faith in his ability to pull off
: miracles. Hopefully, after I have a chance to play with the
: production version of P6 for a while, all of these things that
: currently seem like effluent will start to see like useful tools.

And I have put my faith in the Perl community, and assume it will work
out, because I have an amazing degree of faith in the ability of the
community to recognize the real effluent and avoid it. :-)

: Fingers crossed,

Niy ygsy ,sjra uy s ;py gsefre yp ytor///

:seet

David Storrs

unread,
Mar 7, 2005, 8:37:53 PM3/7/05
to Language List
On Mon, Mar 07, 2005 at 04:58:29PM -0800, Larry Wall wrote:
>
> In fact, we really haven't specified what happens when you say
>
> my Int @a is shape(3) := [1,2];
> my Int @b is shape(3) := [1,2,3,4];
>
[...]

> But I also have this nagging feeling that the user wouldn't have
> specified shape(3) unless they actually meant it. But I suspect

> that in the typical case, they really do want a 3-element vector,
> nothing more, nothing less.

I agree that this is undoubtedly what they meant. I wonder though, if
there is then any way to explicitly leave off an element. Can I do
this:

sub foo( Int @a is shape(3) ) { ... }
foo(1, 2, undef);


--Dks

--
dst...@dstorrs.com

David Storrs

unread,
Mar 7, 2005, 8:56:12 PM3/7/05
to Language List
On Mon, Mar 07, 2005 at 05:15:14PM -0800, Larry Wall wrote:
> On Mon, Mar 07, 2005 at 02:20:47PM -0800, David Storrs wrote:
> : Yes, I know. That's what I meant by "...arrays are objects...(sort
>
> No, they're real objects. (Though it's .elems rather than .length, since
> we've banished the "l" word from our vocabulary.)

Ah, ok. I've got to scrape up the tuits to go back and reread the
A&Es.

Actually, I guess they would have to be...can you apply a role to a
bare type?

my int does SelectOutputFile; # I would expect this to fail
my Int does SelectOutputFile; # I would expect this to work


> : But, every time I find myself thinking these things I take a deep
> : breath, put my faith in Larry, and assume that it will work out--I
> : really do have an amazing degree of faith in his ability to pull off
> : miracles. Hopefully, after I have a chance to play with the
> : production version of P6 for a while, all of these things that
> : currently seem like effluent will start to see like useful tools.
>
> And I have put my faith in the Perl community, and assume it will work
> out, because I have an amazing degree of faith in the ability of the
> community to recognize the real effluent and avoid it. :-)

I think I've just been very, very gently poked. :>

For the record--just because I personally dislike these things doesn't
make them bad, or even bad for the language. I didn't even say that
they WERE effluent, just that right now they seem that way to me
personally...and I'm trying to get past it. As I said, I'm confident
it will all work out well in the end.

>
> : Fingers crossed,
>
>Niy ygsy ,sjra uy s ;py gsefre yp ytor///
>
>:seet

At first I thought I had annoyed you enough that you were attempting
to summon an Elder God through my terminal. Then I realized that it
works out to:

But that makes it a lot harder to type...
Larry

Owie...stop making my head hurt! :>

--Dks

--
dst...@dstorrs.com

Larry Wall

unread,
Mar 7, 2005, 10:40:14 PM3/7/05
to Language List
On Mon, Mar 07, 2005 at 05:56:12PM -0800, David Storrs wrote:

: On Mon, Mar 07, 2005 at 05:15:14PM -0800, Larry Wall wrote:
: > On Mon, Mar 07, 2005 at 02:20:47PM -0800, David Storrs wrote:
: > : Yes, I know. That's what I meant by "...arrays are objects...(sort
: >
: > No, they're real objects. (Though it's .elems rather than .length, since
: > we've banished the "l" word from our vocabulary.)
:
: Ah, ok. I've got to scrape up the tuits to go back and reread the
: A&Es.

Bear in mind the As have [Update] sections but the Exegeses do not.
The Ss should be relatively up-to-date though.

: Actually, I guess they would have to be...can you apply a role to a


: bare type?
:
: my int does SelectOutputFile; # I would expect this to fail
: my Int does SelectOutputFile; # I would expect this to work

The latter always works. The former can probably be made to work in
the case of roles that only add methods and don't change the storage
representation, since the vtable is associated with the class and
not the object.

:seet, er, I mean, Larry

Larry Wall

unread,
Mar 7, 2005, 10:50:47 PM3/7/05
to Language List
On Mon, Mar 07, 2005 at 05:37:53PM -0800, David Storrs wrote:

That's illegal unless you either * the @a or [] the list. By itself an
@a declaration is always looking to bind a single parameter. Arguably,
1,2,undef could be interpreted as a single parameter, forcing the
scalar comma to auto-enreference a [1,2,undef] as it does when you say

$foo = (1,2,undef);

but then we lose argument count checking on any sig ending in an
array, and the meaning of comma subtly changes without warning at
a place other than the expected scalar/variadic boundary. So we
require splats to make that clear. I'd also note that

foo((1,2,undef))

would work in this case because parens in scalar context make all the args
into one arg. (In list context they would flatten, as they do in Perl 5.)
However, it's a lot clearer to say

foo([1,2,undef])

if that's what you mean.

Larry

David Storrs

unread,
Mar 7, 2005, 11:58:44 PM3/7/05
to Language List
On Mon, Mar 07, 2005 at 07:50:47PM -0800, Larry Wall wrote:
> On Mon, Mar 07, 2005 at 05:37:53PM -0800, David Storrs wrote:
> : On Mon, Mar 07, 2005 at 04:58:29PM -0800, Larry Wall wrote:
> : Is

> : there is then any way to explicitly leave off an element. Can I do
> : this:
> :
> : sub foo( Int @a is shape(3) ) { ... }
> : foo(1, 2, undef);
>
> That's illegal unless you either * the @a or [] the list.

Argh. My bad, I meant to * the @a. Ok, rewrite; is THIS legal?:

sub foo( Int *@a is shape(3) ) { ... }
foo(1, 2, undef);

The sense I'm trying to convey is:

"Here is my sub. It takes three ints."

"Here is me calling the sub. I am giving you only two ints and
explicitly telling you [by explicitly passing undef] that I meant
to do that so just take it and be quiet."

To put it another way...in perl5, a sub that was prototyped to take
three scalar args will throw an error when you pass only two but will
accept it if you pass two plus an explicit undef. On the other hand,
if it was prototyped to take an array there is no way to tell the
difference between an explicitly-passed undef and a too-short arg
list. How will P6 handle these two scenarios?

--Dks

Larry Wall

unread,
Mar 8, 2005, 2:17:36 AM3/8/05
to Language List
On Mon, Mar 07, 2005 at 08:58:44PM -0800, David Storrs wrote:
: Ok, rewrite; is THIS legal?:

:
: sub foo( Int *@a is shape(3) ) { ... }
: foo(1, 2, undef);

Yes, since Int can represent undef.

: The sense I'm trying to convey is:


:
: "Here is my sub. It takes three ints."
:
: "Here is me calling the sub. I am giving you only two ints and
: explicitly telling you [by explicitly passing undef] that I meant
: to do that so just take it and be quiet."
:
: To put it another way...in perl5, a sub that was prototyped to take
: three scalar args will throw an error when you pass only two but will
: accept it if you pass two plus an explicit undef. On the other hand,
: if it was prototyped to take an array there is no way to tell the
: difference between an explicitly-passed undef and a too-short arg
: list. How will P6 handle these two scenarios?

Could use "exists", maybe. Though for an array with shape(3)
it's possible that exists(@a[2]) is always true regardless of the
bound value. On the other hand, binding an array that is too short
is going to be a type mismatch, so you probably can't get into the
situation of a shaped array being too short to begin with. It'll
either fail immediately in the case of a normal sub, or it'll
go off looking for something else to MMD to that doesn't violate
any type constraints, and fail if it doesn't fine one.

Larry

Chromatic

unread,
Mar 8, 2005, 6:23:14 PM3/8/05
to Larry Wall, Language List

I could make the argument that it should be possible to decorate an
object with a role. If that means generating a new anonymous class just
to have a vtable to munge, so be it.

-- c

Larry Wall

unread,
Mar 8, 2005, 8:39:57 PM3/8/05
to Language List
On Tue, Mar 08, 2005 at 03:23:14PM -0800, chromatic wrote:
: I could make the argument that it should be possible to decorate an

: object with a role. If that means generating a new anonymous class just
: to have a vtable to munge, so be it.

Er, how is that different from what we already said? Object mixins are
the basis of our whole property system these days...

Larry

Chromatic

unread,
Mar 8, 2005, 8:49:54 PM3/8/05
to Larry Wall, Language List
On Tue, 2005-03-08 at 17:39 -0800, Larry Wall wrote:

> On Tue, Mar 08, 2005 at 03:23:14PM -0800, chromatic wrote:

> : I could make the argument that it should be possible to decorate an
> : object with a role. If that means generating a new anonymous class just
> : to have a vtable to munge, so be it.
>
> Er, how is that different from what we already said?

I didn't think it was, but this explanation used simple words that
didn't rely on me pretending to care about weird mathematics.

-- c

Larry Wall

unread,
Mar 9, 2005, 1:01:16 PM3/9/05
to Language List
On Tue, Mar 08, 2005 at 05:49:54PM -0800, chromatic wrote:

Well, okay, we're in violent agreement on that, but I was also trying
to answer the question about whether and when low-level types like
"int" behave as objects or not. And the basic answer is that they
do as long as you don't try to change their storage representation.
You probably aren't allowed to say

my bit @array is shape(10_000_000);
@array[42] = 1;
@array[42] does AddExtraAttributes;

since a low-level declaration is making certain representations to the
optimizer that would be likely be invalid if we suddenly promoted the
entire array to holding Bit instead of bit. People start getting a
little edgy when they make one function call and their process size
unexpectedly goes from 2 megs to 200 megs...

On the other hand, while I can see us decorating

my bit $maybe = 1;
$maybe does AddOnlyMethods;

it's also a little problematic (I almost said "a bit problematic") to
say:

my bit @array is shape(10_000_000);
@array[42] = 1;
@array[42] does AddOnlyMethods;

insofar as we'd have to decide whether to decorate the return type of the
entire array or not. So maybe we allow decoration of low-level types
only for entire containers. The above would be illegal, but this would not:

my bit @array is shape(10_000_000);
@array[42] = 1;
@array does AddOnlyMethods;

I'm just trying to strike a balance between practicality and purity here.

Larry

Reply all
Reply to author
Forward
0 new messages