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
On Sun, Mar 06, 2005 at 11:58:43PM -0800, Larry Wall wrote: > 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
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).
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
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.
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. :-)
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);
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:
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.
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: : > : > 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);
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
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?
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.
On Mon, 2005-03-07 at 19:40 -0800, Larry Wall wrote: > On Mon, Mar 07, 2005 at 05:56:12PM -0800, David Storrs wrote: > : 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.
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.
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...
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.
On Tue, Mar 08, 2005 at 05:49:54PM -0800, chromatic wrote:
: 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.
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.