Re: [svn:perl6-synopsis] r10077 - doc/trunk/design/syn
[EMAIL PROTECTED] commits: > New Revision: 10077 > Modified: doc/trunk/design/syn/S02.pod > == > > -foo.bar # foo().bar -- postfix prevents args > +foo.bar # foo().bar -- illegal postfix, must use foo().bar > foo .bar # foo($_.bar) -- no postfix starts with whitespace I don't think it makes much sense to start the comments with an alternate form for the expressions now denoted as illegal -- "here's some other syntax which this used to be the same as but it no longer is" probably only confuses the casual reader. Smylers
Re: [svn:perl6-synopsis] r10077 - doc/trunk/design/syn
Smylers wrote: [EMAIL PROTECTED] commits: New Revision: 10077 Modified: doc/trunk/design/syn/S02.pod == -foo.bar # foo().bar -- postfix prevents args +foo.bar# foo().bar -- illegal postfix, must use foo().bar foo .bar # foo($_.bar) -- no postfix starts with whitespace I don't think it makes much sense to start the comments with an alternate form for the expressions now denoted as illegal -- "here's some other syntax which this used to be the same as but it no longer is" probably only confuses the casual reader. On a side note, does that apply only to expressions that start with an identifier, or does that mean that: $socket.accept.getlines will have to be: $socket.accept().getlines ?
Easy Str === Str question: what is a reference type
S03 says: Binary === tests type and value correspondence: for two value types, tests whether they are the same value (eg. 1 === 1); for two reference types, checks whether they have the same identity value. For reference types that do not define an identity, the reference itself is used (eg. it is not true that [1,2] === [1,2], but it is true that @a === @a). There's a problem here, from my point of view. I'll take it one assumption at a time: * $whatever.as.id ~~ $whateverelse.as.id is true if and only if $whatever := $whateverelse at some point in the past, either explicitly, or through some sort of folding. * Str is a boxed type, and thus is a "reference type" * Thus, Str should be compared by .id and not by value, according to the above. So, IMHO, either there's a mistake in S03; Str is a special case WRT ===; or I misunderstand "reference type" (which S03 never defines). Clarification please? Two things were mentioned on IRC about this: * Str might be compared by .id, but .id for Str is based on the contents of its underlying storage... this worries me because it means that Strs with radically different "meanings" would be === because their encoding is different. * A reference type might only mean containers (though S03 seems to imply that objects are included to me). Thanks, and sorry for all the lame questions! I'm just trying to make sure that the docs I write aren't utterly, worthlessly wrong. :-/ -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "We had some good machines, but they don't work no more." -Shriekback
===, =:=, ~~, eq and == revisited (blame ajs!)
Over at #perl6 we had a short discussion on =:=, ===, and ~~, mostly raised by ajs's discussion on Str items and ===. After a brief discussion we managed to formulate several questions that we feel are slightly to totally unresolved. 1. what is .id on references? Is it related to the memory slot, like refaddr() in Perl 5? 2. is .id *always* a low level type representation of the object's value? It's specced that low level typed items have the same ID when they have the same value. What about complex types? 3. Are these descriptions of the operators correct? ~~ matches the left side to a description on the right side =:= makes sure the objects are actually the same single object (if $x =:= $y and you change $x. then $y. was also changed... is this .id on refs?) Is =:= really eq .id? or more like variable($x).id eq variable($y).id? === makes sure that the values are equivalent ( @foo = ( 1, 2, 3 ); @bar = ( 1, 2, 3); @foo === @bar currently works like that, but @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); @foo === @bar does not (in pugs). This is not useful because we already have this return false with =:=). If they are not correct, why is there an overlap between =:=? Why is it hard to deeply compare values in 2006 without using e.g. Data::Compare? 4. will we have a deep (possibly optimized[1]) equality operator, that *will* return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); op(@foo, @bar)? Is it going to be easy to make the newbies use that when they mean "it's the same", like they currently expect == and eq to work on "simple" values? 5. is there room for a new opperator? =::= makes sure the memory slot is the same (might be different for simple values). refaddr($x) == refaddr($y) in Perl 5 =:= makes sure that .ids are the same, and is useful if the .id method is meaningful for an object. A bit like Test::More::is( $x, $y ) but without the diagnosis in Perl 5, or abusing eq if the object doesn't overload stringification. === makes sure the values are the same even if they are copies/clones/whatever. Data::Compare in Perl 5. A bit like what people overload == for in Perl 5 right now (which confuses "numerical" equality with "true" equality, so we want to phase that out). ~~ makes sure the value on the right side describes the value on the left side. Reminiscient of Test::Deep::cmp_deeply, with all the various matching magic. Thanks, [1] It could, of course, be just =:= && === inside, and it could optimize arrays to check length first, and it could cache checksums and it could do whatever - please don't bring this up as a performance issue, it is one of correctness and ergonomics that must be resolved first. -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418 pgpI98L8HHVih.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
If we do have deep value equality checks, then "default" == and eq are probably: sub &infix:<==> ( $x, $y ) { +$x === +$y; } sub &infix: ( $x, $y ) { ~$x === ~$y; } So that the compare-as-sometype behavior is retained from perl 5 without introducing new complexity to the objects being compared as strings/numbers. -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418 pgpefrROP9pJ6.pgp Description: PGP signature
Another quick one: .as
I would assume that all classes automatically define: multi submethod *infix: ($self: $?CLASS) { $self } so that derived classes can automatically: $obj.as Without actually changing their implementation details (only the type that Perl currently thinks it's dealing with polymorphically). In fact, I would expect that this bit of behind-the-curtain magic is how the MCP arranges for polymorphism when you: sub foo(Object $x) {...} my A $y; foo($y); Is all of that fair? -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "We had some good machines, but they don't work no more." -Shriekback
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
Jedai and I went through some of pugs current implementations. Here's a list of what we expect the operators to return and what they currently do. This does not exactly agree with S03 right now, but is our opinion. Force into a type before comparing values: 42 == 42 - true, same numeric value "42" == 42 - true, same numeric value "42" == "42" - true, same numeric value " 42 " == "42.0" - true, same numeric value " 42 " eq "42.0" - false, different string value 4 eq "4" - true, same string value Well typed value comparison: 42 === 42 - true, the same type "42" === 42 - false, not the same type "42" === "42" - true, the same type " 42 " === "42.0" - false, different value in "natural" type (string values) (1, 2, 3) === (1, 2, 3) - true, same value ([1, 2 ], 3 ) === ([1, 2 ], 3) - true, same value - BROKEN (actually false, since refs are not the same). S03 thinks this is actually OK. [1, 2, 3] === [1, 2, 3] - true, same value, (S03 says that this is actually broken, because references should not be the same (we disagree)) my @foo = (1, 2, 3); my @bar = @foo; @foo === @bar - true, same value. my @foo = ([1, 2], 3); my @bar = @foo; @bar === @foo - true, same value - BROKEN (S03 actually agrees with us here, since the ref is the same in this case) Slot/container equality (this is actually up to debate, but this is what we would expect if it was refaddr($x) == refaddr($y)): [ 1, 2, 3 ] =:= [ 1, 2, 3 ] - false, different containers - BROKEN (actually true) my $foo = [ 1, 2, 3 ]; $foo =:= $foo - true, same container my $foo = [ 1, 2, 3 ]; my $bar := $foo; $bar =:= $foo - true, same container my $foo = [ 1, 2, 3 ]; my $bar = $foo; $bar =:= $foo - true, ref to same container, or false since different container, unsure - currently true my @foo = (1, 2, 3); my @bar = @foo; @foo =:= @bar - false, container should be different - BROKEN (actually true) my @foo = (1, 2, 3); my @bar = @foo; @bar[1] = "moose"; @foo =:= @bar - false, container should be different. This actually works like we expected, appearantly pugs does some sort of COW Under := slot semantics the first test should be false, the second should be true, the third should be true, the fourth should be false, the fifth should be false, and the sixth should be false. -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418 pgpNFsdSOd2Lf.pgp Description: PGP signature
Re: [svn:perl6-synopsis] r10077 - doc/trunk/design/syn
On Wed, Jul 12, 2006 at 08:40:53AM -0400, Aaron Sherman wrote: : Smylers wrote: : >[EMAIL PROTECTED] commits: : > : > : >>New Revision: 10077 : >>Modified: doc/trunk/design/syn/S02.pod : >>== : >> : >>-foo.bar# foo().bar -- postfix prevents args : >>+foo.bar# foo().bar -- illegal postfix, must use : >>foo().bar : >> foo .bar # foo($_.bar) -- no postfix starts with : >> whitespace : >> : > : >I don't think it makes much sense to start the comments with an : >alternate form for the expressions now denoted as illegal -- "here's : >some other syntax which this used to be the same as but it no longer is" : >probably only confuses the casual reader. : > : : On a side note, does that apply only to expressions that start with an : identifier, or does that mean that: : :$socket.accept.getlines : : will have to be: : :$socket.accept().getlines : : ? No, this is only list operators, not methods. So $socket.accept.getlines is fine, but foo.accept.getlines is not, unless foo is predeclared 0-ary. But I am tempted to extend it to keywords like "else" and "sub" as well, because any foo{} confusion is going to train people not to think about ...{} as a subscript when they should think about it whenever there's a lack of whitespace. It would be nice if :foo{} were the only exception to that. For similar reasons, I'm also tempted to say that if() is always a function call, because it looks like one. Larry
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, 2006-07-12 at 19:25 +0300, Yuval Kogman wrote: > Over at #perl6 we had a short discussion on =:=, ===, and ~~, mostly raised by > ajs's discussion on Str items and ===. *wave* > 1. what is .id on references? Is it related to the memory slot, like refaddr() > in Perl 5? That's something I'm not sure of, so I'll let it go, other than to say that that question should probably avoid the word "memory", see below. 4. will we have a deep (possibly optimized[1]) equality operator, that *will* Now, let me handle this one out of order, since I think it's really key: > return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); op(@foo, > @bar)? > Is it going to be easy to make the newbies use that when they mean "it's the > same", like they currently expect == and eq to work on "simple" values? Isn't that ~~? Per S03: Array Array arrays are comparablematch if $_ »~~« $x ~~ is really the all-purpose, bake-your-bread, clean-your-floors, wax-your-cat operator that you're looking for. It sounds like pugs is wrong here WRT the spec, since: ( [ 1, 2 ], 3 ) ~~ ( [ 1, 2 ], 3 ) is the same as: [1,2]~~[1,2] && 3 ~~ 3 which is the same as: (1~~1 && 2~~2) && 3~~3 which is true. Ain't recursive hyperoperators grand? Of course, I'm assuming that a comparison hyperoperator in boolean context returns the [&&] reduction of all of the values... that's an interesting assumption, isn't it? But, it seems to be the assumption made by S03 under Smart Matching, so I say it's true. ;) > 2. is .id *always* a low level type representation of the object's value? It's > specced that low level typed items have the same ID when they have the same > value. What about complex types? It cannot be for complex types or even strings... well, at least it I not be I we care about performance. That is, if C<$anything.id> needs to read every byte of $anything, then an anything that happened to be a Buf containing the 3GB in-memory raw image from the Hubble is going to really make C<.id> unhappy. I would hope that C<.id> is an efficient enough operation that === should not look like a performance bottleneck in my code > 3. Are these descriptions of the operators correct? > > ~~ matches the left side to a description on the right side > =:= makes sure the objects are actually the same single object (if $x > =:= $y > and you change $x. then $y. was also changed... is > this .id on refs?) Is =:= really eq .id? or more like > variable($x).id eq variable($y).id? > === makes sure that the values are equivalent ( @foo = ( 1, 2, 3 ); > @bar = ( 1, > 2, 3); @foo === @bar currently works like that, but @foo = ( [ 1, 2 ], > 3 ); > @bar = ( [ 1, 2 ], 3 ); @foo === @bar does not (in pugs). This is not > useful > because we already have this return false with =:=). Let me counter-propose a slightly different way of saying that: ~~ as above. I think we all agree on this. =:= looks in the "symbol table" (caveat dragons) to see if LHS refers to the same variable as the RHS. Does this dereference? Probably not, but I'm not sure, based on S03. === Compares types and .id values. An implementation of this, as I interpreted S03, and with some assumptions made, and with some extra bits filling in the cracks where S03 didn't quite specify an implementation: * A .id method may return C, C or C. === returns false for two objects which are not the same type (with the same traits), and thus the comparison must always be between identical .id return types. * As a special case, however, all "undefined" values (not objects which have the undefined trait, but true undefs with no other functionality) are === to each other. * Objects are always compared according to their underlying type, not the polymorphic role which they are serving at the moment. * num, Num and all like values return their num representation as a .id. * int, Int and all like values return their int representation as a .id. * Bool, bool and bit all have a bit representation for .id * All other code, objects, references, structures, complex numbers, etc. are compared strictly on the basis of an arbitrary C which Perl will generate to represent their storage, and can be overridden by replacing the default .id method. The other way to think about === would be that it tells you if its LHS *could* be constant-folded onto its RHS (if it were constant for long enough), where =:= tells you if that has already been done. Only ~~ has some sort of "deep" semantics, and I think the documentation warns users s
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, Jul 12, 2006 at 04:16:13PM -0400, Aaron Sherman wrote: > On Wed, 2006-07-12 at 19:25 +0300, Yuval Kogman wrote: > > 4. will we have a deep (possibly optimized[1]) equality operator, that > > *will* return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); > > op(@foo, @bar)? > > Is it going to be easy to make the newbies use that when they mean "it's the > > same", like they currently expect == and eq to work on "simple" values? > > Isn't that ~~? > > Per S03: > > Array Array arrays are comparablematch if $_ »~~« $x > > ~~ is really the all-purpose, bake-your-bread, clean-your-floors, > wax-your-cat operator that you're looking for. Granted, ~~ will return true in that case. I think the main problem is Yuval wants a guarantee that it will return true if and only if the things on either side have the same deep structure and values. Currently, ~~ will also return true for structures where this does not hold. For example: @a = ( [ 1, 2] , 3 ); @b = ( sub { return 1 }, sub { return 1 } ); @a ~~ @b; # true Why is that true? By the rules of hyper-operation, it turns into this: [1,2] ~~ sub { return 1 } 3 ~~ sub { return 1 } which is true if these return true values: sub { return 1 }->([1,2]) sub { return 1 }->(3) Which they do. So, smart-match fails as a "deep equality" operator precisely because it's so smart. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Easy Str === Str question: what is a reference type
On 7/12/06, Aaron Sherman wrote: There's a problem here, from my point of view. I'll take it one assumption at a time: * $whatever.as.id ~~ $whateverelse.as.id is true if and only if $whatever := $whateverelse at some point in the past, either explicitly, or through some sort of folding. * Str is a boxed type, and thus is a "reference type" * Thus, Str should be compared by .id and not by value, according to the above. So, IMHO, either there's a mistake in S03; Str is a special case WRT ===; or I misunderstand "reference type" (which S03 never defines). Well, Str is "special" insofar as it surely won't rely on the default .id comparison; as I see it, that's something objects get for free, because it makes sense in a lot of common situations (e.g. a typical Person class would consider each instance to represent a different person). * Str might be compared by .id, but .id for Str is based on the contents of its underlying storage... this worries me because it means that Strs with radically different "meanings" would be === because their encoding is different. Even though S03 doesn't say so, I'm sure that Str's .id will return some sort of value that includes not only the contents but anything else relevant, like the encoding. As for array-refs, I don't know why they couldn't (or shouldn't) be === if they contain the same values. That seems the least surprising way to go. A couple of other questions about S03: Any reference type may pretend to be a value type by defining a .id method which returns a built-in value, i.e. an immutable object or a native value, as specified in S06. Why does it have to be a built-in value (other than for performance)? It might be useful to return a "value" of some other type, which would in turn be checked for its .id's. Or does the problem lie in not being able to guarantee that we'd ever actually reach real built-in values? Because Perl 6 uses a false .id to signify a non-instantiated prototype, all instances should arrange to return a .id that boolifies to true. Does that mean all non-instances are equivalent? I can see that two non-existent Dog's might be considered the same thing, but not a non-existent Dog and a non-existent Cat. Or will $uninstantiated.id return something unique C? -David
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, 2006-07-12 at 15:32 -0500, Jonathan Scott Duff wrote: > On Wed, Jul 12, 2006 at 04:16:13PM -0400, Aaron Sherman wrote: > > On Wed, 2006-07-12 at 19:25 +0300, Yuval Kogman wrote: > > > 4. will we have a deep (possibly optimized[1]) equality operator, that > > > *will* return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); > > > op(@foo, @bar)? > > > Is it going to be easy to make the newbies use that when they mean "it's > > > the > > > same", like they currently expect == and eq to work on "simple" values? > > > > Isn't that ~~? [...] # hmm, what kind of reduction IS that? ;) > > ~~ is really the all-purpose, bake-your-bread, clean-your-floors, > > wax-your-cat operator that you're looking for. > > Granted, ~~ will return true in that case. I think the main problem > is Yuval wants a guarantee that it will return true if and only if > the things on either side have the same deep structure and values. > > Currently, ~~ will also return true for structures where this does > not hold. For example: > > @a = ( [ 1, 2] , 3 ); > @b = ( sub { return 1 }, sub { return 1 } ); > @a ~~ @b; # true Then ~~ is wrong in that respect, and I think we should be talking about that, not about making === into "~~, but without invoking code when it shouldn't." > Why is that true? By the rules of hyper-operation, it turns into > this: > > [1,2] ~~ sub { return 1 } > 3 ~~ sub { return 1 } > > which is true if these return true values: > > sub { return 1 }->([1,2]) > sub { return 1 }->(3) OK, so this always bothered me, I just wasn't sure why. Now I know, and I think I agree with Yuval quite a bit more. ~~ should never imply running it's data arguments as code *when dispatched at runtime*. It's: * likely to cause security problems when I accidentally compare a safe, internal structure that (probably unknown to me) contains code against an unsafe, external structure that I got from a user. * potentially a destructive comparison. * potentially not hyper-parallelization friendly * probably bad in other ways I could think of, given time. Let me boil that down to a simple assertion: comparison via ~~ which will have to perform run-time dispatch should never I to have side-effects (dynamic language, caveat, caveat...) So, I do agree that we need a new operator, but I disagree about how it should be used. I'd suggest: C<=~=> This is similar to C<~~> for arguments that are simple value types such as C or C. For objects which do not have a C<=~=> operation, C<===> is invoked. By default, the only objects which will define a C<=~=> operation will be containers, which will look like: our Bool multi submethod infix:<=~=> ($a: Container $b) { [&&] $a >>=~=<< $b; } which works for Hashes too, since a Pair is a container, so we'll just recursively hyperoperate through each of the hash's .kv Pairs, comparing them, though it might have to sort the Pairs by keys in order to assure it's comparing apples to apples. That's it. Just three types of behavior, unlike ~~s massive table of behavior. Then, in the table for C<~~>: $_ $xType of Match ImpliedMatching Code == = == ... Array Array arrays are comparablematch if $_ »=~=« $x ... Any Any run-time dispatchmatch if infix:<=~=>($_, $x) The first change is to Array/Array, and this is to minimize surprises when comparing containers. There might be a special case for containers that have typed buckets, but I'm not even going to touch that right now. The second change is to Any/Any, and that's purely a matter of putting the control in the hands of the caller, not whoever constructed the caller's data. Anything else is a debugging nightmare. In general, I would expect that no one would use =~= directly (hence the ugly, name that's longer than ~~), it's just an implementation detail of run-time dispatch on ~~ Thoughts? -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "We had some good machines, but they don't work no more." -Shriekback
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, Jul 12, 2006 at 16:16:13 -0400, Aaron Sherman wrote: > Isn't that ~~? > > Per S03: > > Array Array arrays are comparablematch if $_ »~~« $x > > ~~ is really the all-purpose, bake-your-bread, clean-your-floors, > wax-your-cat operator that you're looking for. Not at all, because: ( [ 1, 2 ], 3 ) ~~ ( { 1 }, { 1 } ) It's matching, not equality. > which is true. Ain't recursive hyperoperators grand? It isn't a hyperoperator, it's just recursive ;-) > > 2. is .id *always* a low level type representation of the object's value? > > It's > > specced that low level typed items have the same ID when they have the same > > value. What about complex types? > > It cannot be for complex types or even strings... well, at least it > I not be I we care about performance That's orthogonal. .id is used for hash keys. If you're keying y hubble images then they must be unique for some keyspace, and that's where .id makes a mapping. > =:= looks in the "symbol table" (caveat dragons) to see if LHS > refers to the same variable as the RHS. Does this dereference? > Probably not, but I'm not sure, based on S03. Then it's a purely lexical opeation, and it doesn't even work for my $x := $array[3]; $x =:= $array[3]; but i'll pretend you didn't say that ;-) -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418 pgpPMmzta8SWk.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, Jul 12, 2006 at 17:58:03 -0400, Aaron Sherman wrote: > Then ~~ is wrong in that respect, and I think we should be talking about > that, not about making === into "~~, but without invoking code when it > shouldn't." But it should! It's the smart match! If the rhs matches the code ref (the code ref gets it as an argument it's a match! That's why ~~ isn't a comparison operator, but a smart match operator - it DWIMs *very* deeply. -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418 pgpyx4u1552HO.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, Jul 12, 2006 at 16:16:13 -0400, Aaron Sherman wrote: > The other way to think about === would be that it tells you if its LHS > *could* be constant-folded onto its RHS (if it were constant for long > enough) What is the benefit here? > Because of the word "deep". Deep implies arbitrary work, which isn't > really what you want in such a low-level operator. However, using these > operator, one could easily build whatever you like. The number of times i *sigh*ed at having to reinvent deep operators in a clunky way in Perl 5 is really not in line with Perlishness and DWIM. Also ~~ is deep in exactly the same way. Perl is also not low level. I could build it, and I have, but I don't want to. It can short circuit and be faster when the structure is definitely not the same (totally different early on) or definitely the same (refaddr is equal, etc). Should I go on? > I'd avoid saying "memory", here. Some implementations of Perl 6 might > not know what memory looks like (on a sufficiently abstract VM). "Slot" -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418 pgpvVdjsJ0Et9.pgp Description: PGP signature
[svn:perl6-synopsis] r10156 - doc/trunk/design/syn
Author: larry Date: Wed Jul 12 18:05:24 2006 New Revision: 10156 Modified: doc/trunk/design/syn/S02.pod doc/trunk/design/syn/S03.pod Log: Clarifications from Smylers++ and ajs++. Modified: doc/trunk/design/syn/S02.pod == --- doc/trunk/design/syn/S02.pod(original) +++ doc/trunk/design/syn/S02.podWed Jul 12 18:05:24 2006 @@ -12,9 +12,9 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 10 Aug 2004 - Last Modified: 10 July 2006 + Last Modified: 12 July 2006 Number: 2 - Version: 49 + Version: 50 This document summarizes Apocalypse 2, which covers small-scale lexical items and typological issues. (These Synopses also contain @@ -1215,7 +1215,7 @@ way, but with any radix it's not clear whether the exponentiator should be 10 or the radix, and this makes it explicit: -0b1.1e10illegal, could be read as any of: +0b1.1e10ILLEGAL, could be read as any of: :2<1.1> * 2 ** 10 1536 :2<1.1> * 10 ** 10 15,000,000,000 @@ -1747,15 +1747,15 @@ or a method call in dot form. (It is also allowed on a label when a statement is expected.) So for any undeclared identifier "C": -foo.bar# foo().bar -- illegal postfix, must use foo().bar +foo.bar# ILLEGAL -- postfix must use foo().bar foo .bar # foo($_.bar) -- no postfix starts with whitespace -foo\ .bar # foo().bar -- illegal long dot, use foo()\ .bar -foo++ # foo()++ -- illegal postfix, must use foo()++ +foo\ .bar # ILLEGAL -- long dot must use foo()\ .bar +foo++ # ILLEGAL -- postfix must use foo()++ foo 1,2,3 # foo(1,2,3)-- args always expected after listop foo + 1# foo(+1) -- term always expected after listop foo; # foo();-- no postfix, but no args either foo: # label -- must be label at statement boundary. - -- illegal otherwise + -- ILLEGAL otherwise foo: bar: # two labels in a row, okay .foo: # $_.foo: 1 -- must be "dot" method with : args .foo(1)# $_.foo(1) -- must be "dot" method with () args @@ -1768,13 +1768,13 @@ foo $bar: 1# $bar.foo(1) -- indirect object even if declared sub -- $bar considered one token foo (bar()): # bar().foo(1) -- even if foo declared sub -foo bar(): # illegal -- bar() is two tokens. +foo bar(): # ILLEGAL -- bar() is two tokens. foo .bar: # foo(.bar:)-- colon chooses .bar to listopify foo bar baz: 1 # foo(baz.bar(1)) -- colon controls "bar", not foo. foo (bar baz): 1 # bar(baz()).foo(1) -- colon controls "foo" -$foo $bar # illegal -- two terms in a row -$foo $bar: # illegal -- use $bar.$foo for indirection -(foo bar) baz: 1 # illegal -- use $baz.$(foo bar) for indirection +$foo $bar # ILLEGAL -- two terms in a row +$foo $bar: # ILLEGAL -- use $bar.$foo for indirection +(foo bar) baz: 1 # ILLEGAL -- use $baz.$(foo bar) for indirection The indirect object colon only ever dominates a simple term, where "simple" includes classes and variables and parenthesized expressions, Modified: doc/trunk/design/syn/S03.pod == --- doc/trunk/design/syn/S03.pod(original) +++ doc/trunk/design/syn/S03.podWed Jul 12 18:05:24 2006 @@ -12,9 +12,9 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 8 Mar 2004 - Last Modified: 10 Jul 2006 + Last Modified: 12 Jul 2006 Number: 3 - Version: 45 + Version: 46 =head1 Changes to existing operators @@ -249,18 +249,18 @@ say foo ($bar+1),$baz say(foo($bar+1, $baz)); say foo .($bar+1),$baz say(foo($_.($bar+1), $baz)); -say foo[$bar+1],$baz illegal, need foo()[] -say foo.[$bar+1],$baz illegal, need foo().[] +say foo[$bar+1],$baz ILLEGAL, need foo()[] +say foo.[$bar+1],$baz ILLEGAL, need foo().[] say foo [$bar+1],$baz say(foo([$bar+1], $baz)); say foo .[$bar+1],$baz say(foo($_.[$bar+1], $baz)); -say foo{$bar+1},$baz illegal, need foo(){} -say foo.{$bar+1},$baz illegal, need foo().{} +say foo{$bar+1},$baz ILLEGAL, need foo(){} +say foo.{$bar+1},$baz ILLEGAL, need foo().{} say foo {$bar+1},$baz say(foo({$bar+1}, $baz)); say foo .{$bar+1},$baz say(foo($_.{$bar+1}, $baz));
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
Yuval Kogman wrote: On Wed, Jul 12, 2006 at 17:58:03 -0400, Aaron Sherman wrote: Then ~~ is wrong in that respect, and I think we should be talking about that, not about making === into "~~, but without invoking code when it shouldn't." But it should! It's the smart match! If the rhs matches the code ref (the code ref gets it as an argument it's a match! That's why ~~ isn't a comparison operator, but a smart match operator - it DWIMs *very* deeply DWIM generally means "don't shoot me in the head for trying this", and it can be strongly argued that C is almost certain to shoot you in the head a couple of times in your P6 career if we don't fix it. Now, I'm all for every single case that Larry put in the table for Smart Matching in S03... EXCEPT FOR RUNTIME DISPATCH! There are only two cases of runtime dispatch in there that you could possibly invoke: Array/Array and Any/Any. Fix those two, and I think ~~ DWIMs safely and just as powerfully (perhaps much more so). My suggestion (falling back to a much simpler and less dynamic =~= for runtime dispatch) is one way to fix them, and I think that if we DO fix them in that manner, then no one's expectations will be violated (unless you expected C<@a1 ~~ @a2> to be shorthand for a function vector, dot-product-like, parallel dispatch, in which case I'm going to make the suggestion that you quietly retire from public life and find a nice place in the mountains. ;-) Really, all of the magic on ~~ isn't intended for such runtime traversal of containers. it's intended for the immediate semantic value of the compile-time typed match, most notably in the case of given which has more connotations to hang semantic meaning off of in English. To invoke those special rules when recursively evaluating the "sameness" of containers doesn't even make sense if you stop and consider why you would do such a comparison. Why is C<$a ~~ $b> going to invoke code when I know nothing about $a and $b at compile time? Is that useful other than in defining an alias for ~~?
Re: Another quick one: .as
On Wed, Jul 12, 2006 at 12:51:57PM -0400, Aaron Sherman wrote: : I would assume that all classes automatically define: : : multi submethod *infix: ($self: $?CLASS) { $self } Hmm, "as" is really only intended for explicit type mutation (which can work either by role mixin or by new object construction). It's not intended to give Perl a different "view" of an unmutated object. : so that derived classes can automatically: : : $obj.as Nit: that's illegal syntax. Or rather, it's legal, but you're saying $obj.as.{'ancestor'} which is an attempt to do a hash subscript on whatever .as returns. Only () and : cause arguments to be passed to .as. So you have to write one of $obj.as(Foo)# or .(Foo), \.(Foo), etc. $obj.as: Foo (Note that those work because Foo is predeclared, presumably.) : Without actually changing their implementation details (only the type : that Perl currently thinks it's dealing with polymorphically). Perl doesn't keep track of that in general except by marking a container at compile time with the expected type. But an object is always just itself, unless you go through some kind of proxy or container. : In fact, I would expect that this bit of behind-the-curtain magic is how : the MCP arranges for polymorphism when you: : : sub foo(Object $x) {...} : my A $y; : foo($y); If you ask for the type of $x within foo(), it will tell you A, not Object. (The type of variable($x) is Object, however.) The behind-the-curtain polymorphic magic you're thinking of is really handled within the various dispatchers, which call various methods as if they were subroutines rather than methods. That's how the "lying" happens, generally. Larry