Re: First look: Advanced Polymorphism whitepaper
On Thursday 01 May 2008 06:35:12 John M. Dlugosz wrote: chromatic chromatic-at-wgz.org |Perl 6| wrote: This is why roles-as-types is so important: type inferencers can't infer allomorphism because allomorphism relies on explicitly-marked semantic meanings. What is your nomenclature here? vary in sound without changing its meaning? If I tell the type system that Foo and Bar are equivalent, then they're equivalent even if they have different internal structures and no other relationship in an inheritance sense. What are marked semantic meanings? Types. That is, in the context of Dog, bark means emit a sound. In the context of Tree, bark means the outer skin. Because guessing that bark and bark are cognates doesn't work (duck typing's false cognates) and because the internal structures don't have to be the same between actual cognates, someone has to tell the type checker that two separate entities are polymorphically equivalent. That person is the programmer, and that mechanism is the declaration that one entity performs the role of the other, or both perform the same role, or one subclasses the other. Note that you can implement polymorphic equivalence marking through subclassing in terms of roles, not vice versa. Note also that any given entity may perform multiple roles. -- c
Re: First look: Advanced Polymorphism whitepaper
HaloO, chromatic wrote: What are marked semantic meanings? Types. That is, in the context of Dog, bark means emit a sound. In the context of Tree, bark means the outer skin. Note that the only things that carry meaning in your other example my $result = $thingie.bark; are the English words in it. If you randomize all your identifiers the impression of meaning is almost gone. my $xgdfhls = $hrigo.ksjxkcj; The only thing left is that a variable is initialized with the return value of a method called on another variable. With more type annotation the two bark methods can be distinguished with higher probability. my Sound = $thingie.bark; versus my Bark = $thingie.bark; One problem with duck typing is specific to the language used for the Identifiers. E.g. in German you have bark === Rinde|bellen. But there e.g. Himmel === heaven|sky. So, if we had some meta identifier space that guarantees uniqueness and allows hooking-in localized translations you could translate my $result = $thingie.bark; to German either as mein $Ergebnis = $Ding.bellen; or mein $Ergebnis = $Ding.Rinde; A similar problem to the linguistic one above is that structural identity by far doesn't mean conceptual identity. Take e.g. the arrow type :(Num -- Num). It might be sufficient for a routine that graphs the function, or this graphing might require e.g. differentiability or continuity. How would you say that in Perl 6? role Continuous does Code:(Num -- Num) { } looks promising even though I see no way that the type checker can enforce anything here. But let's trust the programmer who composes the role into her functions. Now sub graph ( func where {.does: Continuous}, Num $from, Num $to ) {...} sub square ( Num $x -- Num ) does Continuous { return $x * $x } graph( square, -10.0, 10.0 ); # type correct The odd thing to me is that graph cannot be defined as sub graph ( Continuous func, Num $from, Num $to ) {...} or is that the same? Then how do I get what I want? I think S06 says that the above means that func returns a Continuous value as in sub foo ( Int func:(Int) -- Int) { return func(17); } sub double (Int $x -- Int) { return 2 * $x; } say foo( double ); # prints 34 My idea is that foo:( Foo f ) should mean the same as foo:( Foo $x ), that is the variables have to contain a value that does Foo. Note that this implies that sub mysub {...} occupies two slots in the surrounding namespace mysub and ::mysub. The latter is a type that can be used as sub mysubuser ( mysub f ) {...} sub yoursub does mysub {...} mysubuser( yoursub ); # OK sub blahh (Int $x) does mysub {...} # composition error Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
--- chromatic [EMAIL PROTECTED] wrote: Given: my $result = $thingie.bark; ... where $thingie may be a Dog or $thingie may be a Tree, is bark a noun or a verb? Sure, it's a lousy example, but remember the immutable law of OO didactics: all examples must be terrible. As a perhaps slightly better example: if $object.read { ... } Implemented as: method read ( -- Boolean ) { ... } (How do I specify no args and a Boolean return type?) Are we successfully 'read'ing from a pip, or is the logfile read into memory? Each of those might take no arguments and have a boolean return type. The latter *should* have a method name like 'is_read', but it's easy in the heat of the deadline to write bad method names. In this case, we have two conceptually similar methods called on different objects. This is the false cognate problem. At its core, you have no syntactic difference and reflection can't tell you that these are radically different. The only difference is semantic, and that's what the programmer has to provide. Otherwise, we're all out of jobs :) Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: First look: Advanced Polymorphism whitepaper
--- John M. Dlugosz [EMAIL PROTECTED] wrote: chromatic chromatic-at-wgz.org |Perl 6| wrote: This is why roles-as-types is so important: type inferencers can't infer allomorphism because allomorphism relies on explicitly-marked semantic meanings. What is your nomenclature here? vary in sound without changing its meaning? What are marked semantic meanings? I was curious about this myself. I always thought of allomorphism as being classes unrelated by inheritance still presenting the same set or subset of behavior. However, chromatic is attaching semantics (correct me if I'm misunderstanding), something I wasn't aware of as a requirement, but in retrospect, it makes sense. So if a class does a particular role, by relying on those methods, you get the semantic meaning (the role) attached to them and that's what we're looking for. However, the CGI/CGI::Simple example I posted earlier doesn't fulfill this. CGI::Simple offers a subset of CGI.pm's functionality and it's guaranteed to be identical (it doesn't have HTML generation functionality and the procedural/OO interfaces are clearly split). I can usually use the latter in place of the former, but since semantic meaning isn't attached, restricting me to roles doesn't work. Requiring others to use roles in this case is also too restrictive. Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: First look: Advanced Polymorphism whitepaper
HaloO, Ovid wrote: However, the CGI/CGI::Simple example I posted earlier doesn't fulfill this. CGI::Simple offers a subset of CGI.pm's functionality and it's guaranteed to be identical Then, since classes are open, the programmer can easily say CGI does CGI::Simple; and let go CGI instances wherever a CGI::Simple is expected. As added value you can get a compiler check with CGI does:strict CGI::Simple; Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- Alan Jay Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
Ovid publiustemp-perl6language2-at-yahoo.com |Perl 6| wrote: However, the CGI/CGI::Simple example I posted earlier doesn't fulfill this. CGI::Simple offers a subset of CGI.pm's functionality and it's guaranteed to be identical (it doesn't have HTML generation functionality and the procedural/OO interfaces are clearly split). I can usually use the latter in place of the former, but since semantic meaning isn't attached, restricting me to roles doesn't work. Requiring others to use roles in this case is also too restrictive. My take on it: If a Perl 6 program declares the function without typing the parameter, you can pass anything without complaint, like with Perl 5, Smalltalk, etc. If the function were declared to take a CGI object, and you had a CGI::Simple object, and they were not updated to explain the relationship, you would get a type error. Rather than needing to delete the type from the parameter, or go ahead and re-factor the classes, it is important that it be easy enough to proceed forward in the current situation and get the benefits of typing that have been added so far, without making the rest of the code useless. So, you explicitly say at the point of the call to make it fit, thus getting the old (run-time method checking) effects without having to back out the type info added thus far. sub foo (CGI) { ... }# you want to use my CGI::Simple $x .= new; foo($x);# nope, compile-time error foo(shoehorn $x); # OK, pretty much the same as if you took # the type off foo's parameter declaration A next step would be to declare once that it is OK to use CGI::Simple where a CGI is wanted, shoehorning automatically, within the scope of said instruction. I declare, CGI::Simple is an allomorph to CGI. ... foo($x); # OK. And a better later step in the evolution is for the author of CGI::Simple to explain the overlap in more detail, without having to touch the CGI class (someone else's code), that will improve upon the checking from the default match-them-all-by-name. Shoehorn sees what is missing, and adds adapters with range checks around changed parameter types, but assumes that bark==bark. The custom explanation can relax the checking, add little adapter wedges, and note when the method should not be considered a match. Also, if you further update foo's declaration to sub foo (CGI ::T $p) { ... } then you can get errors sooner rather than when the missing method is called on $p, and code within foo can incrementally change its own use of CGI to T to further the effect. That is, there is always an easy way forward. --John
Re: First look: Advanced Polymorphism whitepaper
chromatic chromatic-at-wgz.org |Perl 6| wrote: If I tell the type system that Foo and Bar are equivalent, then they're equivalent even if they have different internal structures and no other relationship in an inheritance sense. I agree. If typing is turned on, you want errors if you pass the wrong type. You have to explicitly declare that Bar is an acceptable substitute for Foo. The long-winded way is something like this: declare a coersion operator that takes Bar and returns Foo as the outside return type, but an adapted_Foo as the inside return type. create the adapted_Foo class that is Foo, and references the Bar instance, and delegates all the methods in common to the Bar, and gives error stubs for those missing. --John
Re: First look: Advanced Polymorphism whitepaper
Sex, 2008-05-02 às 14:38 +0200, TSa escreveu: Ovid wrote: However, the CGI/CGI::Simple example I posted earlier doesn't fulfill this. CGI::Simple offers a subset of CGI.pm's functionality and it's guaranteed to be identical Then, since classes are open, the programmer can easily say CGI does CGI::Simple; and let go CGI instances wherever a CGI::Simple is expected. As added value you can get a compiler check with Not really... 'does' will try to compose the CGI::Simple methods to the CGI class (although I think your example was supposed to be CGI::Simple does CGI, but anyway). You don't want to change the class implementation, you just want to annotate an additional 'interface' on the given implementation. I'm actually not sure that you can have 'CGI does CGI::Simple', since CGI::Simple is not a role... daniel
Re: First look: Advanced Polymorphism whitepaper
HaloO, Daniel Ruoso wrote: Not really... 'does' will try to compose the CGI::Simple methods to the CGI class (although I think your example was supposed to be CGI::Simple does CGI, but anyway). Hardly. Ovid said that CGI has more functionality than CGI::Simple. So the hope for CGI.does(CGI::Simple) being true is that the common parts are compatible. The other way around CGI::Simple.does(CGI) is false because of missing functionality. The idea of deriving from a base and then disabling functionality is another classical OO fallacy. You don't want to change the class implementation, you just want to annotate an additional 'interface' on the given implementation. I hope that the does operator is clever enough to find out that everything needed for CGI doing CGI::Simple is already in there. So apart from noting the nominal subtype relation somewhere in the HOW or WHAT of CGI this operation is a no-op. I'm actually not sure that you can have 'CGI does CGI::Simple', since CGI::Simple is not a role... An intermediate, anonymous class is a mere implementation detail ;) Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: sub graph ( func where {.does: Continuous}, Num $from, Num $to ) {...} sub square ( Num $x -- Num ) does Continuous { return $x * $x } graph( square, -10.0, 10.0 ); # type correct The odd thing to me is that graph cannot be defined as sub graph ( Continuous func, Num $from, Num $to ) {...} or is that the same? Then how do I get what I want? I think S06 says that the above means that func returns a Continuous value as in sub foo ( Int func:(Int) -- Int) { return func(17); } sub double (Int $x -- Int) { return 2 * $x; } say foo( double ); # prints 34 In C++, the same problem: void foo (Continuous (*f)()) // f is a function that takes nothing and returns Continuous void foo (Continuous *f) // f is a Continuous In Perl 6, within a signature sub foo ( f:(Int--Int) ) sub foo ( Continuous f ) The latter says that f is of type Continuous, not that the return type is Continuous. That is what you want, right? The latter would be sub bar ( f:(Int --Continuous) ) A closure parameter block follows the block name. The normal annotation type before the name works in the usual manner, typing the whole object. It's not like the C++ syntax at all. --John
Re: First look: Advanced Polymorphism whitepaper
Ovid publiustemp-perl6language2-at-yahoo.com |Perl 6| wrote: Implemented as: method read ( -- Boolean ) { ... } (How do I specify no args and a Boolean return type?) Take your pick: our Bool method read () { ... } method read (--Bool) { ... } method read () of Bool { ... }
Re: First look: Advanced Polymorphism whitepaper
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: Then, since classes are open, the programmer can easily say CGI does CGI::Simple; That would be class CGI is also { does CGI::Simple } and means that CGI::Simple is a role, meant to serve as an interface specification. It's not, it is a whole class that works on its own. Also the direction is backwards. It won't let you pass the CGI::Simple to the function expecting a CGI. A syntax is needed for this express concept: accept B as a substitute for A, without changing A. --John
Re: First look: Advanced Polymorphism whitepaper
On Fri, May 02, 2008 at 08:30:25AM -0500, John M. Dlugosz wrote: I agree. If typing is turned on, you want errors if you pass the wrong type. You have to explicitly declare that Bar is an acceptable substitute for Foo. Maybe we already have this--see emulates in S11. Larry
Re: First look: Advanced Polymorphism whitepaper
On Fri, May 02, 2008 at 08:47:28AM -0500, John M. Dlugosz wrote: In Perl 6, within a signature sub foo ( f:(Int--Int) ) sub foo ( Continuous f ) The latter says that f is of type Continuous, not that the return type is Continuous. That is what you want, right? The latter would be sub bar ( f:(Int --Continuous) ) Hmm, that's not how I've been thinking of it. More like arrays and hashes, where sub foo ( Dog @dogpound ) specifies that @dogpound retuns Dogs, even though you have to call it with a subscript to do so. I think you'll have to stick with sub foo ( f where Continous ) A closure parameter block follows the block name. The normal annotation type before the name works in the usual manner, typing the whole object. It's not like the C++ syntax at all. If this is a proposal, I don't think it'll fly easily. Currently sub foo ( Feline f ) is shorthand for sub foo ( f:(--Feline) ) Larry
Re: First look: Advanced Polymorphism whitepaper
Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: Sex, 2008-05-02 às 09:08 -0500, John M. Dlugosz escreveu: A syntax is needed for this express concept: accept B as a substitute for A, without changing A. Which I'm advocating as class CGI::Simple realises CGI { ... } or CGI::Simple is also { realises CGI } or even... $cgi_simple realises CGI; daniel Yes, I agree. I don't know if realizes will be without conflict of meaning after coming up with consistent nomenclature for generic specializations, role composition, and virtual type names. That is one advantage of using symbols as placeholders for now. I'll split the difference and use Allomorph to specifically mean the duck-typing effect we've been discussing. Conjugating it is tough, but I'll punt on making it roll off the tongue. The point for now is that the word is unique to my specdoc and other discussions so it can be replaced easily. I agree that you should be able to define an Allomorph as part of the class to indicate it is intended to re-implement the same interface (more or less) without having to refactor the two classes to identify that overlap and make it a defined Role. Doing it to a single object is sensible too. Some of them are vetted as such, but generally no. I also want to be able to declare an Allomorph as a scoped directive, so without adding a line into the class I can say it's OK in this scope. class CGI::Simple { ... is allomorph(CGI, :excludebark); } my CGI::Simple $x; ... allomorphism :fromCGI::Simple :toCGI; # for the duration of this scope foo($x); # no complaints, also applies details specified in allomorphism declaration All strawman for syntax. --John
Re: First look: Advanced Polymorphism whitepaper
Larry Wall larry-at-wall.org |Perl 6| wrote: On Fri, May 02, 2008 at 08:30:25AM -0500, John M. Dlugosz wrote: I agree. If typing is turned on, you want errors if you pass the wrong type. You have to explicitly declare that Bar is an acceptable substitute for Foo. Maybe we already have this--see emulates in S11. Larry Works for me. --John
Re: First look: Advanced Polymorphism whitepaper
HaloO, I wrote: I'm actually not sure that you can have 'CGI does CGI::Simple', since CGI::Simple is not a role... An intermediate, anonymous class is a mere implementation detail ;) Sorry I meant an anonymous role created from the definition of CGI::simple. Assuming compatibility of CGI with CGI::Simple this amounts to creating a WHAT that has SGI::Simple in its does-list and leave the HOW with CGI. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
On Fri, May 02, 2008 at 11:34:33AM +0200, TSa wrote: My idea is that foo:( Foo f ) should mean the same as foo:( Foo $x ), that is the variables have to contain a value that does Foo. No, I think f should be treated more like @f and %f as a composite object with a normal return type for the standard usage of the object. Just as @ already implies Array of and % already implies Hash of, so too already implies Function of. Note that this implies that sub mysub {...} occupies two slots in the surrounding namespace mysub and ::mysub. The latter is a type that can be used as sub mysubuser ( mysub f ) {...} sub yoursub does mysub {...} mysubuser( yoursub ); # OK sub blahh (Int $x) does mysub {...} # composition error I don't think most people want to think of functions as types--it just clutters up the type namespace. They can already say: sub mysubuser ( f where mysub.sig ) {...} or some such to do explicit smartmatching against the f object. Alternately if they really want the type they can say subset mysub of Code where mysub.sig; sub mysubuser ( f where mysub ) {...} # note sub mysubuser ( mysub $f ) {...} # note $ Larry
Re: First look: Advanced Polymorphism whitepaper
-- Original message -- From: TSa [EMAIL PROTECTED] HaloO, John M. Dlugosz wrote: Maybe we already have this--see emulates in S11. Works for me. For me, too. But note that we should keep does the ultimate type checker that first checks the declared presence of a role, then falls back to a declared class inheritance and then falls back to a declared emulation. What else should be in this check sequence? Do we need to consider boxed vs un-boxed, E.G. Int vs int? -- Mark Biggar [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: First look: Advanced Polymorphism whitepaper
On Friday 02 May 2008 07:08:21 John M. Dlugosz wrote: TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: Then, since classes are open, the programmer can easily say CGI does CGI::Simple; That would be class CGI is also { does CGI::Simple } and means that CGI::Simple is a role, meant to serve as an interface specification. It's not, it is a whole class that works on its own. All classes imply the existence of a role of the same name. -- c
Re: First look: Advanced Polymorphism whitepaper
mark.a.biggar-at-comcast.net |Perl 6| wrote: For me, too. But note that we should keep does the ultimate type checker that first checks the declared presence of a role, then falls back to a declared class inheritance and then falls back to a declared emulation. What else should be in this check sequence? Do we need to consider boxed vs un-boxed, E.G. Int vs int? -- For designing, we need to consider - every way you might *want* to write two different signatures - every kind of transformation or differing case in how binding works That falls under the first item. Put it on the whiteboard. multi sub call_OS_prim (int) # low-level interface code, written in C and imported. multi sub call_OS_prim (Int) # wrapper that checks for undef first, etc. #then calls the first one. Written in Perl in the module. --John
Re: First look: Advanced Polymorphism whitepaper
On Fri, May 02, 2008 at 11:15:34AM -0700, chromatic wrote: : On Friday 02 May 2008 07:08:21 John M. Dlugosz wrote: : : TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: : : Then, since classes are open, the programmer can easily say : : CGI does CGI::Simple; : : That would be : :class CGI is also { does CGI::Simple } : : and means that CGI::Simple is a role, meant to serve as an interface : specification. It's not, it is a whole class that works on its own. : : All classes imply the existence of a role of the same name. If a role is derived from a class, it must of necessity be a snapshot of the class, because roles are immutable, while classes are not. The only interesting question in my mind is whether you can take another snapshot and override the previous one somehow, or whether such derived roles should version themselves so that the snapshots can be distinguished by longname. Alternately, we make one snapshot when a class is first composed, and refuse to make any other snapshots for that name regardless of how the class under that name changes. Larry
Re: First look: Advanced Polymorphism whitepaper
HaloO, Larry Wall wrote: I don't think most people want to think of functions as types--it just clutters up the type namespace. Which contradicts their first-class status. They can already say: sub mysubuser ( f where mysub.sig ) {...} or some such to do explicit smartmatching against the f object. Didn't where always require braces? And is where unary or binary? sub foo (Int where 0..10 $x) {...} This looks more like the juxtaposition of the two constraints 'Int' and 'where 0..10' or is where binary there? Is the above identical to sub foo ($x of Int where 0..10) {...} # note of while sub foo ($x Int where 0..10) {...} is a syntax error, that perhaps needs sub foo ($x where {Int 0..10}) {...} and applys the constraint to the of type of $x. But that contradicts your usage of where below. So this is more a binary where that checks $x as a whole. But I have difficulties to get a meaning from it. The only idea is that the above fails along the lines that Int is incompatible with Scalar. That is '$x where Foo' means that the implementation type of $x has to be a subtype of Scalar just like '$x is Foo' demands exactly the implementation type Foo. Alternately if they really want the type they can say subset mysub of Code where mysub.sig; sub mysubuser ( f where mysub ) {...} # note sub mysubuser ( mysub $f ) {...} # note $ That is structural subtyping. The thing I wanted was nominal subtyping of functions. In the above f is just constraint to the mysub.sig which drops the reference to the name. And we already have a syntax for that sub foo ( f:(Int--Int) ) {...} # literal sub foo ( f:(mysub.sig) ) {...} # per reference, # perhaps needs flattening with | The important point is how does one declare that a sub implements the concept named by another sub: sub foo {...} # think: class foo sub bar is foo {...} # think: class bar is foo To conflate sub and class should actually be easy because in the background everything is an object anyway. This would e.g. allow the has declarator in a sub: sub mul (Int $x) { has Int $.factor is rw = 1; return $x * $.factor; } mul.factor = 2; say mul(3); # prints 6 I haven't thought that through but it might even be possible to drop as a sigil and get it as a prefix op. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
On Friday 02 May 2008 11:55:54 Larry Wall wrote: On Fri, May 02, 2008 at 11:15:34AM -0700, chromatic wrote: : All classes imply the existence of a role of the same name. If a role is derived from a class, it must of necessity be a snapshot of the class, because roles are immutable, while classes are not. Agreed. The only interesting question in my mind is whether you can take another snapshot and override the previous one somehow, or whether such derived roles should version themselves so that the snapshots can be distinguished by longname. Alternately, we make one snapshot when a class is first composed, and refuse to make any other snapshots for that name regardless of how the class under that name changes. I'm not sure which is best. Snapshotting at the time of first composition (or the first time someone says Hey, I provide that other class's role!) seems right though. -- c
Re: First look: Advanced Polymorphism whitepaper
HaloO, Daniel Ruoso wrote: You're taking it backwards, it's not the type checker that is aware of that, but each object's metamodel. The metamodel protocol is just the do you 'Dog'? thing. Backwards in the sequence of checks? That is we check emulation first, then class inheritance and then role doing? Or do you mean backwards in the sense that the priority is with the object somehow? But note that I regard the objects as the passive part in an object system and the system as the active part. An object checks nothing, it is checked. I understand that you implement Perl 6 with a fully OO system. But the all objects are equal doesn't work out. You need some Orwellians which are more equal. The type-checker is one of these. Of course there can be more than one checker but in a scope there's exactly one in charge at any given point in time. Other Orwellians are the compiler, the namespace manager, the grammar engine, the dispatcher etc. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
On Fri, May 02, 2008 at 12:21:27PM -0700, chromatic wrote: : On Friday 02 May 2008 11:55:54 Larry Wall wrote: : The only interesting question in my mind is whether you can take : another snapshot and override the previous one somehow, or whether : such derived roles should version themselves so that the snapshots : can be distinguished by longname. Alternately, we make one snapshot : when a class is first composed, and refuse to make any other snapshots : for that name regardless of how the class under that name changes. : : I'm not sure which is best. Snapshotting at the time of first composition (or : the first time someone says Hey, I provide that other class's role!) seems : right though. Or maybe a class is just a role that's been ORKED with a COW bit. Larry
Re: First look: Advanced Polymorphism whitepaper
HaloO, Daniel Ruoso wrote: In fact, it simply means that it's up to that object's metaobject to answer that, and not to a supra-meta-model to be able to answer to all of the possible metamodel implementations. Since all three forms are derived from a programmer's declaration involving names the problem is simple lookup, indeed. The fact that N objects share one meta object is just for reducing the memory footprint. You could make every object carry the full meta info around. You can do that as shortcuts and optimizations that are indeed needed in order to actually bootstrap the system, but that's not what the type system is. Would you be so kind to enlighten me what the type system is, if not a type calculation overlaid over a value calculation? Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
On Friday 02 May 2008 12:48:43 Larry Wall wrote: On Fri, May 02, 2008 at 12:21:27PM -0700, chromatic wrote: : I'm not sure which is best. Snapshotting at the time of first : composition (or the first time someone says Hey, I provide that other : class's role!) seems right though. Or maybe a class is just a role that's been ORKED with a COW bit. Do we face a similar rug-yanking situation with delegatee classes being modified after delegate instantiation? I know there are some types of auto-handling, but are they all automatic? -- c
Re: First look: Advanced Polymorphism whitepaper
Sex, 2008-05-02 às 18:55 +0200, TSa escreveu: For me, too. But note that we should keep does the ultimate type checker that first checks the declared presence of a role, then falls back to a declared class inheritance and then falls back to a declared emulation. What else should be in this check sequence? You're taking it backwards, it's not the type checker that is aware of that, but each object's metamodel. The metamodel protocol is just the do you 'Dog'? thing. daniel
Re: First look: Advanced Polymorphism whitepaper
Sex, 2008-05-02 às 21:49 +0200, TSa escreveu: Daniel Ruoso wrote: In fact, it simply means that it's up to that object's metaobject to answer that, and not to a supra-meta-model to be able to answer to all of the possible metamodel implementations. Since all three forms are derived from a programmer's declaration involving names the problem is simple lookup, indeed. The fact that N objects share one meta object is just for reducing the memory footprint. You could make every object carry the full meta info around. And more importantly, the fact is that they *can* carry the full meta info around, and even more importantly, they might even build completely different set of features. You can do that as shortcuts and optimizations that are indeed needed in order to actually bootstrap the system, but that's not what the type system is. Would you be so kind to enlighten me what the type system is, if not a type calculation overlaid over a value calculation? I think that migth be the key point to understand our disagreement. There's no such thing as *the* Perl 6 type system, there's *a default* type system declared in the spec, but what Perl 6 has is a *meta object protocol* that allows you to deal with several type systems at once. daniel
Re: First look: Advanced Polymorphism whitepaper
Andy_Bach-at-wiwb.uscourts.gov |Perl 6| wrote: in. Er, so would: my CGI::Simple $x .= new; my $y = CGI::Simple.new; mean that: $x whatever the compare class operater is $y is not true? Or would there be a way to tell them apart, on a class (?) level. The actual dynamic type at run time of the values in $x and $y are both CGI::Simple. The static compile-time type of $y is Any. $x.nosuchmethod; will give a compile-time error if nosuchmethod is not declared as part of CGI::Simple. $y.nosuchmethod; will look it up when the attempt is made, and only then fail. (Or succeed if something funny is going on and it exists =now= but wasn't declared originally. There are a few documented ways to be funny already.)
Re: First look: Advanced Polymorphism whitepaper
Sex, 2008-05-02 às 09:08 -0500, John M. Dlugosz escreveu: A syntax is needed for this express concept: accept B as a substitute for A, without changing A. Which I'm advocating as class CGI::Simple realises CGI { ... } or CGI::Simple is also { realises CGI } or even... $cgi_simple realises CGI; daniel
Re: First look: Advanced Polymorphism whitepaper
Sex, 2008-05-02 às 21:22 +0200, TSa escreveu: Or do you mean backwards in the sense that the priority is with the object somehow? In fact, it simply means that it's up to that object's metaobject to answer that, and not to a supra-meta-model to be able to answer to all of the possible metamodel implementations. I understand that you implement Perl 6 with a fully OO system. But the all objects are equal doesn't work out. You need some Orwellians which are more equal. The type-checker is one of these. Of course there can be more than one checker but in a scope there's exactly one in charge at any given point in time. Other Orwellians are the compiler, the namespace manager, the grammar engine, the dispatcher etc. You can do that as shortcuts and optimizations that are indeed needed in order to actually bootstrap the system, but that's not what the type system is. daniel
Re: First look: Advanced Polymorphism whitepaper
John M. Dlugosz wrote: Andy_Bach-at-wiwb.uscourts.gov |Perl 6| wrote: in. Er, so would: my CGI::Simple $x .= new; my $y = CGI::Simple.new; mean that: $x whatever the compare class operater is $y is not true? Or would there be a way to tell them apart, on a class (?) level. The actual dynamic type at run time of the values in $x and $y are both CGI::Simple. The static compile-time type of $y is Any. These are consistent with what I understand. $x.nosuchmethod; will give a compile-time error if nosuchmethod is not declared as part of CGI::Simple. Is this spec'd somewhere? I don't think we can statically know what methods CGI::Simple will have at compile time. What if I do a class CGI::Simple is also { method nosuchmethod() { ... } } inside an eval? Then it does have the method by the time we get to instantiating it, and calling the method. I think Perl 6 is just too dynamic to do these kinds of checks, without using some kind of additional (not the default) pragma saying I promise that classes don't get changed at runtime. $y.nosuchmethod; will look it up when the attempt is made, and only then fail. (Or succeed if something funny is going on and it exists =now= but wasn't declared originally. There are a few documented ways to be funny already.) Right, but I don't know that being funny should preclude you from being able to write a type constraint on a variable that makes sure we never assign anything to it that isn't compatible with CGI::Simple. Making $x.nosuchmethod; fail at compile time by default would stop you using them that way in the cases where there are more subtle things going on. I've kinda come to view Perl 6's types, unless you ask them to be more than this, as a way of saying make sure X never can happen at runtime and complain if it does, as well as giving the compiler more chances to optimize various things, rather than allowing us to do a load of type-checking stuff statically and fail at compile time. The subset types can be as complex as you like, so you can't check them statically at all, since it boils down to the halting problem, which is one thing I don't think we should require people implementing Perl 6 compilers to have to solve. ;-) Jonathan
Re: First look: Advanced Polymorphism whitepaper
Larry Wall larry-at-wall.org |Perl 6| wrote: If a role is derived from a class, According to S12: A role may not inherit from a class... it must of necessity be a snapshot of the class, because roles are immutable, while classes are not. The only interesting question in my mind is whether you can take another snapshot and override the previous one somehow, or whether such derived roles should version themselves so that the snapshots can be distinguished by longname. Alternately, we make one snapshot when a class is first composed, and refuse to make any other snapshots for that name regardless of how the class under that name changes. Larry But, the way I see it, the item listed in the role that says is Base; is declaring it from the point of view of the eventual class that composites the role. It will be processed when a class is defined by playing back the metaobject instructions to create a class, just like you had said is Base in that class's block at THAT TIME. The definition of the role simply files away is Base for later, and doesn't look to see what's in Base now for purposes of seeing which symbols are already available. No need for keeping track of snapshots. How's that? --John
Re: First look: Advanced Polymorphism whitepaper
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: Would you be so kind to enlighten me what the type system is, if not a type calculation overlaid over a value calculation? Regards, TSa. The other day I put it for those not following the scholarly stuff: The questions of “can this substitute for that?”, “if so, how?”, and “is this better or worse?” describes the meat of the *type system. * That is mainly to calm fears that the type system will make them do things they don't want, relative to Perl 5. * *
Re: First look: Advanced Polymorphism whitepaper
chromatic chromatic-at-wgz.org |Perl 6| wrote: Do we face a similar rug-yanking situation with delegatee classes being modified after delegate instantiation? I know there are some types of auto-handling, but are they all automatic? -- c In the sense that the more detailed formal documentation will need to specify exactly what happens if you try, yes. In the sense that the answer might be simple, maybe not. Off hand, I envision having to specify in what way the implementation is allowed to cache delegations by updating the class, and explain the range of allowed behavior that is still conforming. And point out that having a range of allowed behavior is always a way to allow nonportable code, so that should be a warning by default. --John
Re: First look: Advanced Polymorphism whitepaper
Jonathan Worthington jonathan-at-jnthn.net |Perl 6| wrote: $x.nosuchmethod; will give a compile-time error if nosuchmethod is not declared as part of CGI::Simple. Is this spec'd somewhere? I don't think we can statically know what methods CGI::Simple will have at compile time. What if I do a class CGI::Simple is also { method nosuchmethod() { ... } } inside an eval? Then it does have the method by the time we get to instantiating it, and calling the method. I think Perl 6 is just too dynamic to do these kinds of checks, without using some kind of additional (not the default) pragma saying I promise that classes don't get changed at runtime. Precedent in the synopses thus far mention knowing what is in the class thus far, including non-wildcard delegations. The formal wording of what happens in every case is my own particular interest. None of the notes I've made from this list's discussions address this beyond above precedent for related issues. Implementation-centric thinkers want to be assured of making dispatch tables ahead of time, and the whole idea of declaring a type is to get compile-time checking that you don't mistype a method name! Now if I can brainstorm a bit, a failure at compile-time will alert you to the problem that something funny is happening, without the need for full run-time coverage testing to spot it for you. Normally you see you used the wrong object, misspelled the name, or whatever. If you decide Oh, that's a funny case then you deliberately indicate that you want to try anyway at run-time, on that particular call, and re-compile. After all, you chose to enable strong type checking on that particular passage of code. That's what it's for. Right, but I don't know that being funny should preclude you from being able to write a type constraint on a variable that makes sure we never assign anything to it that isn't compatible with CGI::Simple. Making $x.nosuchmethod; fail at compile time by default would stop you using them that way in the cases where there are more subtle things going on. So you want a type label that says these objects are meant to be in a particular set of objects so you don't pass the wrong one or assign one to the wrong variable, but not to apply any meaning to that type beyond that. I can see applying the generics mechanism to check the code at the time it is called, not at the time it was defined, in case the type changes meaning. But that doesn't flush and re-apply if the type changes again. You can derive a new class just to give it a distinct type, to pick up changes. I see a variety of techniques for maintaining strong typing and earliest checking in light of open classes and reusing code that was compiled too soon. I can also see simply not using the strong checking features when that is getting in the way rather than helping. my $y = $x; $y.nosuchmethod; # forget strong type by using another variable $x.?nosuchmethod;# explicitly do run-time lookup if it wasn't found no typecheck :methodcall # turn off in scope my CGI::Simple ::Realtype $y = $x; # specialize generated code based on actual contents of type now. $y.nosuchmethod; # OK, I see it as part of Realtype --John
Re: First look: Advanced Polymorphism whitepaper
On Wednesday 30 April 2008 21:58:50 Brandon S. Allbery KF8NH wrote: On May 1, 2008, at 0:53 , chromatic wrote: correctness sense. Sadly, both trees and dogs bark.) Hm, no. One's a noun, the other's a verb. Given the linguistic orientation of [Perl 6], it seems a bit strange that the syntax for both is the same: while accessors and mutators are *implemented* as verbs, they should *look* like nouns. Given: my $result = $thingie.bark; ... where $thingie may be a Dog or $thingie may be a Tree, is bark a noun or a verb? Sure, it's a lousy example, but remember the immutable law of OO didactics: all examples must be terrible. Shapes, colors, and cars, -- c
Re: First look: Advanced Polymorphism whitepaper
Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: On Wed, Apr 30, 2008 at 9:58 PM, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote: On May 1, 2008, at 0:53 , chromatic wrote: correctness sense. Sadly, both trees and dogs bark.) Hm, no. One's a noun, the other's a verb. Given the linguistic orientation of Perl6, it seems a bit strange that the syntax for both is the same: while accessors and mutators are *implemented* as verbs, they should *look* like nouns. In defense of chromatic's point, both people and syrup run. Sometimes you don't even know the correct part of speech without a backtracking parser or infinite lookahead in English. The green can (continues...) be watered after it has been cut.
Re: First look: Advanced Polymorphism whitepaper
chromatic chromatic-at-wgz.org |Perl 6| wrote: This is why roles-as-types is so important: type inferencers can't infer allomorphism because allomorphism relies on explicitly-marked semantic meanings. What is your nomenclature here? vary in sound without changing its meaning? What are marked semantic meanings? --John
Re: First look: Advanced Polymorphism whitepaper
-- Original message -- From: John M. Dlugosz [EMAIL PROTECTED] Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: On Wed, Apr 30, 2008 at 9:58 PM, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote: On May 1, 2008, at 0:53 , chromatic wrote: correctness sense. Sadly, both trees and dogs bark.) Hm, no. One's a noun, the other's a verb. Given the linguistic orientation of Perl6, it seems a bit strange that the syntax for both is the same: while accessors and mutators are *implemented* as verbs, they should *look* like nouns. In defense of chromatic's point, both people and syrup run. Sometimes you don't even know the correct part of speech without a backtracking parser or infinite lookahead in English. The green can (continues...) be watered after it has been cut. And sometime you can't even do it syntactically: Time flies like an arrow. Fruit flies like a banana. -- Mark Biggar [EMAIL PROTECTED] [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: First look: Advanced Polymorphism whitepaper
Brandon S. Allbery KF8NH wrote: But there *is* some commonality there, to the extent that both are motion. This is the kind of thing that spawned this discussion, in fact: if what matters is motion, there is no reason *not* to substitute one for the other. { draw $gun }: makes a big difference whether you're talking to a gunfighter or an artist (and if the gunfighter is an artist in her days off...)
Re: First look: Advanced Polymorphism whitepaper
On Thu, May 01, 2008 at 10:02:27AM -0700, Dave Whipp wrote: Brandon S. Allbery KF8NH wrote: But there *is* some commonality there, to the extent that both are motion. This is the kind of thing that spawned this discussion, in fact: if what matters is motion, there is no reason *not* to substitute one for the other. { draw $gun }: makes a big difference whether you're talking to a gunfighter or an artist (and if the gunfighter is an artist in her days off...) Duck typing: if it walks like a duck, and talks like a duck, then you'd better duck, because the person drawing the gun is probably not an artist. Larry
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
HaloO, Daniel Ruoso wrote: [ I'm using this message to reply, because I didn't receive your reply... I'm taking it from the list history... There really seems to be something wrong with this list... ] I see all your messages arrive twice. This is not specced apparently to leave room for decision in the implementation. But there's an important question to be answered before that... what is the type returned by WHICH? Isn't that up to the implementation as well? E.g. on a 32bit platform use an unsigned 32bit integer. The only things that should not happen is that you let it leak onto the value level or that WHICHes of differently typed objects are compared. With leaking to the value level I mean allowing $x.WHICH == 42 even if it is known that WHICH is implemented with a number. But it's important to keep in mind that eqv behaviour might also be overriden by the object, that might give a canonical representation that matches the other object. Ups, no object can override eqv or any other binary method. These live outside of HOW space. You can insert your dispatch targets but that's about it. On the other hand, a 'realises' trait could change the object in order that it would still match with both 'eqv' and '===', while still '~~' to an additional type. This would be done simply by creating an anonymous class that isa the original class while overriding .^does, WHICH and eqv to shadow to the original class, and then re-blessing the object to this anonymous class. I don't understand your motivation, but I think it is the obsession with object identity. You say that the object changes class, i.e. its HOW or WHAT changes while perhaps keeping its WHICH. But eqv, === and ~~ are defined outside of the class or object system. There is an inheritance order on HOW space and a subtyping order on WHAT space. Class based dispatch goes along the former, type based dispatch along the latter. The object that changes class should not be eqv or === to itself before the transition or nominal typing becomes absurd. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
HaloO, John M. Dlugosz wrote: TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: multi infix:= (Any $lhs, A $rhs) { $lhs.STORE($rhs.clone); # or .cow if that's not automatic } $lhs.VAR.STORE. I guess I also forgot the is rw to get a binding to the caller's container not the local one of the sub. Otherwise you could write into the caller's container without rw in the sig. The issue I want to address is how easy it is to implement immutable semantics. The ref copying is sort of an annoyance there. class A { has $.a = 0; submethod BUILD ($.a) {} method inc ($self is rw:) # get at the container of { # of the caller $self = self.^new(self.a + 1); # return self.^new(self.a + 1) without the rw # sadly doesn't work for $x.inc syntax } } my A $a .= new(7); my A $b = $a; $a === $b; # true $a eqv $b; # true $a.inc; # shall behave like ++ for Int $a === $b; # false $a eqv $b; # false The spec also says that one has to use .=method to call an in-place mutator. That is $x.inc in Daniel's example should actually mean $x = $x.inc along the lines that $x++ also means $x = $x + 1. Finally combine that with the wish to allow literals of class A. Let's assume the grammar is patched to parse integer literals as As. Then with the above 7.inc gives an error because 7 is not mutable. So as I outlined before I want to care for the callers constraint. Perl 6 lacks a syntax for that. My readings have been that = just copies the ref. Unless it's a value type or immutable which just means that it doesn't matter. I'll have to read up on that some more soon. Keep us informed, please. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
--- chromatic [EMAIL PROTECTED] wrote: $p1 must be like a Point, but it needn't actually be a Point. Both $p2 and the return value must be the same type of thing that $p1 is. That was always my goal for roles in the first place. I'll be a little sad if Perl 6 requires an explicit notation to behave correctly here -- that is, if the default check is for subtyping, not polymorphic equivalence. I had initially thought this, but think about the case where someone wants to rewrite something to be compliant to another interface. If I pass a CGI::Simple object to a method expecting a CGI object, there's an excellent chance that it will *just work*, even though there's no relation between the two. In this case, a role really doesn't work. Of course, the '£' might not work either since we're not specifying that we only need a subset of the behavior to work properly. Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: First look: Advanced Polymorphism whitepaper
Qua, 2008-04-30 às 08:56 -0700, Ovid escreveu: I had initially thought this, but think about the case where someone wants to rewrite something to be compliant to another interface. If I pass a CGI::Simple object to a method expecting a CGI object, there's an excellent chance that it will *just work*, even though there's no relation between the two. In this case, a role really doesn't work. This makes me think that 'realises' has a considerably more common usage than I thought... Every time you implement something like CGI::Simple, you would like to say 'CGI::Simple realises CGI'. Of course that, in an ideal OO world, CGI would be an abstract role that both the default CGI implementation and CGI::Simple would 'do'. But that seems to javaish to me (read that as something I hate;), and having how to 'lie' about who you are seems more like a Perl thing to do... daniel
Re: First look: Advanced Polymorphism whitepaper
Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: Qua, 2008-04-30 às 08:56 -0700, Ovid escreveu: I had initially thought this, but think about the case where someone wants to rewrite something to be compliant to another interface. If I pass a CGI::Simple object to a method expecting a CGI object, there's an excellent chance that it will *just work*, even though there's no relation between the two. In this case, a role really doesn't work. This makes me think that 'realises' has a considerably more common usage than I thought... Every time you implement something like CGI::Simple, you would like to say 'CGI::Simple realises CGI'. Of course that, in an ideal OO world, CGI would be an abstract role that both the default CGI implementation and CGI::Simple would 'do'. But that seems to javaish to me (read that as something I hate;), and having how to 'lie' about who you are seems more like a Perl thing to do... daniel Especially when the fit does not have to be perfect. Part of my (unfinished overall) design is to have a way to say close enough. It will line up the stuff that fits, and put runtime checks around the stuff that doesn't. I use the keyword 'shoehorn' for this forced semi-casting g. So you can shoehorn a CGI::Simple into a CGI to call code that was written to expect strict subtyping. It will work just like non-typed message dispatch, only let you use optimized dispatch tables and document the intent and have it tell you (if you care) where the problem areas will be. --John
Re: First look: Advanced Polymorphism whitepaper
On Wednesday 30 April 2008 08:56:24 Ovid wrote: That was always my goal for roles in the first place. I'll be a little sad if Perl 6 requires an explicit notation to behave correctly here -- that is, if the default check is for subtyping, not polymorphic equivalence. I had initially thought this, but think about the case where someone wants to rewrite something to be compliant to another interface. If I pass a CGI::Simple object to a method expecting a CGI object, there's an excellent chance that it will *just work*, even though there's no relation between the two. Sure; ad hoc polymorphism allows for cognates. Not all cognates are false cognates. (If no cognates were false, duck typing would work in a correctness sense. Sadly, both trees and dogs bark.) In this case, a role really doesn't work. I think that's a non sequitur. There's no allomorphism in your example. This is why roles-as-types is so important: type inferencers can't infer allomorphism because allomorphism relies on explicitly-marked semantic meanings. -- c
Re: First look: Advanced Polymorphism whitepaper
On May 1, 2008, at 0:53 , chromatic wrote: correctness sense. Sadly, both trees and dogs bark.) Hm, no. One's a noun, the other's a verb. Given the linguistic orientation of Perl6, it seems a bit strange that the syntax for both is the same: while accessors and mutators are *implemented* as verbs, they should *look* like nouns. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH
Re: First look: Advanced Polymorphism whitepaper
On Wed, Apr 30, 2008 at 9:58 PM, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote: On May 1, 2008, at 0:53 , chromatic wrote: correctness sense. Sadly, both trees and dogs bark.) Hm, no. One's a noun, the other's a verb. Given the linguistic orientation of Perl6, it seems a bit strange that the syntax for both is the same: while accessors and mutators are *implemented* as verbs, they should *look* like nouns. In defense of chromatic's point, both people and syrup run. -- Jonathan Dataweaver Lang
Re: First look: Advanced Polymorphism whitepaper
On May 1, 2008, at 1:30 , Jon Lang wrote: On Wed, Apr 30, 2008 at 9:58 PM, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote: On May 1, 2008, at 0:53 , chromatic wrote: correctness sense. Sadly, both trees and dogs bark.) Hm, no. One's a noun, the other's a verb. Given the linguistic orientation of Perl6, it seems a bit strange that the syntax for both is the same: while accessors and mutators are *implemented* as verbs, they should *look* like nouns. In defense of chromatic's point, both people and syrup run. But there *is* some commonality there, to the extent that both are motion. This is the kind of thing that spawned this discussion, in fact: if what matters is motion, there is no reason *not* to substitute one for the other. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH
Re: First look: Advanced Polymorphism whitepaper
On Thu, May 01, 2008 at 01:34:45AM -0400, Brandon S. Allbery KF8NH wrote: On May 1, 2008, at 1:30 , Jon Lang wrote: In defense of chromatic's point, both people and syrup run. But there *is* some commonality there, to the extent that both are motion. This is the kind of thing that spawned this discussion, in fact: if what matters is motion, there is no reason *not* to substitute one for the other. Er, ask Nasa their opinion of duck typing newtons and pounds. Hey, they're both units of thrust, so they both cause motion... Me, my nose runs and my feet smell. Quack. Larry
Re: First look: Advanced Polymorphism whitepaper
On May 1, 2008, at 1:46 , Larry Wall wrote: On Thu, May 01, 2008 at 01:34:45AM -0400, Brandon S. Allbery KF8NH wrote: On May 1, 2008, at 1:30 , Jon Lang wrote: In defense of chromatic's point, both people and syrup run. But there *is* some commonality there, to the extent that both are motion. This is the kind of thing that spawned this discussion, in fact: if what matters is motion, there is no reason *not* to substitute one for the other. Er, ask Nasa their opinion of duck typing newtons and pounds. Hey, they're both units of thrust, so they both cause motion... Well, yes; but what spawned this side discussion was the whole notion of mixing things that normally wouldn't. It *is* Perlish to let you do such things, after all. (Note that strong typing would disallow this, so NASA could still have their units check.) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
HaloO, Daniel Ruoso wrote: hrmm... I might just be overlooking something... but... sub foo (Point $p) {...} means... $signature ~~ $capture means... Point $p := $capture[0] means... $capture[0] ~~ Point means... $capture[0].^does(Point) The thing is the .^does traverses the meta information to find the *named* concept Point. The FoxPoint in John's example doesn't have that and thus nominally fails the Point test. The idea is now to also have sub foo (Point $p) {...} to mean $capture[0].^like(Point) which does a *structural* analysis. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
HaloO chromatic, you wrote: That was always my goal for roles in the first place. I'll be a little sad if Perl 6 requires an explicit notation to behave correctly here -- that is, if the default check is for subtyping, not polymorphic equivalence. What is polymorphic equivalence to you? I remember us discussion the issue of duck typing versus nominal typing. I'll try to dig that out. But here is a version from memory using John's pointlike role: %hx y new midpoint = T.new(1), T.new(2), new, midpoint; where new and midpoint refer to code objects with applicable signature. Then I think that we have %h.does(Point) === False; %h.like(Point) === True; with the second test being more elaborate and hence more expensive. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
HaloO, Jon Lang wrote: What, if anything, is the significance of the fact that pointlike (in John's example; 'Point' in TSa's counterexample) is generic? Note that I didn't give a counterexample. I just used different syntax. Here values and types behave very similar. On the value level you can check 3 + 4 == 7. In a generic addition 3 + $x == 7 you can do two different things. First you can check the truths for different values of $x or you can *solve* for $x. The latter also happens in higher order type checks but of course with type variables. The type system signals an error if it can't find a suitable solution given the constraints. E.g. on the value level my Int $x; $x + $x == 7; is unsolvable. The same can happen on type level. Hope that helps, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
HaloO, Daniel Ruoso wrote: .^does *might* traverse the information as well as simply return true if the object says so. Let's not regard the problem of meta level interoperation for now. That is we have *one* meta level. The spec says that .^does asks this meta system. Now the meta system does not invent the answer! The programmer of FoxPoint has to declare that explicitly via class FoxPoint does Point {...} The point here is whom to delegate the association between FoxPoint and Point... I see only two systems: the meta and the type system. The latter is still underspecced. Even more unspecced is their interrelation. If we are to define an operator to declare that some arbitrary object conforms to some API, I would think the following as saner... sub foo(Point $p) {...}; FoxPoint $fp = ...; $fp realises Point; foo($fp); Here the spec is quite clear that 'realises' is spelled 'does'. This is the infix operator that composes a role into an object's class at runtime. This way, the dispatching mechanism is still the same (and still typed), but the object now also answers true to .^does(Point). But note that FoxPoint $fp = ...; $y = $fp; $y === $fp; # obviously true $fp does Point; $y === $fp; # false because of different HOW? Unfortunately S03 doesn't say if === checks for the same WHAT or the same HOW as precondition to checking the WHICH. Generally WHAT is also quite underspecced. Which means that the typed code remains typed and the feature is implemented as a trait that can be used to any object, thus leaving the fragile type inference to the code calling the method and not to the method that wants a stronger typing... I don't understand what you want to say here. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
Ter, 2008-04-29 às 09:28 +0200, TSa escreveu: The thing is the .^does traverses the meta information to find the *named* concept Point. The FoxPoint in John's example doesn't have that and thus nominally fails the Point test. The idea is now to also have .^does *might* traverse the information as well as simply return true if the object says so. The point here is whom to delegate the association between FoxPoint and Point... If we are to define an operator to declare that some arbitrary object conforms to some API, I would think the following as saner... sub foo(Point $p) {...}; FoxPoint $fp = ...; $fp realises Point; foo($fp); This way, the dispatching mechanism is still the same (and still typed), but the object now also answers true to .^does(Point). Which means that the typed code remains typed and the feature is implemented as a trait that can be used to any object, thus leaving the fragile type inference to the code calling the method and not to the method that wants a stronger typing... daniel
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
Ter, 2008-04-29 às 11:54 +0200, TSa escreveu: If we are to define an operator to declare that some arbitrary object conforms to some API, I would think the following as saner... sub foo(Point $p) {...}; FoxPoint $fp = ...; $fp realises Point; foo($fp); Here the spec is quite clear that 'realises' is spelled 'does'. This is the infix operator that composes a role into an object's class at runtime. Not really... 'does' is a composition operation, 'realises' would be just a type annotation that doesn't change the actual composition. This way, the dispatching mechanism is still the same (and still typed), but the object now also answers true to .^does(Point). But note that FoxPoint $fp = ...; $y = $fp; $y === $fp; # obviously true $fp does Point; $y === $fp; # false because of different HOW? Wrong. $fp is still the same object and $y would also answer true to .^does(Point). it's an in-place change, not a copy. you would need to do $y = $fp.clone(); to keep the non-typed version. Unfortunately S03 doesn't say if === checks for the same WHAT or the same HOW as precondition to checking the WHICH. It doesn't. By definition. === only checks WHICH. Generally WHAT is also quite underspecced. WHAT is implementation specific, it's underspecced for that reason. Which means that the typed code remains typed and the feature is implemented as a trait that can be used to any object, thus leaving the fragile type inference to the code calling the method and not to the method that wants a stronger typing... I don't understand what you want to say here. I mean, the code that is calling the method would be the one doing the untyped-typed mapping, not the calling sub signature (which would make the dispatch much slower). daniel
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
HaloO, Daniel Ruoso wrote: Not really... 'does' is a composition operation, 'realises' would be just a type annotation that doesn't change the actual composition. OK, but that is not in the spec yet. To me that is like the proposed 'like' operator but with the programmer taking full responsibility. Like reinterpret_cast in C++. This way, the dispatching mechanism is still the same (and still typed), but the object now also answers true to .^does(Point). But note that FoxPoint $fp = ...; $y = $fp; $y === $fp; # obviously true $fp does Point; $y === $fp; # false because of different HOW? Wrong. $fp is still the same object and $y would also answer true to .^does(Point). it's an in-place change, not a copy. you would need to do $y = $fp.clone(); First of all assignment has copy semantics. That is after $y = $fp, $y =:= $fp is false. I agree that $before := $fp; $fp does Point; $fp =:= $before; # maintain referential identity But either the HOW, the WHAT or both of $fp have to change which implies that $y === $fp can't remain true after $fp does Point. BTW, an interesting question is if a typed binding could become invalid: subset AntiPoint of Any where {not .^does(Point)} my AntiPoint $ap := $fp; # fine for now $fp does Point; # now $ap is bound to a Point which # violates the AntiPoint constraint It doesn't. By definition. === only checks WHICH. Then we must read different versions of S03. Mine has the sentence Two values are never equivalent unless they are of exactly the same type. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
HaloO, Daniel Ruoso wrote: So... class A { has $.a; method inc { $.a++ } }; $a = A.new( a = 0); $b = $a; $b.inc(); $a.inc(); say $a.a; # 2 say $b.a; # 2 Will work as expected. Depends a bit on one's expectations :) So infix:= has shallow copy semantics. IIRC, there was once an 'is deep' trait. Otherwise one has to implement multi infix:= (Any $lhs, A $rhs) { $lhs.STORE($rhs.clone); # or .cow if that's not automatic } But either the HOW, the WHAT or both of $fp have to change That is true So, even though the WHICH stays the eqv check has to change: $a = A.new( a = 0); # your class A $b = A.new( a = 0); $a === $b; # False, but $a eqv $b; # True because of snapshot semantic $b does Point; $a eqv $b; # False because HOW or WHAT is different BTW, is WHICH globally unique? Or is that also an implementation detail? The snapshot check is of course type aware: class B { has $.a; method inc { $.a++ } }; $a = A.new( a = 0); # your class A $b = B.new( a = 0); # same structural type $a eqv $b; # False because of type mismatch Funnily this implies we also need a version of eqv that uses like or duck semantics. But this seems to be foreseen. Could someone post the signature to use for eqv() to make $a and $b to compare equal structurally here? Is it eqv($a, $b, :(like A, like A))? Perhaps that can be abbreviated to eqv($a, $b, :like)? Or even infix:like with the rational that this always is a test not a modifying call like infix:does. But I would like to reserve infix:like for a type check without subsequent canonical value comparison. That is continuing from above $b.inc; $a like $b; # still true even though $a.a != $b.a Or the structural type test is similar to .does $a .like: $b; BTW, an interesting question is if a typed binding could become invalid: subset AntiPoint of Any where {not .^does(Point)} my AntiPoint $ap := $fp; # fine for now $fp does Point; # now $ap is bound to a Point which # violates the AntiPoint constraint This is a composition error that generates an exception. It even provides enough information for a compile-time error. Where is it raised? In the '$fp does Point;' statement with the error can't compose role Point because of AntiPoint binding to $ap? How would that change if the line read my AntiPoint $ap = $fp; # or with real assignment # after the declaration Would it say can't compose role Point because of AntiPoint reference in $ap? How far does that reach? I mean does the meta object system know about the constraints of all bindings and stored references to an object? Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: HaloO, Daniel Ruoso wrote: Not really... 'does' is a composition operation, 'realises' would be just a type annotation that doesn't change the actual composition. OK, but that is not in the spec yet. To me that is like the proposed 'like' operator but with the programmer taking full responsibility. Like reinterpret_cast in C++. I've not gotten that far yet, but I do envision a way to test for conformance rather than mix-in to create conformance and change things around. There might be a more primitive operation for doing than than binding a capture to a signature. I also envision that this can give the compiler information that it uses to make a cached dispatch table, but this is not visible to the user. It just means that declaring your types, even duck types will not only give compile-time checking but speed up calling for that variable. But either the HOW, the WHAT or both of $fp have to change which implies that $y === $fp can't remain true after $fp does Point. BTW, an interesting question is if a typed binding could become invalid: subset AntiPoint of Any where {not .^does(Point)} my AntiPoint $ap := $fp; # fine for now $fp does Point; # now $ap is bound to a Point which # violates the AntiPoint constraint It's not different than my Int $y = 5; subset X of Int where { $_ 5 } my X $x := $y; ++$y; The subset is part of the type of the item container. You alias it to something which is a different type of container. How can such aliasing ever be other than non-variant to be correct, unless the alias is read-only? That's no different than defining a symbol with container type MyTiedItem and then trying to alias it to a plain Scalar. Type mismatch in the := operation. --John
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: multi infix:= (Any $lhs, A $rhs) { $lhs.STORE($rhs.clone); # or .cow if that's not automatic } $lhs.VAR.STORE. My readings have been that = just copies the ref. Unless it's a value type or immutable which just means that it doesn't matter. I'll have to read up on that some more soon. --John
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
[ I'm using this message to reply, because I didn't receive your reply... I'm taking it from the list history... There really seems to be something wrong with this list... ] TSa wrote: BTW, is WHICH globally unique? Or is that also an implementation detail? This is not specced apparently to leave room for decision in the implementation. But there's an important question to be answered before that... what is the type returned by WHICH? I haven't implemented that in SMOP yet (because I have the constant identifiers that allow me to make simple pointer comparison), but I think in the low-level it will end-up being something like a native binary blob. Which means that every non-native type will, in the end, have to be reduced to native types in the WHICH call to provide a proper value for comparison. TSa wrote: So, even though the WHICH stays the eqv check has to change: $a = A.new( a = 0); # your class A $b = A.new( a = 0); $a === $b; # False, but $a eqv $b; # True because of snapshot semantic $b does Point; $a eqv $b; # False because HOW or WHAT is different But it's important to keep in mind that eqv behaviour might also be overriden by the object, that might give a canonical representation that matches the other object. An implementation of the 'realises' trait could make its canonical representation unchanged. As I said earlier, 'does' is an composition operator, it will change the class composition, therefore making it a different object. On the other hand, a 'realises' trait could change the object in order that it would still match with both 'eqv' and '===', while still '~~' to an additional type. This would be done simply by creating an anonymous class that isa the original class while overriding .^does, WHICH and eqv to shadow to the original class, and then re-blessing the object to this anonymous class. TSa wrote: But I would like to reserve infix:like for a type check without subsequent canonical value comparison. That is continuing from above $b.inc; $a like $b; # still true even though $a.a != $b.a It doesn't need to be part of the spec, it's a simple module that traverses .^methods to check if $a implements all methods described by $b. You might want to implement it already in other to reserve the name ;). daniel
Re: Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
Ter, 2008-04-29 às 14:21 +0200, TSa escreveu: Daniel Ruoso wrote: Not really... 'does' is a composition operation, 'realises' would be just a type annotation that doesn't change the actual composition. OK, but that is not in the spec yet. To me that is like the proposed 'like' operator but with the programmer taking full responsibility. Like reinterpret_cast in C++. It doesn't need to be. New traits can be implemented later. First of all assignment has copy semantics. That is after $y = $fp, $y =:= $fp is false. I agree that It will copy the scalar, which means that later change in the value cell won't propagate to the other variable. But both cells point to the same value. $a = $b; $a === $b; # TRUE $a =:= $b; # FALSE $b = $c; $a === $b; # FALSE As opposed to $a := $b; $a === $b; # TRUE $a =:= $b; # TRUE $b = $c; $a === $b; # TRUE In the later, the scalar itself is copied, which means that both variables *are* the same scalar, and changing the cell value in one is the same as changing the cell value in the other. So... class A { has $.a; method inc { $.a++ } }; $a = A.new( a = 0); $b = $a; $b.inc(); $a.inc(); say $a.a; # 2 say $b.a; # 2 Will work as expected. But either the HOW, the WHAT or both of $fp have to change That is true which implies that $y === $fp can't remain true after $fp does Point Not really... see below... BTW, an interesting question is if a typed binding could become invalid: subset AntiPoint of Any where {not .^does(Point)} my AntiPoint $ap := $fp; # fine for now $fp does Point; # now $ap is bound to a Point which # violates the AntiPoint constraint This is a composition error that generates an exception. It even provides enough information for a compile-time error. It doesn't. By definition. === only checks WHICH. Then we must read different versions of S03. Mine has the sentence Two values are never equivalent unless they are of exactly the same type. *Value types*!!! Which is not the case here, we are talking about *Object types*, also in S03: for two mutable types (object types), checks whether they have the same identity value. (For most such types the identity is simply the reference itself.) Which means that (continuing the code starting with class A)... $a = A.new(a = 0); $b = $a; $a === $b; # TRUE $b.inc; $a === $b; # TRUE daniel
Re: First look: Advanced Polymorphism whitepaper
--- John M. Dlugosz [EMAIL PROTECTED] wrote: Here is a first look at the ideas I've worked up concerning the Perl 6 type system. It's an overview of the issues and usage of higher-order types in comparison with traditional subtyping subclasses. http://www.dlugosz.com/Perl6/ Nice paper. ++ This might not be too big a deal, but the formatting of the code is a bit odd. It's not monospaced and the indentation and brace placement seem very arbitrary. Since these items are always code smells to me of a bad programmer[1], seeing it in an otherwise good paper is very jarring. Could this merely be a strange rendering artifact? Cheers, Ovid [1] Well, the monospaced bit isn't since I'm not used to programmers programming in word processors instead of text editors. Perhaps I'm spoiled :) -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: First look: Advanced Polymorphism whitepaper
Ovid publiustemp-perl6language2-at-yahoo.com |Perl 6| wrote: This might not be too big a deal, but the formatting of the code is a bit odd. It's not monospaced and the indentation and brace placement seem very arbitrary. Since these items are always code smells to me of a bad programmer[1], seeing it in an otherwise good paper is very jarring. Could this merely be a strange rendering artifact? Cheers, Ovid [1] Well, the monospaced bit isn't since I'm not used to programmers programming in word processors instead of text editors. Perhaps I'm spoiled :) The code is not monospaced, since this isn't the 1980's. I've been writing code using an editor that uses proportional fonts for years. I find it more readable, and helps fit things on a line without scrolling too. Source Insight even changes font size and color for highlighting. Function names are big and blue, for example. If the braces and positioning is funny, I wonder if it's a rendering thing. I'm using Windows and have the fonts. Could you post a screen shot and point out what's inconsistent? sub foo () { # one char indent for body ... } class { has $.x;# blocks indented 3 spaces } Closing brace is always aligned with the content it is closing. Opening may be same, or on previous line. --John
Re: First look: Advanced Polymorphism whitepaper
--- John M. Dlugosz [EMAIL PROTECTED] wrote: If the braces and positioning is funny, I wonder if it's a rendering thing. I'm using Windows and have the fonts. Could you post a screen shot and point out what's inconsistent? I see that a large part of this is that we have significantly different brace styles, so I can see your point. With the proportional font, it's still a bit difficult to see, but if you're happy with it, that's OK. I'm also on Windows, though not sure about the fonts. http://tinyurl.com/4mvnxw http://i82.photobucket.com/albums/j275/publius_ovidius/Random/polymorphism.png Glad to see the nice work, though. Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: First look: Advanced Polymorphism whitepaper
John M. Dlugosz wrote: Here is a first look at the ideas I've worked up concerning the Perl 6 type system. It's an overview of the issues and usage of higher-order types in comparison with traditional subtyping subclasses. http://www.dlugosz.com/Perl6/ Very interesting, if puzzling, read. I'm having some difficulty understanding the business with £. I _think_ that you're saying that £ sort of acts as a prefix operator that changes the meaning of the type with which it is associated; and the only time that a change in meaning occurs is if the type in question makes use of ::?CLASS or a generic parameter. You say that in Perl 6, a role normally treats ::?CLASS as referring to the role. Perhaps things have changed while I wasn't looking; but I was under the impression that Perl 6 roles try to be as transparent as possible when it comes to the class hierarchy. As such, I'd expect ::?CLASS to refer to whatever class the role is being composed into, rather than the role that's being composed. If you have need to reference the role itself, I'd expect something like ::?ROLE to be used instead. Of course, without something like your '£', the only way to decide whether you actually want the class type or the role type would be within the definition of the role itself; and without a sort of reverse '£', there would be no way to take a role that refers to ::?ROLE and make it refer to ::?CLASS instead. That said, I'm not convinced that this is a problem. As for classes and roles that have generic parameters: here, you've completely lost me. How does your proposed '£' affect such classes and roles? -- Jonathan Dataweaver Lang
Re: First look: Advanced Polymorphism whitepaper
HaloO, Jon Lang wrote: I'm having some difficulty understanding the business with £. I _think_ that you're saying that £ sort of acts as a prefix operator that changes the meaning of the type with which it is associated; and the only time that a change in meaning occurs is if the type in question makes use of ::?CLASS or a generic parameter. The difference seems to be the two definitions of bendit sub bendit (IBend ::T $p --T) { IBend $q = get_something; my T $result= $p.merge($q); return $result; } sub bendit (£ IBend ::T $p --T) { T $q = get_something; my T $result= $p.merge($q); return $result; } The interesting thing that is actually left out is the return type of get_something. I think in both cases it does the IBend role but in the second definition it is checked against the actual type T which is Thingie if called with a Thingie for $p. So the advantage of this code is that the compiler can statically complain about the return type of get_something. But I fail to see why we need £ in the signature to get that. The use of £ in sub foo (£ pointlike ::PointType $p1, PointType $p2 -- PointType) is that of *structural* subtyping. Here FoxPoint is found to be pointlike. In that I would propose again to take the 'like' operator from JavaScript 2. Doing that the role should be better named Point and foo reads: sub foo (like Point ::PointType $p1, PointType $p2 -- PointType) This is very useful to interface between typed and untyped code. With rthe 'like' the role Point has to be *nominally* available in the argument. There's no problem with 'like'-types beeing more expensive than a nominal check. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: First look: Advanced Polymorphism whitepaper
TSa wrote: The use of £ in sub foo (£ pointlike ::PointType $p1, PointType $p2 -- PointType) is that of *structural* subtyping. Here FoxPoint is found to be pointlike. In that I would propose again to take the 'like' operator from JavaScript 2. Doing that the role should be better named Point and foo reads: sub foo (like Point ::PointType $p1, PointType $p2 -- PointType) This is very useful to interface between typed and untyped code. With the 'like' the role Point has to be *nominally* available in the argument. There's no problem with 'like'-types being more expensive than a nominal check. Ah; that clears things up considerably. If I understand you correctly, John is using '£' to mean use Duck Typing here. _That_, I can definitely see uses for. As well, spelling it as 'like' instead of '£' is _much_ more readable. With this in mind, the above signature reads as $p1 must be like a Point, but it needn't actually be a Point. Both $p2 and the return value must be the same type of thing that $p1 is. What, if anything, is the significance of the fact that pointlike (in John's example; 'Point' in TSa's counterexample) is generic? -- Jonathan Dataweaver Lang
Re: First look: Advanced Polymorphism whitepaper
Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: I'm having some difficulty understanding the business with £. I _think_ that you're saying that £ sort of acts as a prefix operator that changes the meaning of the type with which it is associated; and the only time that a change in meaning occurs is if the type in question makes use of ::?CLASS or a generic parameter. Not only generic parameters, but overridden virtual type names too. In general, type names can be changed by derived classes just like methods. You say that in Perl 6, a role normally treats ::?CLASS as referring to the role. No, ::?CLASS refers to the actual class. Maybe you're confused because a footnote said to pretend it stood for the role when using the role itself as a type, because it does not exist at all. As for classes and roles that have generic parameters: here, you've completely lost me. How does your proposed '£' affect such classes and roles? The pointlike[::T] role has a generic parameter. The concrete class Point3D[Rat] matches pointlike, and it figures out that to make the match work that T has to be Rat. It figures out that FoxPoint is pointlike, if it uses Num for T.
Re: First look: Advanced Polymorphism whitepaper
chromatic wrote: Jon Lang wrote: Ah; that clears things up considerably. If I understand you correctly, John is using '£' to mean use Duck Typing here. _That_, I can definitely see uses for. As well, spelling it as 'like' instead of '£' is _much_ more readable. With this in mind, the above signature reads as $p1 must be like a Point, but it needn't actually be a Point. Both $p2 and the return value must be the same type of thing that $p1 is. That was always my goal for roles in the first place. I'll be a little sad if Perl 6 requires an explicit notation to behave correctly here -- that is, if the default check is for subtyping, not polymorphic equivalence. By my reading, the default behavior is currently nominal typing, not duck-typing. That said, my concern isn't so much about which one is the default as it is about ensuring that the programmer isn't stuck with the default. Once it's decided that Perl 6 should support both duck-typing and nominal typing, _then_ we can argue over which approach should be the default, and how to represent the other approach. -- Jonathan Dataweaver Lang
Re: First look: Advanced Polymorphism whitepaper
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: HaloO, Jon Lang wrote: I'm having some difficulty understanding the business with £. I _think_ that you're saying that £ sort of acts as a prefix operator that changes the meaning of the type with which it is associated; and the only time that a change in meaning occurs is if the type in question makes use of ::?CLASS or a generic parameter. The difference seems to be the two definitions of bendit sub bendit (IBend ::T $p --T) { IBend $q = get_something; my T $result= $p.merge($q); return $result; } sub bendit (£ IBend ::T $p --T) { T $q = get_something; my T $result= $p.merge($q); return $result; } The interesting thing that is actually left out is the return type of get_something. I think in both cases it does the IBend role but in the second definition it is checked against the actual type T which is Thingie if called with a Thingie for $p. So the advantage of this code is that the compiler can statically complain about the return type of get_something. But I fail to see why we need £ in the signature to get that. In the top example, merge has to be declared with invariant parameter types, so the actual type passed isa IBend. That means merge's parameter is IBend. If get_something returned the proper type, it would be lost. In the lower example, the merge parameter is allowed to be covariant. The actual type is not a subtype of IBend. The parameter to merge is checked to make sure it is also T. The £ means use the higher-order £ike-this rather than isa substitutability. The issue is how to give covariant parameter types =and= minimal type bounds for T at the same time. The use of £ in sub foo (£ pointlike ::PointType $p1, PointType $p2 -- PointType) is that of *structural* subtyping. Here FoxPoint is found to be pointlike. In that I would propose again to take the 'like' operator from JavaScript 2. Doing that the role should be better named Point and foo reads: sub foo (like Point ::PointType $p1, PointType $p2 -- PointType) This is very useful to interface between typed and untyped code. With rthe 'like' the role Point has to be *nominally* available in the argument. There's no problem with 'like'-types beeing more expensive than a nominal check. Yes, with Point would work for matching as well as pointlike. When the covariant parameter type destroys the isa relationship between Point and Point3D, £ Point will still indicate conformance to the like rules. I like like as the ASCII synonym to £, but didn't want to get into that in the whitepaper. I wanted to concentrate on the need for a higher-order type check, not worry about how to modify the grammar. --John
Re: First look: Advanced Polymorphism whitepaper
John M. Dlugosz wrote: TSa wrote: Jon Lang wrote: I'm having some difficulty understanding the business with £. I _think_ that you're saying that £ sort of acts as a prefix operator that changes the meaning of the type with which it is associated; and the only time that a change in meaning occurs is if the type in question makes use of ::?CLASS or a generic parameter. The difference seems to be the two definitions of bendit sub bendit (IBend ::T $p --T) { IBend $q = get_something; my T $result= $p.merge($q); return $result; } sub bendit (£ IBend ::T $p --T) { T $q = get_something; my T $result= $p.merge($q); return $result; } The interesting thing that is actually left out is the return type of get_something. I think in both cases it does the IBend role but in the second definition it is checked against the actual type T which is Thingie if called with a Thingie for $p. So the advantage of this code is that the compiler can statically complain about the return type of get_something. But I fail to see why we need £ in the signature to get that. In the top example, merge has to be declared with invariant parameter types, so the actual type passed isa IBend. That means merge's parameter is IBend. If get_something returned the proper type, it would be lost. In the lower example, the merge parameter is allowed to be covariant. The actual type is not a subtype of IBend. The parameter to merge is checked to make sure it is also T. The £ means use the higher-order £ike-this rather than isa substitutability. The issue is how to give covariant parameter types =and= minimal type bounds for T at the same time. Perhaps it would be clearer if you could illustrate the difference between sub bendit (£ IBend ::T $p --T) { T $q = get_something; my T $result= $p.merge($q); return $result; } and sub bendit (IBend ::T $p --T) { T $q = get_something; my T $result= $p.merge($q); return $result; } Or perhaps it would be clearer if I actually understood what covariant means. The use of £ in sub foo (£ pointlike ::PointType $p1, PointType $p2 -- PointType) is that of *structural* subtyping. Here FoxPoint is found to be pointlike. In that I would propose again to take the 'like' operator from JavaScript 2. Doing that the role should be better named Point and foo reads: sub foo (like Point ::PointType $p1, PointType $p2 -- PointType) This is very useful to interface between typed and untyped code. With rthe 'like' the role Point has to be *nominally* available in the argument. There's no problem with 'like'-types beeing more expensive than a nominal check. Yes, with Point would work for matching as well as pointlike. When the covariant parameter type destroys the isa relationship between Point and Point3D, £ Point will still indicate conformance to the like rules. I like like as the ASCII synonym to £, but didn't want to get into that in the whitepaper. I wanted to concentrate on the need for a higher-order type check, not worry about how to modify the grammar. OK; how does higher-order type checks vs. isa relationships differ from duck typing vs. nominal typing? -- Jonathan Dataweaver Lang
Re: First look: Advanced Polymorphism whitepaper
Andy_Bach-at-wiwb.uscourts.gov |Perl 6| wrote: Just an even simpler question: sub bendit (£ IBend ::T $p --T) { T $q = get_something; Does the T ... usage then scope the var so no 'my/our' is needed? a --- Andy Bach Systems Mangler Internet: [EMAIL PROTECTED] Voice: (608) 261-5738 Fax: 264-5932 When angry, count to four; when very angry, swear. Mark Twain Yes. ::T declares T, as a parameter, just like $p. --John
Re: First look: Advanced Polymorphism whitepaper
Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: Ah; that clears things up considerably. If I understand you correctly, John is using '£' to mean use Duck Typing here. _That_, I can definitely see uses for. As well, spelling it as 'like' instead of '£' is _much_ more readable. With this in mind, the above signature reads as $p1 must be like a Point, but it needn't actually be a Point. Both $p2 and the return value must be the same type of thing that $p1 is. What, if anything, is the significance of the fact that pointlike (in John's example; 'Point' in TSa's counterexample) is generic? It is designed for coping with generics and virtual types that have been redefined by the base class. It works for structural duck typing too, using the same algorithm. The example shows that it needs to figure out what T must be, and help show how generic classes don't have the proper isa because the types change in each specialization.
Re: First look: Advanced Polymorphism whitepaper
chromatic chromatic-at-wgz.org |Perl 6| wrote: That was always my goal for roles in the first place. I'll be a little sad if Perl 6 requires an explicit notation to behave correctly here -- that is, if the default check is for subtyping, not polymorphic equivalence. -- c Perhaps the default can be like, not isa, for cases where the actual type is being captured in a generic argument too. F-bounds type propagation only works if the actual assigned type is tracked and further propagated through use of that symbol. Making it a one-time assignment (actual type noticed when binding, and then type noted as a generic) allows the full higher-order polymorphism to work without needing to radically change the way typing works in the first place--it's the same as declaring it of that type, which the type system can handle already. That make more sense if you just read the higher order parts (pun intended; parts 18-20 or so) of The Theory of Classification (http://www.dcs.shef.ac.uk/~ajhs/classify/index.html) I will meditate on the idea of what happens if higher-order polymorphism is the default for matching. --John
Re: First look: Advanced Polymorphism whitepaper
Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: Perhaps it would be clearer if you could illustrate the difference between sub bendit (£ IBend ::T $p --T) { T $q = get_something; my T $result= $p.merge($q); return $result; } and sub bendit (IBend ::T $p --T) { T $q = get_something; my T $result= $p.merge($q); return $result; } Or perhaps it would be clearer if I actually understood what covariant means. The use of £ in sub foo (£ pointlike ::PointType $p1, PointType $p2 -- PointType) is that of *structural* subtyping. Here FoxPoint is found to be pointlike. In that I would propose again to take the 'like' operator from JavaScript 2. Doing that the role should be better named Point and foo reads: sub foo (like Point ::PointType $p1, PointType $p2 -- PointType) This is very useful to interface between typed and untyped code. With rthe 'like' the role Point has to be *nominally* available in the argument. There's no problem with 'like'-types beeing more expensive than a nominal check. Yes, with Point would work for matching as well as pointlike. When the covariant parameter type destroys the isa relationship between Point and Point3D, £ Point will still indicate conformance to the like rules. I like like as the ASCII synonym to £, but didn't want to get into that in the whitepaper. I wanted to concentrate on the need for a higher-order type check, not worry about how to modify the grammar. OK; how does higher-order type checks vs. isa relationships differ from duck typing vs. nominal typing? I think I see another whitepaper in my immediate future. And to think I was asking the same question (what is covariant) on this mailing list less than a month ago! See http://www.nntp.perl.org/group/perl.perl6.language/2008/04/msg28845.html and the reply. --John
Polymorphism and Representations (Was: Re: First look: Advanced Polymorphism whitepaper)
Seg, 2008-04-28 às 10:15 -0700, Jon Lang escreveu: Ah; that clears things up considerably. If I understand you correctly, John is using '£' to mean use Duck Typing here. _That_, I can definitely see uses for. hrmm... I might just be overlooking something... but... sub foo (Point $p) {...} means... $signature ~~ $capture means... Point $p := $capture[0] means... $capture[0] ~~ Point means... $capture[0].^does(Point) which is implementation specific, but as for what it's worth, might be abasolutely anything that says true to that call, even if it's just a reference to a pointer in a low-level binding of some library... The point I'm trying to make is that Perl 6 already accepts anything that does Point, even if it isn't a Point, that happens basically because Perl 6 have polymorphic representation. That actually means that you *never* can count on knowing how the object is implemented (except for native types, of course). So there's actually no need for the like idiom, because there's no true isa in Perl 6. In Perl 6 one object isa something as long as it says true to isa something. The only exceptions are the native types, see http://www.perlfoundation.org/perl6/index.cgi?smop_native_types for a little longer reasoning on that. daniel
Re: First look: Advanced Polymorphism whitepaper
Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: John M. Dlugosz wrote: I think I see another whitepaper in my immediate future. I look forward to it. I'll put a link to it on http://www.dlugosz.com/Perl6/, perhaps even before I'm finished with it. --John