A12 - Protected Attributes and Methods
Apocalypse 12 was very clear about the difference between private and public class members, but it didn't say anything about protected ones? How can you define a protected member? Do you have to do the following? has $.foo is protected; method bar() is protected; Maybe we could have another secondary sigil to mark a protected method or attribute. I'd suggest the semicolon, but I'm afraid it would cause havoc with the parser. Joe Gottman
Re: A12: default accessors and encapsulation
On Mon, Apr 19, 2004 at 06:53:29PM -0400, John Siracusa wrote: : Yeah, that's exactly what I don't want to type over and over :) I really don't understand what you're getting at here. First you complain that you'd rather write an ordinary method, and then you complain that you have to. Have I met someone lazier than me? :-) Larry
Re: A12: Required Named Parameters Strike Back!
John Siracusa asked: Well, actually, we saved you last summer when we decided to make + mean that the parameter must be named. ...named and required, or named and optional? Named and optional, by default. IOW, is this all true? sub foo(+$a, +$b) { ... } foo(); # compile-time error! No. foo(1, 2); # compile-time error! Yes. foo(a => 1, 2); # compile-time error! Yes. foo(a => 1);# compile-time error! No. foo(a => 5, b => 7); # ok foo(b => 1, a => 2); # ok Yes. Yes. You want: sub foo(+$a is required, +$b is required) { ... } Damian
Re: A12: Required Named Parameters Strike Back!
On Mon, Apr 19, 2004 at 01:44:53PM -0400, John Siracusa wrote: : On 4/19/04 1:30 PM, Larry Wall wrote: : > On Mon, Apr 19, 2004 at 01:14:57PM -0400, John Siracusa wrote: : > : I know we are running out of special characters, but I really, really think : > : that required named parameters are a natural fit for many common APIs. A12 : > : has reinforced that belief. Save me, Dami-Wan Wallnobi, you're my only : > : hope... : > : > Well, actually, we saved you last summer when we decided to make + : > mean that the parameter must be named. : : ...named and required, or named and optional? IOW, is this all true? : : sub foo(+$a, +$b) { ... } : : foo(); # compile-time error! : foo(1, 2); # compile-time error! : foo(a => 1, 2); # compile-time error! : foo(a => 1);# compile-time error! : : foo(a => 5, b => 7); # ok : foo(b => 1, a => 2); # ok Well, no, we're still stuck at run-time validation of that. In the case of methods you can't really do anything else anyway, generally speaking. For subs, we could make the compiler pay attention to something in the declaration: sub foo(+$a is req, +$b is req) { ... } sub foo(+$a = fail, +$b = fail) { ... } But I still don't think it rates a strange character of its own. Possibly there's something going on with multi subs and invocants. I'm not sure what 6.0.0 will make of a declaration like: multi sub foo(+$a, +$b: +$c) { ... } since we've told the Parrot people they don't have to worry about anything but positional parameters for 6.0.0. But none of this has much bearing on BUILD routines, which are shielded from positional semantics anyway by the fact that .bless() doesn't take any extra positional parameters. Larry
Re: backticks (or slash, maybe)
Sean O'Rourke wrote: > I'm saying "division" is now defined such that when the numerator is > a hash(-ref), the result is the set of values associated with the > denominator. I've never tried to divide a hash or hashref by > something without it being a bug. Right...in Perl 5. In Perl 6, a hash in a numeric context returns the number of entries it contains. So I can readily imagine: sub decimate_hash (%hash is rw) { for 1..%hash/10 { delete %hash{ pick any(keys %hash) }; } } Damian
Re: A12: default accessors and encapsulation
John Siracusa wrote: > I'd either like a way to more cleanly extend the default accessor's > assignment behavior down the road (i.e. by just writing a new name() method, > not by hacking away at STORE traits and adding private worker subs) or a way > to auto-generate the slightly more "boring" default accessor shown above. There *is* a way to do the latter. In A12, Larry implies that the declarators in the body of a class definition are actually method calls on an instance of MetaClass: http://www.perl.com/pub/a/2004/04/16/a12.html?page=3#use_of_classes http://www.perl.com/pub/a/2004/04/16/a12.html?page=19#new_grammatical_categories So, presumably, by defining a new C, you would be able to override the default accessor-generating behaviour. The least scary way to do this would be to encapsulate it in a trait that is applied to (and has its way with ;- the class declaration: class Dog is getset { has $.name is rw; ... } or perhaps is applied instead to individual attribute declarations: class Dog { has $.name is getset; ... } Alternatively, you could just *cheat* and define a macro (putting it in a lexically-scoped module for convenience and safety): module GetSet; macro getset is export(:MANDATORY) is parsed(rx:words/ ? /) ($attr) { my $accessor = substr $attr{attr_var}, 2; return "method set_$accessor ($attr{type} $attr{$attr_var}) {} " ~ "method get_$accessor () { return $attr{attr_var} } " ~ "has $attr{type} $attr{attr_var}" ; } and then: class Dog { use GetSet; getset $.name; ... } Damian
Re: A12: default accessors and encapsulation
John Siracusa writes: > On 4/19/04 3:58 PM, Austin Hastings wrote: > >> I initially decide to accept the default accessors. > >> > >> $dog.name = 'Ralph'; > >> print $dog.age; > >> > >> This works well for a while, but then I decide to update Dog so that setting > >> the name also sets the gender. > >> > >> $dog.name = 'Susie'; # also sets $dog.gender to 'female' > >> > >> How do I write such a name() method? > > > > has $.name is rw > > will STORE { .set_name($^name); }; > > The "will STORE" stuff covers the easy cases, but can I extend it all the > way up to a name() that's a multimethod with a ton of optional args? I > supposed you can (technically) do all of that with "will STORE", but it > seems an odd place for what would more naturally be code in the name() > method itself. I think a role on the attribute is not the right place to put it. What you're doing is returning a proxy object that knows how to set both the name and the gender. Here are a couple of implementations: class Dog { has $.name; has $.gender; method name() { return my $dummy is Proxy( for => $.name, STORE => sub ($in) { $.gender = // ?? 'male' :: 'female'; $.name = $in; }, ); } } Yuck. Much nicer: class Dog { has $.name; has $.gender; method name() will get { $.name } will set -> $in { $.gender = // ?? 'make' :: 'female'; $.name = $in; } { } } This is nothing new. So, for fun, here's the implementation of C and C: role get { multi sub trait_auxiliary:is(get $trait, &code: ?$arg) { wrap &code: { my $result := call; return my $dummy is Proxy( for => $result, FETCH => $arg, ); }; } } role set { multi sub trait_auxiliary:is(set $trair, &code: ?$arg) { wrap &code: { my $result := call; return my $dummy is Proxy( for => $result, STORE => $arg, ); }; } } Luke
Re: A12: default accessors and encapsulation
On 4/19/04 4:47 PM, [EMAIL PROTECTED] wrote: >> On 4/19/04 3:58 PM, Austin Hastings wrote: >> One work-around might be an alternate kind of default accessor that doesn't >> allow assignment: >> >> $dog.name # get >> $dog.name('foo') # set >> $dog.name = 'foo' # compile-time error > > I think we already have this. Just define a non-rw attribute and then > add your own writer as a multi-method. > > has Str $.name; > multi method name(Str $n) {$.name = $n;} Yeah, that's exactly what I don't want to type over and over :) It's not much better than the old Perl 5 standby: sub name { @_ > 1 ? $_[0]->{'name'} = $_[1] : $_[0]->{'name'} } since once I have to write something, the time and effort savings is pretty much cancelled out. -John
Re: backticks (or slash, maybe)
Sean O'Rourke skribis 2004-04-19 15:34 (-0700): > I'm saying "division" is now defined such that when the numerator is > a hash(-ref), the result is the set of values associated with the > denominator. I've never tried to divide a hash or hashref by > something without it being a bug. I understand now. But that means the meaning of the / is unknown until runtime, which means $foo/0 can't be a compile time error. And it doesn't quote the thing after it, which means still doing a lot of typing. $foo/bar should be a compile time error (Perl 6 has no barewords) if $foo is not a hashref, but be $foo{'bar'} if it is. Waiting for runtime is bad, I think. > /foo/ # trailing slash -- so it's a regexp (m/foo/) > /foo\/bar/ # trailing slash -- syntax error (m/foo/ bar/) > /foo/a # hash-path -- no trailing slash ($_.{'foo'}{'a'}) > /foo\/bar # hash-path -- no trailing slash ($_.{'foo/bar'}) > /foo\/ # hash-path -- no trailing slash ($_.{'foo/'}) Thanks. Now I'm sure I don't like the bare path idea. After a hash, perhaps it's doable, and even "if -r /etc/passwd" is doable, but there are too many allowed characters in filenames (on my system: any character except \0 and /). Juerd
Re: backticks (or slash, maybe)
On Mon, Apr 19, 2004 at 03:34:13PM -0700, Sean O'Rourke wrote: in a '/' is a regex, anything otherwise is a hash slice. I don't understand. Could you give some examples? Is this in the context of bare /path/to/foo, even? /foo/ # trailing slash -- so it's a regexp (m/foo/) /foo\/bar/ # trailing slash -- syntax error (m/foo/ bar/) /foo/a # hash-path -- no trailing slash ($_.{'foo'}{'a'}) /foo\/bar # hash-path -- no trailing slash ($_.{'foo/bar'}) /foo\/ # hash-path -- no trailing slash ($_.{'foo/'}) I think this is highly ambiguous. $x = /foo * $bar/and +bar(); would that be: $x = m/foo* $bar/ && (+bar()); or $x = $_.{'foo'} * $bar.{'and'} + bar(); ? As much as I see the appeal of this syntax, the / is simply too heavily used already. -- Matthijs van Duin -- May the Forth be with you!
Re: backticks (or slash, maybe)
[EMAIL PROTECTED] (Juerd) writes: > Sean O'Rourke skribis 2004-04-19 15:11 (-0700): >> > I'd hate to give up dividing slash. It's one of the few operators that I >> > sometimes type without whitespace. Simple because 1/10 is good enough >> > and 1 / 10 is very wide. >> You can have both, though. > > But not in a way that makes $foo/$bar divide $foo by $bar, if $foo is a > hashref. I'm saying "division" is now defined such that when the numerator is a hash(-ref), the result is the set of values associated with the denominator. I've never tried to divide a hash or hashref by something without it being a bug. >> > That would mean giving up // for regexes (i.e. making the m >> > mandatory). >> Since modifiers have to be up front, and since hash slices won't have >> a trailing '/', I don't think there's any ambiguity -- anything ending >> in a '/' is a regex, anything otherwise is a hash slice. > > I don't understand. Could you give some examples? Is this in the context > of bare /path/to/foo, even? Sure: /foo/ # trailing slash -- so it's a regexp (m/foo/) /foo\/bar/ # trailing slash -- syntax error (m/foo/ bar/) /foo/a # hash-path -- no trailing slash ($_.{'foo'}{'a'}) /foo\/bar # hash-path -- no trailing slash ($_.{'foo/bar'}) /foo\/ # hash-path -- no trailing slash ($_.{'foo/'}) /s
Re: backticks (or slash, maybe)
Sean O'Rourke skribis 2004-04-19 15:11 (-0700): > > I'd hate to give up dividing slash. It's one of the few operators that I > > sometimes type without whitespace. Simple because 1/10 is good enough > > and 1 / 10 is very wide. > You can have both, though. But not in a way that makes $foo/$bar divide $foo by $bar, if $foo is a hashref. > > That would mean giving up // for regexes (i.e. making the m > > mandatory). > Since modifiers have to be up front, and since hash slices won't have > a trailing '/', I don't think there's any ambiguity -- anything ending > in a '/' is a regex, anything otherwise is a hash slice. I don't understand. Could you give some examples? Is this in the context of bare /path/to/foo, even? Juerd
Re: backticks (or slash, maybe)
[EMAIL PROTECTED] (Juerd) writes: > Angel Faus skribis 2004-04-19 22:43 (+0200): >> If we really need a ultra-huffman encoding for hash subscriptors, I >> have always dreamt of being able to do: >> %hash/key >> $hashref/foo/bar/baz/quux >> ... > > I'd hate to give up dividing slash. It's one of the few operators that I > sometimes type without whitespace. Simple because 1/10 is good enough > and 1 / 10 is very wide. You can have both, though. >>for /home/angel -> $file { > > That would mean giving up // for regexes (i.e. making the m > mandatory). Since modifiers have to be up front, and since hash slices won't have a trailing '/', I don't think there's any ambiguity -- anything ending in a '/' is a regex, anything otherwise is a hash slice. /s package DH; require Tie::Hash; @ISA = 'Tie::StdHash'; sub TIEHASH { return bless {}, 'DH'; } sub SCALAR { return shift; } sub STORE { my ($h, $k, $v) = @_; $h->{$k} = $v; } use overload '/' => sub { my ($x, $y, $rev) = @_; if (!$rev) { if (ref $y eq 'ARRAY') { return [EMAIL PROTECTED]@$y}]; } else { return $x->{$y}; } } else { return $y / keys %$x; } }; package main; my %h; tie %h, 'DH'; %h = qw(a 1 b 2 c 3); my $xs = %h / [qw(a c)]; print %h / 'a', "\n"; print "@$xs\n";
Re: backticks (or slash, maybe)
Angel Faus skribis 2004-04-19 22:43 (+0200): > If we really need a ultra-huffman encoding for hash subscriptors, I > have always dreamt of being able to do: > %hash/key > $hashref/foo/bar/baz/quux > ... I'd hate to give up dividing slash. It's one of the few operators that I sometimes type without whitespace. Simple because 1/10 is good enough and 1 / 10 is very wide. Other than that, I like it. But it isn't really doable. >%hash/{ some_func() } # dynamic key >%hash/«key1 key2» # hash slice >%hash/['key', 'key2'] # the same I think this is not a good idea. >* «a b» and ['a', 'b'] are always substitutable, ever Only because they are here, doesn't mean they are everywhere. > A xml library could make every node a tied hash, effectively embedding > a good portion of xpath within perl Hmm... If only the slash weren't used by something extremely important. >for /home/angel -> $file { That would mean giving up // for regexes (i.e. making the m mandatory). And I think having quotes for strings other than very simple ones (anything containing a / is not a simple string imho) is good for readability. Juerd
Re: backticks (or slash, maybe)
Miércoles 14 Abril 2004 14:18, Juerd wrote: > I propose to use ` as a simple hash subscriptor, as an alternative > to {} and <<>>. It would only be useable for \w+ keys or perhaps > -?\w+. As with methods, a simple "atomic" (term exists only in > perlreftut, afaix, but I don't know another word to describe a > simple scalar variable) scalar should be usable too. If we really need a ultra-huffman encoding for hash subscriptors, I have always dreamt of being able to do: %hash/key $hashref/foo/bar/baz/quux ... If only because of the filesystem analogy. Because a filesystem is really just a very big tied hash, isn't it? The idea would be be to replace the %hash{'key'} notation by the slash one, thus making {} always mean a closure without nothing to do with subscripting. It would work just like with methods so we would have: %hash/key # like $obj.method %hash/$key # like $obj.$method %hash/{ some_func() } # dynamic key %hash/«key1 key2» # hash slice %hash/['key', 'key2'] # the same The benefits I see in terms of clarity are: * {} means one thing (closure) and just one * « and » have only two meanings (literal array and hyperoperator) instead of three * «a b» and ['a', 'b'] are always substitutable, ever The cultural assumption of / as a subscripter is further reinforced with the omnipresence of xpath these days. We could play some tricks with this, too. A xml library could make every node a tied hash, effectively embedding a good portion of xpath within perl: my $price = $doc/books[14]/price; for $doc/books -> $book { print "Price is $book/price and title is $book/title"; } (scalar and array context with help us to overcome the "an xpath expression always returns a sequence syndrome") Pushing the analogy a bit too further away, one could hack the grammar so that a leading / does indicate the root directory in the system (and a leading ./ indicates the current directory), thus letting me write: for /home/angel -> $file { print $file; } Which looks cute for shell scripting, althought a bit dangerous maybe. And so on... The beauty (?) of this is not so much in that we should play these tricks, but in that we are reusing a good deal of cultural background in them. Oh, and saving a few keystrokes when you are dealing with hashes the whole day (say, because you are using DBI, or extracting some data from an XML document, or whatever) is not totally unpleasing. -angel
Re: A12: default accessors and encapsulation
On 4/19/04 3:58 PM, Austin Hastings wrote: >> I initially decide to accept the default accessors. >> >> $dog.name = 'Ralph'; >> print $dog.age; >> >> This works well for a while, but then I decide to update Dog so that setting >> the name also sets the gender. >> >> $dog.name = 'Susie'; # also sets $dog.gender to 'female' >> >> How do I write such a name() method? > > has $.name is rw > will STORE { .set_name($^name); }; The "will STORE" stuff covers the easy cases, but can I extend it all the way up to a name() that's a multimethod with a ton of optional args? I supposed you can (technically) do all of that with "will STORE", but it seems an odd place for what would more naturally be code in the name() method itself. > You can leave the "name" attribute around as a placeholder and let the STORE > block update the "official" location, or you could return some sort of > proxy-lvalue object that wasn't really a part of Dog Heh, getting progressively more scary :) >From the point of view of the person coding the new, fancier name() method, it would be nice if some magic would make all existing calls to $dog.name = 'foo'; look like this inside the new name() method $dog.name('foo'); but I supposed that really hoses the meaning of "=" :) The alternate techniques suggested are powerful, but they also strike me as slightly heroic. I can imaging using them to patch or extend some existing code, but starting a Perl 6 class from scratch, I'd really have to think about the costs of using the default accessors at all. One work-around might be an alternate kind of default accessor that doesn't allow assignment: $dog.name # get $dog.name('foo') # set $dog.name = 'foo' # compile-time error That is a lot more directly (and simply) "future-proof" than the "is rw" accessor. I'd either like a way to more cleanly extend the default accessor's assignment behavior down the road (i.e. by just writing a new name() method, not by hacking away at STORE traits and adding private worker subs) or a way to auto-generate the slightly more "boring" default accessor shown above. I'd prefer the former since I'm hoping to avoid the likes of Class::MethodMaker as long as possible in the world of Perl 6 :) In the absence of both, I can imaging that 5 years into the life of 6PAN, a substantial portion of the Perl 6 modules will have STORE hooks on what they originally thought would be "simple" attributes that don't need full-blown accessors... :) -John
RE: A12: default accessors and encapsulation
> -Original Message- > From: John Siracusa [mailto:[EMAIL PROTECTED] > Sent: Monday, 19 April, 2004 02:21 PM > To: Perl 6 Language > Subject: A12: default accessors and encapsulation > > > Let's say I have a class with some attributes: > > class Dog; > > has $.name is rw; > has $.age is rw; > has $.gender is rw; > > I initially decide to accept the default accessors. > > $dog.name = 'Ralph'; > print $dog.age; > > This works well for a while, but then I decide to update Dog so > that setting > the name also sets the gender. > > $dog.name = 'Susie'; # also sets $dog.gender to 'female' > > How do I write such a name() method? Do I just check the arg, set the > gender, and then return $.name as an "lvalue" or something? class Afghan is Dog { does Hunter; does AKC; has $.name is rw will STORE { .set_name($^name); }; has $.taliban is OppressiveGovernment; method set_name($self: String $name) { DESTROY unless $.taliban.approves($name); given ($name) { when { ... } ... } } } > > If so, what happens if, some time down the road, the $.name attribute goes > away entirely? I can't return it as an lvalue now, can I? method name(String ?$name) {...} > > Basically, I'm wondering how much of the object's internals I'm > exposing by accepting the default accessors. Since lvalue subs/methods are easy, and $obj.attr looks like $obj.method with no args, it should be pretty trivial to drop in a replacement if you decide you don't like the attribute-based solution. You are a little committed, since <$dog.name = "fred"> does assume that you've got a reference to something you can pass back, but that's about it. You can leave the "name" attribute around as a placeholder and let the STORE block update the "official" location, or you could return some sort of proxy-lvalue object that wasn't really a part of Dog: class WeaselDog is Dog { class PhonyAttr { $.store; $.fetch; method STORE { $.store($^value); return $_; } method FETCH { return $.fetch(); } } method set_name(String $name) {...} method get_name() {...} method name is rw { return new PhonyAttr( object => $_, store => { .set_name $^name; }, fetch => { .get_name; } ); } } =Austin
Re: A12: Naming Police - "P6opaque"
On 4/19/04 3:36 PM, Larry Wall wrote: > On Mon, Apr 19, 2004 at 02:04:55PM -0400, John Siracusa wrote: > : So, how about "Perl6opaque" (or "Perl6Opaque"), just to be safe :) > > How 'bout just "Opaque", meaning Parrot's native object type, or whatever > the native opaque type is for the platform in question. > > But I really don't care, as long as I have the 0 shortcut. I'm disappointed that you didn't suggest 0paque ;) I'm fine with Opaque too. I just object to needless (and possibly ambiguous) abbreviation. -John
Re: A12: Naming Police - "P6opaque"
On Mon, Apr 19, 2004 at 02:04:55PM -0400, John Siracusa wrote: : >From page 7: : : > In any event, strings are reserved for other object layouts. We could : > conceivably have things like: : > : >return $class.bless("Cstruct", *%_); : > : > So as it happens, 0 is short for the layout "P6opaque". : : I feel like "we" have pretty well staked out the letters p-e-r-l, but : anything else is still up for grabs. (I think I brought this up before on : the internals list regarding the PL_ prefix.) Well, this is all from the viewpoint of Perl anyway...it's probably an enum internally in any event, and any language can give the values any names they please. : The C language probably has a good claim on "C", Does that mean I can't use "Class". :-) : but I think it's unwise for : us try to squat on P\d+, especially when this is such a rare use (first arg : to bless) and three extra characters are not the end of the world. What : happens in 5 years when the super-popular "P6" language starts sweeping the : nation? Oops. Also, "Perl6" makes for better documentation than "P6". : : So, how about "Perl6opaque" (or "Perl6Opaque"), just to be safe :) How 'bout just "Opaque", meaning Parrot's native object type, or whatever the native opaque type is for the platform in question. But I really don't care, as long as I have the 0 shortcut. Larry
Re: Minor confusion
On Mon, Apr 19, 2004 at 01:02:36PM -0500, Jonathan Scott Duff wrote: : Quoting A12... : > Note that an attribute declaration of the form : > : > has Tail $wagger .= new(...) : > : > might not do what you want done when you want it done, if what you : > want done is to create a new Dog object each time an object is built. : > For that you'd have to say: : > : > has Tail $wagger = { .new(...) } : > : > or equivalently, : > : > has Tail $wagger will build { .new(...) } : : Since $wagger is meant to be an object attribute, shouldn't it have a : dot? And is omitting the dot an error? : : has Tail $.wagger = { .new(...) } # right? Yes, and yes. : Also, based on the earlier assertion that closure valued attributes : get the attribute as the topic, shouldn't the text say "to create a : new Tail object" rather than "Dog"? i.e., : : has Tail $.wagger = { .new(...) } # is the same as : has Tail $.wagger = { $.wagger.new(...) } : : which does some appropriate magic to call Tail.new because $.wagger : hasn't been initialized yet. Or is Tail also a Dog somehow? What happens : if the attribute is untyped? Presumably that's an error. Yes, it should have said "Tail". Larry
Re: A12: default accessors and encapsulation
John Siracusa skribis 2004-04-19 14:20 (-0400): > has $.gender is rw; > (...) > This works well for a while, but then I decide to update Dog so that setting > the name also sets the gender. > $dog.name = 'Susie'; # also sets $dog.gender to 'female' > How do I write such a name() method? Do I just check the arg, set the > gender, and then return $.name as an "lvalue" or something? IIRC, something like has $.name is rw is STORE { ... }; > If so, what happens if, some time down the road, the $.name attribute goes > away entirely? I can't return it as an lvalue now, can I? Why not? Juerd
A12: default accessors and encapsulation
Let's say I have a class with some attributes: class Dog; has $.name is rw; has $.age is rw; has $.gender is rw; I initially decide to accept the default accessors. $dog.name = 'Ralph'; print $dog.age; This works well for a while, but then I decide to update Dog so that setting the name also sets the gender. $dog.name = 'Susie'; # also sets $dog.gender to 'female' How do I write such a name() method? Do I just check the arg, set the gender, and then return $.name as an "lvalue" or something? If so, what happens if, some time down the road, the $.name attribute goes away entirely? I can't return it as an lvalue now, can I? Basically, I'm wondering how much of the object's internals I'm exposing by accepting the default accessors. -John
Re: A12: Required Named Parameters Strike Back!
At 1:50 PM -0400 4/19/04, John Siracusa wrote: On 4/19/04 1:41 PM, Dan Sugalski wrote: At 1:14 PM -0400 4/19/04, John Siracusa wrote: I know we are running out of special characters, but I really, really think that required named parameters are a natural fit for many common APIs. Well... maybe, but ponder a likely common case--automatically redelegated initialization methods with classes that have parents written in languages without named parameters. (Like, say, all the rest...) Then either make the order part of the API ("Sorry, we're using a C lib!") or provide "manual" delegation with an arg-ordering wrapper. Calling out to lesser languages is always bound to be crufty... ;) Um. Yeah. I think it's safe to say you're going to have positional args in core APIs for an awfully long time to come. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
A12: Naming Police - "P6opaque"
>From page 7: > In any event, strings are reserved for other object layouts. We could > conceivably have things like: > >return $class.bless("Cstruct", *%_); > > So as it happens, 0 is short for the layout "P6opaque". I feel like "we" have pretty well staked out the letters p-e-r-l, but anything else is still up for grabs. (I think I brought this up before on the internals list regarding the PL_ prefix.) The C language probably has a good claim on "C", but I think it's unwise for us try to squat on P\d+, especially when this is such a rare use (first arg to bless) and three extra characters are not the end of the world. What happens in 5 years when the super-popular "P6" language starts sweeping the nation? Oops. Also, "Perl6" makes for better documentation than "P6". So, how about "Perl6opaque" (or "Perl6Opaque"), just to be safe :) -John
Minor confusion
Quoting A12... > Note that an attribute declaration of the form > > has Tail $wagger .= new(...) > > might not do what you want done when you want it done, if what you > want done is to create a new Dog object each time an object is built. > For that you'd have to say: > > has Tail $wagger = { .new(...) } > > or equivalently, > > has Tail $wagger will build { .new(...) } Since $wagger is meant to be an object attribute, shouldn't it have a dot? And is omitting the dot an error? has Tail $.wagger = { .new(...) } # right? Also, based on the earlier assertion that closure valued attributes get the attribute as the topic, shouldn't the text say "to create a new Tail object" rather than "Dog"? i.e., has Tail $.wagger = { .new(...) } # is the same as has Tail $.wagger = { $.wagger.new(...) } which does some appropriate magic to call Tail.new because $.wagger hasn't been initialized yet. Or is Tail also a Dog somehow? What happens if the attribute is untyped? Presumably that's an error. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: A12: Required Named Parameters Strike Back!
On 4/19/04 1:41 PM, Dan Sugalski wrote: > At 1:14 PM -0400 4/19/04, John Siracusa wrote: >> I know we are running out of special characters, but I really, really think >> that required named parameters are a natural fit for many common APIs. > > Well... maybe, but ponder a likely common case--automatically > redelegated initialization methods with classes that have parents > written in languages without named parameters. (Like, say, all the > rest...) Then either make the order part of the API ("Sorry, we're using a C lib!") or provide "manual" delegation with an arg-ordering wrapper. Calling out to lesser languages is always bound to be crufty... ;) -John
Re: A12: Required Named Parameters Strike Back!
On Mon, Apr 19, 2004 at 10:30:18AM -0700, Larry Wall wrote: > On Mon, Apr 19, 2004 at 01:14:57PM -0400, John Siracusa wrote: > : I know we are running out of special characters, but I really, really think > : that required named parameters are a natural fit for many common APIs. A12 > : has reinforced that belief. Save me, Dami-Wan Wallnobi, you're my only > : hope... > > Well, actually, we saved you last summer when we decided to make + > mean that the parameter must be named. Except that last time I read, named parameters are always optional. So, if John wants perl to carp when any of the name, age, or id is unspecified, he's back to manually checking the parameters at run-time. Maybe that's a feature. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: A12: Required Named Parameters Strike Back!
On 4/19/04 1:30 PM, Larry Wall wrote: > On Mon, Apr 19, 2004 at 01:14:57PM -0400, John Siracusa wrote: > : I know we are running out of special characters, but I really, really think > : that required named parameters are a natural fit for many common APIs. A12 > : has reinforced that belief. Save me, Dami-Wan Wallnobi, you're my only > : hope... > > Well, actually, we saved you last summer when we decided to make + > mean that the parameter must be named. ...named and required, or named and optional? IOW, is this all true? sub foo(+$a, +$b) { ... } foo(); # compile-time error! foo(1, 2); # compile-time error! foo(a => 1, 2); # compile-time error! foo(a => 1);# compile-time error! foo(a => 5, b => 7); # ok foo(b => 1, a => 2); # ok -John
Re: A12: Required Named Parameters Strike Back!
At 1:14 PM -0400 4/19/04, John Siracusa wrote: I know we are running out of special characters, but I really, really think that required named parameters are a natural fit for many common APIs. Well... maybe, but ponder a likely common case--automatically redelegated initialization methods with classes that have parents written in languages without named parameters. (Like, say, all the rest...) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: A12: Required Named Parameters Strike Back!
On Mon, Apr 19, 2004 at 01:14:57PM -0400, John Siracusa wrote: : I know we are running out of special characters, but I really, really think : that required named parameters are a natural fit for many common APIs. A12 : has reinforced that belief. Save me, Dami-Wan Wallnobi, you're my only : hope... Well, actually, we saved you last summer when we decided to make + mean that the parameter must be named. Larry
Re: Apo 12
On Mon, Apr 19, 2004 at 01:19:36PM -0400, John Siracusa wrote: : On 4/19/04 11:11 AM, Larry Wall wrote: : > On Sat, Apr 17, 2004 at 01:12:58PM -0400, Austin Hastings wrote: : > : If it's not totally obvious to everyone, you should download a copy of A12 : > : (I like the "printer-friendly" all-in-one-page version) as a hedge against : > : the almost-inevitable slashdotting. : > : > Or not... : > : > Perhaps slashdot has decided they don't frontpage PhD dissertations. :-) : : Yeah, but did you see the story about that awesome new D language? It has a : native "dictionary" type! Hey, it supports C syntax, so maybe we could compile Parrot in it. :-) Larry
Re: placeholder attachment?
On Mon, Apr 19, 2004 at 09:42:14AM -0700, Dave Whipp wrote: : "Trey Harris" <[EMAIL PROTECTED]> wrote i : > It's easy to just say "don't nest placeholder-using closures," but that : > doesn't seem workable in practice since every block is a closure, unless : > placeholders are forbidden from all but the most trivial cases. Absurdly : > trivial, it seems. How about : > : > $sub = { if $^a { $^b = $^a } }; : : I would like to think that not all blocks have the same context. We could : define a "placeholder" scope as being a lexical scope that sends data to a : block. Thus C, C etc., all introduce lexical scopes that : are tagged as placeholder scopes; but C and C do not. Its a bit : like an inside-out-in-reverse C concept. We can certainly outlaw placeholders in scopes that already specify the argument list externally (including when there are no arguments for C et al.). But what we're *not* going to do is complexify the rules about which closure the placeholders try to bind to in the first place. Useless generalization is a really good place to trim the complexity of a language. And generalizing placeholders would be useless, in my estimation, particularly since we introduced the -> notation as an intermediate form specifically to take away the need to generalize placeholders. Larry
Re: Apo 12
On 4/19/04 11:11 AM, Larry Wall wrote: > On Sat, Apr 17, 2004 at 01:12:58PM -0400, Austin Hastings wrote: > : If it's not totally obvious to everyone, you should download a copy of A12 > : (I like the "printer-friendly" all-in-one-page version) as a hedge against > : the almost-inevitable slashdotting. > > Or not... > > Perhaps slashdot has decided they don't frontpage PhD dissertations. :-) Yeah, but did you see the story about that awesome new D language? It has a native "dictionary" type! -John
A12: Required Named Parameters Strike Back!
Those with encyclopedic knowledge of the perl6-language list will recall my impassioned, but ultimately futile plea for required named parameters--that is, required arguments to a function that must be supplied as "pairs" rather than positionally. Here's a post from the middle of that old thread: http://www.nntp.perl.org/group/perl.perl6.language/14689 Okay, so no one seemed to buy my argument the last time around, but now I'm reading A12 and I see things like this: http://www.perl.com/pub/a/2004/04/16/a12.html?page=7#the_default_constructor > The arguments for the default constructor are always named arguments, hence > the *%_ declaration to collect all those pairs and pass them on to bless. http://www.perl.com/pub/a/2004/04/16/a12.html?page=9#multi_submethod_build > It is not likely that Perl 6.0.0 will support multiple dispatch on named > arguments, but only on positional arguments. Since all the extra arguments to > a BUILD routine come in as named arguments, you probably can't usefully multi > a BUILD (yet). These passages may not seem directly relevant to my earlier argument, but I think they do add something to the topic. The first one confuses me a bit. The default constructor has a *%_ signature, which means it slurps up all the named parameters. It's obvious that the default constructor is only interested in named params, but the signature doesn't really enforce this, AFAICT. If I call a default constructor like this: $dog = Dog.new(name => 'Fido', age => 7, 2, 'Brown', Collar.new()); then Perl 6 won't say boo at either compile time or runtime. Or maybe I'm wrong, but either way this isn't really an argument for required named params since there are no required args to the default constructor anyway. But I'm getting there (I hope), so bear with me :) I'm not sure what the above would do, assuming the default new() doesn't have a [EMAIL PROTECTED] term waiting at end of its signature to slurp up the args 7, 'Brown', and Collar.new(). Would those args just be ignored? And what if it was called like this? $dog = Dog.new(2, name => 'Fido', age => 7, 'Brown', Collar.new()); Is that a compile-time or runtime error? Hm. Anyway, let's move on. Let's supposed that I don't like the default constructor and want to replace it with one of my own. I decode that an object of my Dog class cannot be instantiated without a name, age, and id. But being a good Perl 6 citizen, I document the usage of my constructor like this: $dog = Dog.new(name => 'Fido', age => 7, id => 2); After all, according to A12, "arguments for the default constructor are always named arguments", so I'm trying to follow suit. I don't want my customized constructor to be needlessly different than the default constructor. Unfortunately, the signature for my constructor has to be: method new($name, $age, $id, *%rest) { ... } which means that, regardless of how I document the API, someone can do this: $dog = Dog.new('Fido', 2, 7); and there's nothing I can do to stop them. ...so, did you catch the fact that the second example is a two year-old dog instead of a seven year-old dog? Maybe, maybe not, which is part of why I, as the API designer, decided that those params should named. Even more importantly, I decided to use named params because there's no "natural" or implied order for the name, age, and id attributes. It's completely arbitrary. Okay, so it's arbitrary. Then why can't I just maintain that arbitrary order forever and ever? In fact, if I do nothing, it will be maintained. So what's the problem? Yes, the answer is that "it's the principle." Name, age, and id are required, but there is no implied order. I want them to be named params. I am the API designer. I think it will reduce errors and make code that uses my Dog object easier to read and maintain. It's not as if I'm forbidding Dog users from using the indirect object syntax or something like that. My demands are modest, useful, and certainly no more onerous or "B&D"-esque than choosing method names or deciding which arguments are required or any of the other things that an API designer does. Obviously the Perl 6 Language Design Illuminati have at least a few thoughts in a similar direction. "The arguments for the default constructor are always named arguments" because constructors often initialize lots of attributes, and those attributes rarely have a natural or implied order. Constructors just plain look and work better with named params. (The only possible exception is a special-case for a single argument.) But, ha ha, that's too bad if you also decide that some of the constructor params are required! Even if nothing has changed about the lack of a natural or implied order of the arguments, you, as the API designer, are forced to both *choose* and *maintain forever* an arbitrary order for your params! I think this is a bad thing. This may seem like it has turned into just a repeat of the Synopsis 6 discuss
Re: Is Dog|undef a legal type?
On Mon, Apr 19, 2004 at 07:01:34PM +0200, Juerd wrote: : Abhijit A. Mahabal skribis 2004-04-19 11:00 (-0500): : > when Dog: ... : > when Array: ... : : Shouldn't that be: : : when Dog { ... } : when Array { ... } Yes, that's how it should be written. : Or is there some .when that I have not yet heard of? Nope. I was just reading the previous as pseudocode, so I didn't say anything about it. Larry
Re: Is Dog|undef a legal type?
> Abhijit A. Mahabal skribis 2004-04-19 11:00 (-0500): > > when Dog: ... > > when Array: ... > > Shouldn't that be: > > when Dog { ... } > when Array { ... } > > Or is there some .when that I have not yet heard of? Guilty as charged. My Perl6 is getting rusty... --Abhijit
Re: placeholder attachment?
On Mon, Apr 19, 2004 at 08:57:47AM -0700, Trey Harris wrote: : > : > It's easy to just say "don't nest placeholder-using closures," but that : > : > doesn't seem workable in practice since every block is a closure, unless : > : > placeholders are forbidden from all but the most trivial cases. Absurdly : > : > trivial, it seems. How about : > : > : > : > $sub = { if $^a { $^b = $^a } }; : > : : > : I want this to work. It could look at C's signature and see that : > : the closure it is expecting wants arguments, and since it doesn't, it : > : knows that they belong outside. But that doesn't generalize. : > : > I don't think I want that to work. : : Alright, you're the boss. But it does make placeholders nearly useless, : does it not, by essentially limiting them to subs containing single : expressions? Placeholders are by nature useless in anything complex if nobody can figure out their scope. The intent is to keep the rule simple enough that you use placeholders for simple things, but -> $a,$b {...} for more complex things. Strictly speaking, they're not limited to single expressions. You just can't put them into a subordinate closure. You could have any number of statements in your block. But yes, the strong intent is to discourage their use beyond simple expressions. You may think that anything that can't be completely generalized is "nearly useless", but natural language is full of non-generalizable but nevertheless useful idioms. Linguists like to distinguish productive from non-productive affixes, for instance. A new productive suffix in English is -gate, which means "the scandal associated with..." On the other hand, the bi- prefix is on the verge of dying in English, which is partly why we found "bicoastal" funny when it was coined, I suspect. By contrast, the -ant suffix meaning "person who does..." is pretty much completely non-productive anymore. That doesn't mean we stop using words like "attendant", however. : > : I think a better solution would be to associate all placeholders with : > : the outermost closure that introduced a placeholder. For example: : > : : > : $sub = { { $^a + $^b } }; : > : : > : Would bind them both to the inner one, while: : > : : > : $sub = { $^a; { $^a + $^b } }; : > : : > : Would bind them both to the outer one. : > : > This is the sort of twisty thinking that some people can keep straight : > and some people can't. That's why we simplified the list of rules : > from the original placeholder RFC, after all. : : What is the list of rules? That's why I asked, and I'm still not clear : exactly what happens in the example I gave. Saying that my example : shouldn't work only eliminates one of the possibilities, the one where it : works, while leaving all the ways it might not work open. It being : guaranteed to do what I don't mean is a step towards making what I mean be : something closer to what it does, but it would be helpful if I knew what : it does so that I can more finely adjust what I mean. :-) There is no list of rules. There is only one rule: Placeholders bind to the most closely surrounding closure. If you want a list of rules, go see RFC 23. :-) Larry
Re: Is Dog|undef a legal type?
Abhijit A. Mahabal skribis 2004-04-19 11:00 (-0500): > when Dog: ... > when Array: ... Shouldn't that be: when Dog { ... } when Array { ... } Or is there some .when that I have not yet heard of? Juerd
Re: placeholder attachment?
"Trey Harris" <[EMAIL PROTECTED]> wrote i > It's easy to just say "don't nest placeholder-using closures," but that > doesn't seem workable in practice since every block is a closure, unless > placeholders are forbidden from all but the most trivial cases. Absurdly > trivial, it seems. How about > > $sub = { if $^a { $^b = $^a } }; I would like to think that not all blocks have the same context. We could define a "placeholder" scope as being a lexical scope that sends data to a block. Thus C, C etc., all introduce lexical scopes that are tagged as placeholder scopes; but C and C do not. Its a bit like an inside-out-in-reverse C concept. Dave.
Re: Is Dog|undef a legal type?
On Mon, Apr 19, 2004 at 11:00:33AM -0500, Abhijit A. Mahabal wrote: : If we have a method that returns Dog if it returns anything at all, can we : say: : : method foo returns Dog|undef {...} Yes, but... You'd say that only if you wanted to allow a return type that can be simultaneously Dog and undef, as well as either. Remember that | is inclusive-OR, not exclusive. The default meaning of method foo returns Dog {...} is actually method foo returns Dog^undef {...} since any Object is implicitly allowed to be undef instead. : In a similar vein, if the function reurns a dog or a refernce to an array : , can we use Dog|Array? Certainly. Again, you might wish to be more specific with Dog^Array, though Dog|Array will certainly work, and is arguably more readable. : And is this legal: : : given ($obj){ : when Dog: ... : when Array: ... : #obviously $obj can be a ref to an array, not itself an array : } Yes. Note that there's little distinction in Perl 6 between a ref to an an array and the array itself. If you use an array in scalar context, you automatically get the reference. Larry
Re: Apo 12
On Mon, Apr 19, 2004 at 11:44:24AM -0400, Dan Sugalski wrote: : For that they leave it to lambda.weblogs.com to heap *educated* scorn : and derision on things. :) Hmm, well, in all their educatedness, they don't seem to have figured out that the prototyping behavior they're looking for is actually supplied by wildcard delegation in Perl 6... Larry
Re: Apo 12: Space in method calls
> No, obviously arguments. Okay, I see the problem. What you're missing > is that in an earlier Apocalypse, we said that postfix subscripts > and argument lists may not have an intervening space. Oh, I see. Yes, I had missed that. Thanks for clearing that up. --Abhijit
Is Dog|undef a legal type?
If we have a method that returns Dog if it returns anything at all, can we say: method foo returns Dog|undef {...} In a similar vein, if the function reurns a dog or a refernce to an array , can we use Dog|Array? And is this legal: given ($obj){ when Dog: ... when Array: ... #obviously $obj can be a ref to an array, not itself an array } --Abhijit Abhijit A. Mahabal http://www.cs.indiana.edu/~amahabal/
Re: placeholder attachment?
In a message dated Mon, 19 Apr 2004, Larry Wall writes: > On Mon, Apr 19, 2004 at 04:48:05AM -0600, Luke Palmer wrote: > : Trey Harris writes: > : > Can anyone explain the rules of placeholder attachment? i.e., in the > : > example in Perl6::Placeholder's manpage, > : > > : > grep { $data{$^value} } 1..10; > [...] > : In your first example, it does what you mean because the hash subscript > : isn't a closure. Curlies are always closures, except when they're not > : (to be specific, in hash subscripts and hash constructors). > > Yes, that's the basic rule. In Perl 5 the curlies are (potentially) > blocks, though the optimizer throws away the block entry and exit > when it thinks it can. In Perl 6 we'll just say that those aren't > blocks. If you really want a block inside a subscript, you can always > use do {}. (But merely putting semicolons inside a subscript turns > it into a multidimensional subscript, not a block.) Okay, thanks for setting me straight there. > : > It's easy to just say "don't nest placeholder-using closures," but that > : > doesn't seem workable in practice since every block is a closure, unless > : > placeholders are forbidden from all but the most trivial cases. Absurdly > : > trivial, it seems. How about > : > > : > $sub = { if $^a { $^b = $^a } }; > : > : I want this to work. It could look at C's signature and see that > : the closure it is expecting wants arguments, and since it doesn't, it > : knows that they belong outside. But that doesn't generalize. > > I don't think I want that to work. Alright, you're the boss. But it does make placeholders nearly useless, does it not, by essentially limiting them to subs containing single expressions? > : I think a better solution would be to associate all placeholders with > : the outermost closure that introduced a placeholder. For example: > : > : $sub = { { $^a + $^b } }; > : > : Would bind them both to the inner one, while: > : > : $sub = { $^a; { $^a + $^b } }; > : > : Would bind them both to the outer one. > > This is the sort of twisty thinking that some people can keep straight > and some people can't. That's why we simplified the list of rules > from the original placeholder RFC, after all. What is the list of rules? That's why I asked, and I'm still not clear exactly what happens in the example I gave. Saying that my example shouldn't work only eliminates one of the possibilities, the one where it works, while leaving all the ways it might not work open. It being guaranteed to do what I don't mean is a step towards making what I mean be something closer to what it does, but it would be helpful if I knew what it does so that I can more finely adjust what I mean. :-) Trey
Re: Apo 12: Space in method calls
On Mon, Apr 19, 2004 at 10:37:57AM -0500, Abhijit A. Mahabal wrote: : > $obj.meth, -> obviously not arguments : > $obj.meth $foo,$bar -> obviously arguments : > : : $obj.meth() + $bat -> obviosly not arguments : $obj.meth () + $bat-> obviosly not arguments No, obviously arguments. Okay, I see the problem. What you're missing is that in an earlier Apocalypse, we said that postfix subscripts and argument lists may not have an intervening space. : $obj.meth ($foo + $bar) + $bat -> ambiguous, likely to be list No, obviously arguments. : $obj.meth($foo + $bar) + $bat -> $foo + $bar the argument Correct. : $obj.meth($foo + $bar), $bat -> list No, if you mean that $bat is the final argument to the method call. Yes, if by that you mean the list is outside the method call. The absence of a space makes ($foo + $bar) a postfix argument-supplying operator. So this is parsed: ($obj.meth($foo + $bar)), $bat : Is that about the story so far? Or is the last example probably going to : be illegal without a space? It's certainly not illegal, but it won't do what you want if you think it'll pass $pat to $obj.meth. : How bad is it to require space before arguments that are a list, so that : the no-space case is unambiguous? It may turn out that all the unambiguous cases do in fact require space before the list (unless you use the explicit colon). However, that doesn't necessarily make it beneficial to declare that $obj.meth+1 is unambiguous in the other direction. I think if something is going to be unclear to the *reader* of the code, we should probably not make it easy to write it that way. Larry
Re: Apo 12
At 8:11 AM -0700 4/19/04, Larry Wall wrote: On Sat, Apr 17, 2004 at 01:12:58PM -0400, Austin Hastings wrote: : If it's not totally obvious to everyone, you should download a copy of A12 : (I like the "printer-friendly" all-in-one-page version) as a hedge against : the almost-inevitable slashdotting. Or not... Perhaps slashdot has decided they don't frontpage PhD dissertations. :-) For that they leave it to lambda.weblogs.com to heap *educated* scorn and derision on things. :) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Apo 12: Space in method calls
On Mon, 19 Apr 2004, Larry Wall wrote: > On Sat, Apr 17, 2004 at 01:07:44PM -0500, Abhijit A. Mahabal wrote: > : $obj.method ($x + $y) + $z > : > : >From the earlier examples (like $obj.method +1), I got the impression that > : you look ahead until you find a term or an operator. In the example above, > : isn't ($x + $y) a full term, all by itself, and in that case would not > : What am I missing? > > The distinction is not term/operator exactly. It's a four-way distinction > between > > definitely a postfix op -> () hold arguments, otherwise no arguments > definitely a binary op-> there are no arguments > ambiguous -> require disambiguation > definitely a term -> treat method as list operator > > where the last category assumes that the term indicates the first item > in an expression. (Note that a definite unary operator is the beginning > of a term.) > $obj.meth,-> obviously not arguments > $obj.meth $foo,$bar -> obviously arguments > $obj.meth() + $bat -> obviosly not arguments $obj.meth () + $bat-> obviosly not arguments $obj.meth ($foo + $bar) + $bat -> ambiguous, likely to be list $obj.meth($foo + $bar) + $bat -> $foo + $bar the argument $obj.meth($foo + $bar), $bat -> list Is that about the story so far? Or is the last example probably going to be illegal without a space? How bad is it to require space before arguments that are a list, so that the no-space case is unambiguous? > Larry --Abhijit
Re: placeholder attachment?
On Mon, Apr 19, 2004 at 04:48:05AM -0600, Luke Palmer wrote: : Trey Harris writes: : > Can anyone explain the rules of placeholder attachment? i.e., in the : > example in Perl6::Placeholder's manpage, : > : > grep { $data{$^value} } 1..10; : > : > C<$^value> is clearly intended to attach to the outer closure C<{ : > $data{$^value} }>, not the inner closure C<{$^value}>. But how does the : > compiler know? What is the general rule? : : This is a tough question, one to which I don't know the answer. I'll : do something different for a change and speculate :-) Hey, I never speculate. ;-) : In your first example, it does what you mean because the hash subscript : isn't a closure. Curlies are always closures, except when they're not : (to be specific, in hash subscripts and hash constructors). Yes, that's the basic rule. In Perl 5 the curlies are (potentially) blocks, though the optimizer throws away the block entry and exit when it thinks it can. In Perl 6 we'll just say that those aren't blocks. If you really want a block inside a subscript, you can always use do {}. (But merely putting semicolons inside a subscript turns it into a multidimensional subscript, not a block.) : > It's easy to just say "don't nest placeholder-using closures," but that : > doesn't seem workable in practice since every block is a closure, unless : > placeholders are forbidden from all but the most trivial cases. Absurdly : > trivial, it seems. How about : > : > $sub = { if $^a { $^b = $^a } }; : : I want this to work. It could look at C's signature and see that : the closure it is expecting wants arguments, and since it doesn't, it : knows that they belong outside. But that doesn't generalize. I don't think I want that to work. : I think a better solution would be to associate all placeholders with : the outermost closure that introduced a placeholder. For example: : : $sub = { { $^a + $^b } }; : : Would bind them both to the inner one, while: : : $sub = { $^a; { $^a + $^b } }; : : Would bind them both to the outer one. This is the sort of twisty thinking that some people can keep straight and some people can't. That's why we simplified the list of rules from the original placeholder RFC, after all. : Since placeholders are meant for : small scopes, this seems a good heuristic. That second example was : obviously a hack to get it to work right. The clean way to do that : would be: : : $sub = -> $a, $b { { $a + $b } }; Yup. Larry
Re: Apo 12
On Sat, Apr 17, 2004 at 01:12:58PM -0400, Austin Hastings wrote: : If it's not totally obvious to everyone, you should download a copy of A12 : (I like the "printer-friendly" all-in-one-page version) as a hedge against : the almost-inevitable slashdotting. Or not... Perhaps slashdot has decided they don't frontpage PhD dissertations. :-) Larry
Re: Apo 12: Space in method calls
On Sat, Apr 17, 2004 at 01:07:44PM -0500, Abhijit A. Mahabal wrote: : I do not understand one of the examples in the Use of methods/the dot : notation section: : : $obj.method ($x + $y) + $z : : >From the earlier examples (like $obj.method +1), I got the impression that : you look ahead until you find a term or an operator. In the example above, : isn't ($x + $y) a full term, all by itself, and in that case would not : this mean ($obj.method($x + $y)) + $z, the same as the other call it is : contrasted with: : : $obj.method($x + $y) + $z : : What am I missing? The distinction is not term/operator exactly. It's a four-way distinction between definitely a postfix op -> () hold arguments, otherwise no arguments definitely a binary op -> there are no arguments ambiguous -> require disambiguation definitely a term -> treat method as list operator where the last category assumes that the term indicates the first item in an expression. (Note that a definite unary operator is the beginning of a term.) The basic underlying motivation is to allow methods a list operators: $my.for 1..3 {...} Now, we haven't actually defined what puts the method call into which category. But the rather obvious poler opposites are $obj.meth, -> obviously not arguments $obj.meth $foo,$bar -> obviously arguments If the rules get skewed one way or the other to eliminate the ambiguos middle category, I'd say that we tend to give the benefit of the doubt to the list, and you have to put a "stopper" like comma or a right bracket or brace, or put explicit empty parens, if you want to pass no arguments. But if we can unambiguously define what's ambiguous :-) then it might be useful to force people to clarify what they mean, just for readability. Larry
RE: Apocalypse 12
> -Original Message- > From: Mark A. Biggar [mailto:[EMAIL PROTECTED] > > Brent 'Dax' Royal-Gordon wrote: > > > chromatic wrote: > > > >> Perl.com has just made A12 available: > > > > > > I started reading it last night, and ended up going to bed before I was > > finished. But I just wanted to say that this: > > > > With this dispatcher you can continue by saying "next METHOD". > > > > is the sort of genius that makes me glad Larry's designing this > > language. Well done! > > > > Yeah, remmeber from A4 that flow control stuff like "next", "leave", > "return" are semantically a form of exception throw and so are actaully > dymanically (not lexically) scoped (although the compiler is free to > optimize if the target is in the lexical scope of the construct or > vice versa). I kind of have a problem with this on fragility grounds. Not so much the C syntax, as the whole non-local-goto idea. Specifically, if you have code that uses C or C without the loop name, it's vulnerable to having additional control structures inserted in the flow. (If the named approach is used, it's vulnerable to having named entities inserted in the flow. Less vulnerable, but vulnerable.) I'm wondering if there's some way to convert C into C, such that each loop would have a unique "identity" that could be passed around. This would raise the bar for erroneous invocations, and at the same time make slightly more programmatic things possible. (Sure, C works, but at what price?) =Austin
RE: A12 undef method calls
> -Original Message- > From: Luke Palmer [mailto:[EMAIL PROTECTED] > Sent: Monday, 19 April, 2004 06:00 AM > To: Language List > Subject: A12 undef method calls > > > A12 mentions that C<$foo.bar> should return undef if C<$foo> is undef. > While I like the idea a lot, I don't think it should happen without > distinction. In fact, that's what I would most expect C<.?> to do, not > "call a method if there is one," though that seems useful, too. > > I'm just shooting in the dark here, but perhaps C should play that > role. That way you have: > > $foo.?bar # return undef if "bar" is undef... in a > manner of speaking > $foo?.bar # return undef if $foo is undef > $foo?.?bar # return undef if either is (?) > I think that undef->undef is desirable default behavior, not something that should have to be spelled out over and over again. There are really four cases. Assuming errors in all: 1- Untyped/Undefined: "I don't know *WHAT* you want." 2- Typed/Undefined: "I know what you want, but you can't get it (yet)." 3- Untyped/Defined: "I know what you want, but this object doesn't support it." 4- Typed/Defined: "I know what you want, and this is plain wrong." I think that 3 and 4 should throw exceptions, as being clearly wrong (unless AUTHMETH[DEF] is present). 1 and 2 on the other hand are more in the region of "easygoing DWIMery", so should just return a helpful undef, unless C is in effect. > Either that or C<.?> could double as both roles, considering C > an object with no methods. Ugh. Let's make '.' as useful as possible, please. > And I can't figure out for the life of me why you'd ever want to use > C<.+>... This is probably the "should be" default for '.': "Call a method. If there's more than one, figure out what to do about that case and do it. But make sure that SOMETHING gets done, or let me know why not." =Austin
Re: placeholder attachment?
Trey Harris writes: > Can anyone explain the rules of placeholder attachment? i.e., in the > example in Perl6::Placeholder's manpage, > > grep { $data{$^value} } 1..10; > > C<$^value> is clearly intended to attach to the outer closure C<{ > $data{$^value} }>, not the inner closure C<{$^value}>. But how does the > compiler know? What is the general rule? This is a tough question, one to which I don't know the answer. I'll do something different for a change and speculate :-) In your first example, it does what you mean because the hash subscript isn't a closure. Curlies are always closures, except when they're not (to be specific, in hash subscripts and hash constructors). > It's easy to just say "don't nest placeholder-using closures," but that > doesn't seem workable in practice since every block is a closure, unless > placeholders are forbidden from all but the most trivial cases. Absurdly > trivial, it seems. How about > > $sub = { if $^a { $^b = $^a } }; I want this to work. It could look at C's signature and see that the closure it is expecting wants arguments, and since it doesn't, it knows that they belong outside. But that doesn't generalize. I think a better solution would be to associate all placeholders with the outermost closure that introduced a placeholder. For example: $sub = { { $^a + $^b } }; Would bind them both to the inner one, while: $sub = { $^a; { $^a + $^b } }; Would bind them both to the outer one. Since placeholders are meant for small scopes, this seems a good heuristic. That second example was obviously a hack to get it to work right. The clean way to do that would be: $sub = -> $a, $b { { $a + $b } }; Luke
Re: Apocalypse 12
Brent 'Dax' Royal-Gordon wrote: chromatic wrote: Perl.com has just made A12 available: I started reading it last night, and ended up going to bed before I was finished. But I just wanted to say that this: With this dispatcher you can continue by saying "next METHOD". is the sort of genius that makes me glad Larry's designing this language. Well done! Yeah, remmeber from A4 that flow control stuff like "next", "leave", "return" are semantically a form of exception throw and so are actaully dymanically (not lexically) scoped (although the compiler is free to optimize if the target is in the lexical scope of the construct or vice versa). -- [EMAIL PROTECTED] [EMAIL PROTECTED]
placeholder attachment?
Can anyone explain the rules of placeholder attachment? i.e., in the example in Perl6::Placeholder's manpage, grep { $data{$^value} } 1..10; C<$^value> is clearly intended to attach to the outer closure C<{ $data{$^value} }>, not the inner closure C<{$^value}>. But how does the compiler know? What is the general rule? It's easy to just say "don't nest placeholder-using closures," but that doesn't seem workable in practice since every block is a closure, unless placeholders are forbidden from all but the most trivial cases. Absurdly trivial, it seems. How about $sub = { if $^a { $^b = $^a } }; ? Are there two C<$^a>'s, one masking the other? Or just one? If two, then the code should fail at runtime for attempted assignment to an undefined lvalue (because $^b isn't set) or more likely at compile-time for a missing required parameter. If there's just one C<$^a>, wouldn't C<$^b> get set to the topic of the C, i.e. C<$^a> (or is the topic of an C's first closure always C?), leading to the expression being equivalent to $sub = ( if $^a { $^a = $^a } }; ? Or will Perl DWIM and attach both $^a and $^b to the outer sub? If so, how did it know to do that, and not attach it to whatever sub contains the assignment to $sub? I'm probably just confused here, but I'd appreciate some straightening out, as it's relevant to something I'm working on. Apo 6 seems to be silent on this (which perhaps indicates that I'm making this a lot harder than it is). Trey
Re: A12: Mutating Methods and hyperoperators
Luke Palmer wrote: Matthew Walton writes: But can I do @things».=method(); Of course. Excellent. Thankyou. Not this time :-) Next time then, probably.
A12 undef method calls
A12 mentions that C<$foo.bar> should return undef if C<$foo> is undef. While I like the idea a lot, I don't think it should happen without distinction. In fact, that's what I would most expect C<.?> to do, not "call a method if there is one," though that seems useful, too. I'm just shooting in the dark here, but perhaps C should play that role. That way you have: $foo.?bar # return undef if "bar" is undef... in a manner of speaking $foo?.bar # return undef if $foo is undef $foo?.?bar # return undef if either is (?) Either that or C<.?> could double as both roles, considering C an object with no methods. And I can't figure out for the life of me why you'd ever want to use C<.+>... Luke
Re: A12: Mutating Methods and hyperoperators
Matthew Walton writes: > I know these were discussed to death not that long ago, but reading > Apocalypse 12 I had a query I couldn't remember if it had been covered > before or not, and I certainly don't recall seeing it in the Apocalypse, > although I've not read the entire thing with as much attention as I > might like yet (it's great work though). > > So, simple query. I know I can do > > @thingsÂ.method(); > > But can I do > > @thingsÂ.=method(); Of course. > which would presumably be the same as > > map { .=method() } @things; > > And if I can't do it, why not? I think I should be able to do it, but > it's entirely possible I've missed something, because I usually have. Not this time :-) Luke
Re: Apocalypse 12
Brent 'Dax' Royal-Gordon wrote: chromatic wrote: Perl.com has just made A12 available: I started reading it last night, and ended up going to bed before I was finished. But I just wanted to say that this: With this dispatcher you can continue by saying "next METHOD". is the sort of genius that makes me glad Larry's designing this language. Well done! Yeah, remmeber from A4 that flow control stuff like "next", "leave", "return" are semantically a form of exception throw and so are actaully dymanically (not lexically) scoped (although the compiler is free to optimize if the target is in the lexical scope of the construct or vice versa). -- [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: A12 Q: Pointer-to-member-function behavior?
On Sat, Apr 17, 2004 at 11:52:19AM -0400, Austin Hastings wrote: : Is it permissible to use variable dispatch for private methods? Don't see why not, as long as the overhead of switching isn't imposed on every method call. : class Cerebellum { : method :think() {...} : method :ponder() {...} : method :cogitate() {...} : : method some_method() { : ... : $activity = «:think, :ponder, :cogitate».random; s/,//g : $brain.$activity; : } : } : : Or would the colons be on the invocation, not the name? Could be made to work either way. : PS: Sorry, Piers. He can just ignore this thread if he thinks it's too much. But Piers really shouldn't carp--the backticks thread is highly compressible... :-) Larry
A12: Mutating Methods and hyperoperators
I know these were discussed to death not that long ago, but reading Apocalypse 12 I had a query I couldn't remember if it had been covered before or not, and I certainly don't recall seeing it in the Apocalypse, although I've not read the entire thing with as much attention as I might like yet (it's great work though). So, simple query. I know I can do @things».method(); But can I do @things».=method(); which would presumably be the same as map { .=method() } @things; And if I can't do it, why not? I think I should be able to do it, but it's entirely possible I've missed something, because I usually have. Thanks Matthew
Returning from Rules
I notice that when I write a grammar, I end up doing this an awful lot (in P::RD notation): list: term ',' list { make_node(@item[0,1,3]) } | term { $item[1] } With attention on the actions, and assuming is on. In Perl 6, aside from the fact that there's a clearly better way to write this rule, this would be translated: rule list { , { $0 = make_node('list', $?term, $?list) } |{ $0 = $?term } } The part that I'm complaining about in this mail is C<$0 = >. While it's only three extra characters, I believe that it is a large hindrance to readability. However, we can reclaim this readability by noticing that the construct: <{ get_rule() }># call an anonymous rule returned by the code block Can also be written: <$( get_rule() )> Because of the interpretation of: <$somerule> Therefore, the first syntax can be redefined to evaluate the code block and assign the result to $0. The example now becomes: rule list { , <{ make_node('list', $?term, $?list) }> | <{ $?term }> } My argument for using this notation stems from the fact that it would be a royal pain to write subs like: sub add ($a, $b) { $RET = $a + $b; } Even though it's just a few extra characters. I don't want to think about replacing the current parse tree node, I just want the rule to represent a value. An assignment has little place there. Luke