Re: WTF? - Re: method calls on $self
On 7/14/05, Larry Wall <[EMAIL PROTECTED]> wrote: > Certainly. The problem is that there are too many viable alternatives, > and half of everyone hates half of the alternatives. > > You will know I'm no longer a benevolent dictator when I start to enjoy > watching people squirm every time I change my mind. Well, you've certainly got everyone flustered enough that they'll be overjoyed even if you pick the alternative they hated the most... :-) Aankhen
Re: User-defined infix subs/methods?
On Wed, 13 Jul 2005, Ingo Blechschmidt wrote: no, if I understood Larry correctly, you can of course write a nice grammar-modifying module, but other modules you use() still use Perl 6's standard grammar. E.g.: Ah, then of course I would have never expected things to be different at all. If you wanted the compiler to parse SomeOtherModule.pm using Ruby's grammar, you'd have to write: use Grammar::Ruby; reuse SomeOtherModule So that, after all, I don't think it would be much used since if SomeOtherModule was thought to be parsed according to Grammar::Ruby, it would take care of using it in the first place, I guess. Unless, of course, SomeOtherModule could be parsed correctly -and hopefully behave differently- under two or more different grammars, in which case it would be funny to see the effects of, say, use Grammar::Ruby; reuse SomeOtherModule; use Grammar::hq9plus; reuse SomeOtherModule; # ... which reminds me of good'ol' "GEB"... Michele -- Never attribute to malice that which can be adequately explained by stupidity - "Hanlon's Razor"
Re: What do use and require evaluate to?
Larry Wall <[EMAIL PROTECTED]> writes: > On Tue, Jul 12, 2005 at 08:48:41PM +0300, Gaal Yahas wrote: > : I propose to throw away the filesystem coupling, and map from a more > : general name of the bit of code we are requiring to a more general > : description of which instance of it we actually got. Once modules return > : interesting values, it might be useful to keep a copy of that value > : somewhere on the value side of %*INC: or else turn it inside out and > : stipulate that a standard field in the Module object is where you got > : this particular module. > > Yes, that's basically what I was mumbling about in my response. Now just > make sure %*INC is lexically scoped. > > : Probably, %*INC values should be weak references. > > Why should they be weak references? If %*INC is lexically scoped > then its entries represent this lexical scope's *real* references to > modules, and there's no need to weaken them, since it's not functioning > as some kind of cache. As long as this lexical scope sticks around, it > needs the modules it points to. As soon as the lexical scope is destroyed, > it doesn't need them any more. (Counting all closures over this lexical > scope as preserving its needfulness, until all such closures are dead > objects.) > > It's my conjecture that any explicit need for weak references probably > indicates a design failure somewhere. Something like the mis-scoping > of a reference variable, or maybe only something niggly like the > absence of a feature like "is cached" to encapsulate weak semantics. > Or maybe something as major as the lack of robust GC, in the case of > Perl 5... So long as there's some way of asking the garbage collector for everything in the live set so you can grep through them I'm sure you're right. Because almost everything is extensible at runtime a class is going to need some way of finding all its (and its subclasses) instances so it can update 'em when/if it's definition changes. I'm also trying to think how an object/database mapper could be made to work effectively without being able to keep track of all its managed objects, or would that just be handled through the use of 'is cached'?
Re: WTF? - Re: method calls on $self
Aankhen skribis 2005-07-14 12:39 (+0530): > Well, you've certainly got everyone flustered enough that they'll be > overjoyed even if you pick the alternative they hated the most... :-) It's just a Solomon judgement situation. That can work out well, but I really hate when it's forced and used to test patience. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: WTF? - Re: method calls on $self
On 7/14/05, Juerd <[EMAIL PROTECTED]> wrote: > It's just a Solomon judgement situation. That can work out well, but I > really hate when it's forced and used to test patience. If Juerd is right about this being a solomonian situation, let me just give up my baby to the other woman by saying: * "It's hers." It's not important what syntax you give it. `./` is ok, but I trust @larry to make the right choice there. * "Please don't hurt my baby." Let `.foo` still mean `$_.foo`, unconditionally. That's all that really matters. // Carl
Re: WTF? - Re: method calls on $self
If this were a straw poll, I'd say... 1. Meaning of $_ .method should mean $_.method always. Making it into a runtime error is extremely awkward; a compile-time error with detailed explanataion is acceptable but suboptimal. 2. Topicalization of $?SELF Neutral on this -- I can argue bothways. in my limited experience of writing p6 code, it is convenient but somewhat confusing to topicalize the invocant. 3. Shorthand of $?SELF.method I find ./method to be very useful in practice, and my brain gets use to it rather quickly. The association to pattern matching and division gradually fades away, at which time its novelty cease to be a problem. Thanks, /Autrijus/ pgpyMrTt9ljfK.pgp Description: PGP signature
Re: DBI v2 - The Plan and How You Can Help
On 7/14/05, Sam Vilain <[EMAIL PROTECTED]> wrote: > Of course it will be entirely possible to layer support for this sort of > thing atop any DBI interface; Exactly my point. Please be so kind as to implement your ideas in a DBI extension. Time and community will prove whether you are right by using your extension or not. Fact is, that there are quite some drivers which will never be able to adhere to your wishes. Blocking them implementing a DBI2 driver seems (to me) to be a larger problem, compared with the need of using a DBI2 subclass and not DBI2 directly. Jochen -- What are the first steps on the moon, compared to your child's?
Re: MML dispatch
Thanks for your very detailed explanation of your views on the Pure MMD scheme, Damian. I finally understand why you're opposed to it. I could never really buy your previous argument: "Manhattan distance is better". Damian writes: > Similarly, since the number of potential variants is the Cartesian product of > the total sizes of the class hierarch(y|ies) for each parameter position, > getting adequate coverage of the MMD search space quickly becomes tedious if > most of the search space is (by default) ambiguous, as in "pure ordering" > dispatch schemes. Indeed, pure MMD will be ambiguous in more cases. If you think narrowly, then it causes you to write many disambiguating cases which *usually* end up being what a manhattan metric would give you anyway. But you can get away from that terrible duplication by being more precise about your types. You can define type classes using empty roles[1], where you simply organize your type dag into abstractions that make sense to your dispatcher. The upshot of all this is that it forces you to think in a way so that the "*usually*" above becomes an "always". And it involves defining more (very small) types that make sense to humans, not gratuitously many MMD variants which are pretty hard to think about. > One very common problem with pure ordering schemes is that subsequent changes > in one or more class hierarchies can cause previously unambiguous cases to > become ambiguous, by extending a zone of ambiguity in the search space. > In > contrast, because a metric approach always fully partitions the entire search > space, hierarchy changes may alter where a particular call dispatches to, but > only ever to a "closer", more appropriate variant. You just made my primary argument against manhattan distance for me. If you change something in the middle of the class hierarchy, manhattan distance causes multimethods on the leaves to change semantics. You say that pure MMD causes them to break when a change occurs. Isn't that better than changing? Presumably you ran it through the ambiguity checker and a test suite and got it right once, and then you have to do it again when you refactor. This comes with the meaningless "unit derivation" that a metric scheme defines. Perhaps I've made this argument before, but let me just ask a question: if B derives from A, C derives from A, and D derives from C, is it sensible to say that D is "more derived" from A than B is? Now consider the following definitions: class A { } class B is A { method foo () { 1 } method bar () { 2 } method baz () { 3 } } class C is A { method foo () { 1 } } class D is C { method bar () { 2 } } Now it looks like B is more derived than D is. But that is, of course, impossible to tell. Basically I'm saying that you can't tell the relative relationship of D and B when talking about A. They're both derived by some "amount" that is impossible for a compiler to detect. What you *can* say is that D is more derived than C. In conclusion, the reason that manhattan distance scares me so, and the reason that I'm not satisfied with "use mmd 'pure'" is that for the builtins that heavily use MMD, we require *precision rather than dwimmyness*. A module author who /inserts/ a type in the standard hierarchy can change the semantics of things that aren't aware that that type even exists. If you're going to go messing with the standard types, you'd better be clear about your abstractions, and if you're not, the program deserves to die, not "dwim" around it. Oh, and the mmd style should probably look like: multi foo (...) is mmd {...} multi bar (...) is mmd {...} Rather than a pragma. > Note too that Perl 6 *will* still support a form of "pure ordered" dispatch--a > left-most-closest-match scheme like that used by CLOS--via "invocant groups": > > multi sub Foo(A: B: C:) {...} > multi sub Foo(A: D: C:) {...} > multi sub Foo(F: B: G:) {...} > > This, of course, is not "global pure ordering", but rather "left-biased pure > ordering". > > To summarize: pure ordering renders more of the MMD search space "ambiguous", > which is potentially safer but much less DWIMish. Metric schemes have far > fewer ambiguities and usually dispatch in an predictable way. Metric schemes > can still provide pure-ordering analyses via static analysis tools or special > warning modes, but pure ordering schemes can't avoid ambiguities or DWIM. > > Of course, none of this prevents: > > use MMD ; > > > Damian Luke [1] And I find this to be useful even when using manhattan distance. I'd like to be able to define such type classes out-of-band, like: role Foo defines Bar # Bar does Foo now defines Baz # Baz does Foo now { }
more .method (was: Perl 6 Summary for 2005-07-05 through 2005-07-12)
On Wed, 13 Jul 2005, Juerd wrote: > Dave Whipp skribis 2005-07-13 8:44 (-0700): > > > Within a method or submethod, C<.method> only works when C<$_ =:= > > > $?SELF>. > > >C<.method> is perfectly legal on *any* topic anywhere that $?SELF > > >doesn't exist. > > Just to be clear, this includes any method/submethod with an explicitly > > named invocant, I hope. > > No, $?SELF exists in every method. It's not the *default* invocant > variable, it's the *always there* invocant variable. There is no default > variable anywhere in the language that isn't $_. Actually I took his question to be: If I explicitly name my invocant in the method signature, does that give the compiler enough assurance that I'm not going to use .method to mean $?SELF.method, and it will allow me to safely use .method as $_.method in for and given? ~ John Williams
Re: What do use and require evaluate to?
On Thu, Jul 14, 2005 at 11:09:40AM +0100, Piers Cawley wrote: : So long as there's some way of asking the garbage collector for everything in : the live set so you can grep through them I'm sure you're right. Because almost : everything is extensible at runtime a class is going to need some way of : finding all its (and its subclasses) instances so it can update 'em when/if : it's definition changes. I'm also trying to think how an object/database mapper : could be made to work effectively without being able to keep track of all its : managed objects, or would that just be handled through the use of 'is cached'? I just said it was my conjecture. That doesn't mean I think it's right. :-) Larry
Re: User-defined infix subs/methods?
On Thu, Jul 14, 2005 at 09:19:29AM +0800, Autrijus Tang wrote: : Within perl 5, there is an extremely easy way to write that, namely : coderef in @INC that provides line-based filtering: : : http://search.cpan.org/dist/Acme-use-strict-with-pride/pride.pm : : Are we to discontinue use of [EMAIL PROTECTED], and switch to the : slightly more difficult but far more manageable approach of rebinding : &*require? I suppose that depends in part on whether we want to guarantee the @INC interface for Perl 6 at all. Or it may be that we keep @INC but make it point to abstract repositories rather than just directories. And maybe some of those repositories have an interface with active components. Or maybe @INC is a list of repository locating commands with optional arguments. Maybe @INC is *all* closures that return a package object or fail. Maybe @INC is just a fancy rule. I dunno. Nobody's actually designed the library system yet. It would be nice if it degenerated to a simple file lookup in list of a simple directories, I suppose, since that's the current Perl-think, but that doesn't mean we have to cap the abstraction at the top. I suppose what it comes down to is that we'll still have @INC, and allow closures in it, and probably pull in the standard library with a closure that knows how to load standard modules efficiently. Whether or not the standard library is represented by a closure in @INC, the standard library needs to have some kind of placeholder in the list so that users can put overrides in front of it or defaults in back of it. Or @INC has to be split into a @PREINC plus @POSTINC, but a single @INC seems simpler, and also allows multiple "standard" libraries, as long as there's some way to name them. Larry
Re: WTF? - Re: method calls on $self
On Thu, Jul 14, 2005 at 05:37:38PM +0200, Carl Mäsak wrote: > On 7/14/05, Juerd <[EMAIL PROTECTED]> wrote: > > It's just a Solomon judgement situation. That can work out well, but I > > really hate when it's forced and used to test patience. > > If Juerd is right about this being a solomonian situation, let me just > give up my baby to the other woman by saying: > > * "It's hers." It's not important what syntax you give it. `./` is ok, > but I trust @larry to make the right choice there. > > * "Please don't hurt my baby." Let `.foo` still mean `$_.foo`, > unconditionally. That's all that really matters. Yes, let .foo still mean $_.foo, unconditionally, please. The `./` is nice, but I'm willing to give up the syntax in favor of letting .foo always mean $_.foo. Autrijus joked? about $?.method once (instead of ./method), in case we need any more bad alternatives for $?SELF.method. But I also trust @larry, or %larry, or even $larry, to make a decent choice that will serve the community well. So long as .foo (pretty please) means $_.foo all the time (with sugar on top?). -kolibrie
Re: WTF? - Re: method calls on $self
Nathan Gray skribis 2005-07-14 12:55 (-0400): > Autrijus joked? about $?.method once (instead of ./method), in case we > need any more bad alternatives for $?SELF.method. But I also trust > @larry, or %larry, or even $larry, to make a decent choice that will > serve the community well. Would this mean that $? is an alias for $?SELF, or only that "$?." comes in "./"'s stead? Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Method Resolution Order question
On Wed, Jul 13, 2005 at 07:27:52PM -0400, Stevan Little wrote: : The way I am viewing the notion of "current class" for submethods : currently is: : : From inside another method or submethod: : : - a submethod should only be called from the class which defines it. This doesn't sound right to me. There is no distinction between inside or outside. A submethod is simply a method that says "These aren't the droids you're looking for" if you call it via either SMD or MMD dispatch and the first invocant isn't of the exact run-time type of the lexical class. In other words, it just has an implicit next METHOD if $?SELF != $?CLASS; at the front. So the dispatch continues until it finds either a submethod that does have an exact match or a method that isn't a submethod. : This means that since Object::bless() calls Object::BUILDALL() it is : all well and good, assuming you have not overridden bless() in your : class, and are calling it $class.bless(). No, Object::bless() (which perhaps delegates to Class.meta.bless so that different meta classes can have different .bless primitives) calls MyClass.CREATE to create the type, while will be an opaque type if that normal method dispatch runs up the tree to Object::CREATE. (But user classes are allowed to define their own CREATE method to create non-opaque objects.) After the storage is allocated, .meta.bless then calls $newobj.BUILDALL as an ordinary method call on the instance. Again this is overridable by each class, but typically goes back to Object::BUILDALL (which, as usual, probably delegates at least some of the work to the meta class). : (Object::BUILDALL of course then digs into the metaclass to call : BUILD() for all the superclasses in post-order. I am not sure how to do : that otherwise, submethod or not.) I believe there's pseudo-code for that in A12. The trick is that you can always force a call to a submethod of the "wrong" class by taking it as a sub reference and calling it like an ordinary subroutine. : However, if you define MyClass::bless, then you will need to define : MyClass::BUILDALL as well. We did not intend that people redefined .bless. It's really intended to be a primitive like .meta. The occasional redefinables are CREATE and BUILDALL, but it's really only intended that BUILD be defined typically. : Or is it possible just do $self.Object::BUILDALL()? So can I call a : submethod from a different class if I fully qualify it? No, that would just fail. You have to do the reference casting trick to call it as an ordinary subroutine. We made that hard on purpose. : From outside a method (in "user" space): : : - the invocant of the submethod must be a direct instance of the class : in which the submethod is defined. No inheritance involved. : : Maybe this is too strict, though? What do you think? There is no "user" space distinction. You still just call a method with the ordinary dispatcher, and it still just runs down the list of dispatcher class candidates till it either finds one that's a method or finds one that is a submethod and whose class matches the object's. Of course, that's highly unlikely to match a submethod on anything but the first probe, given the usual visitation order of the standard dispatcher and the fact that virtual method calls always start with the actual run-tiem type of the object, but MMD might have a different idea about order, and the same principle still applies. Plus other dispatchers are possible. The point of a submethod is that it doesn't make sense to call it on anything other than an actual object of this type (where initialization and finalization are examples of where we basically lie about the actual type because we want the various bit of the current object treated as if they were really an ancestral class even though they aren't really). Since that's the point of a submethod, the proper place to put the constraint is on the front of the submethod itself, and let it just fail to be dispatched to if it doesn't want to be dispatched to. In general, unless you are a funny dispatcher like .*foo, you shouldn't be thinking about "how you call them". : > There's some kind of "yes I mean : >you" notion in the dispatcher. It comes out in user-visible terms : >in .*foo calls but not ordinary .foo calls, : : I am not familiar with .*foo calls? Can you elaborate? This is all pretty much straight from A12. : > which call a submethod : >only when the object is actually that type, and otherwise look for an : >ancestral method of that name. : : Yes, to expand upon my above statements. The method resolution would : begin looking in the local submethod table, then move onto the local : method table, and then on up the superclass hierarchy. Is that correct? There is no separate submethod table. From the standpoint of ordinary .foo method resolution they're ordinary methods that happen to say "next METHOD" as a form of failure. The dispatcher doesn't even have to know the
Re: MML dispatch
On Thu, Jul 14, 2005 at 03:27:53PM +1200, Sam Vilain wrote: : Can I present an alternative way of viewing them, which I don't think : contradicts with what I've understood of them so far from the : Apocalypses and Synopses documents. : : First a couple of definitions; : : A "runtime class" is a package name, and a collection of functions : that form a "dispatch table". There are actually two tables - one : for private and one for public methods. Private and public methods are probably stored in a single table, but the private methods just happen to have a name starting with :. : The public table links to : "superclasses" where further dispatch may occur. Er, the concept of superclasses is not hidden in the dispatch table. Different dispatchers may have different ideas about method ordering, so the ISA information is really just passive trait data that must be interpreted by cooperation between dispatchers and meta classes. As such it's really a separate datum than the list of available methods. (Certainly, a given dispatcher might want to cache parental links in the current package's symbol table, but that's an optimization, and depends on the particular dispatcher's semantics.) : A "method" on a Role or a Class is a function that takes two : implicit arguments; a dispatch table for private method lookups, and : one for public methods lookups. The private dispatch table is bound : when the function is added to a runtime class, but the public : dispatch table is bound as late as possible (or until the class is : closed in some situations). I think you must be using "private" to mean something different than A12, but that's okay as long as we realize that. I'd prefer to couch things in terms of instantiated and uninstantiated generics, but we're probably just talking about the same things with different terms. : Here's the meat: : : A Class is then a Role that gets its runtime class created, and all : its methods' private dispatch tables bound at declaration time. I'd say the generic methods are forced to instantiate with either the default implementation provided by the role or the overriding implementation provided by the class, or by some combination of them if the class's method wants to delegate to the role's method. : A Role, on the other hand, leaves methods that can't be called, : until they are bound into a "runtime class". So they _look_ like : they are flattened as the runtime classes are composed, unless you : are introspecting to the sufficient level. : : The "runtime class" would be the ::Type objects, and the real Class and : Role objects what you get from the .meta objects. Which you consider "realer" depends on whether you're a Platonist or an Aristotelian, but okay. I would say your "runtime class" is the representative proxy for all objects of its type, while the meta classes are in charge of the dirty work. So who's "realer", the Senator who stands in front and smiles, or the Senator's aides who stand behind and frown? :-) : This might be a half empty / half full thing, I just thought you might : find that description interesting. Note that I don't deal with "state", : I'm just treating attributes as if all they are is a set of accessor : functions, which store in an unspecified&unimportant location. We're just basically assuming a role can behave like a parent class to the extent necessary to manage its state on behalf of the real object, so for instance it can have its own BUILD submethod that somehow magically gets incorporated into the object's own BUILD process. But politically the role is just that of the biological parent, not the guardian parent. You could almost think of a collection of roles as sort of a sperm and egg bank. Well, that's enough metaphors for today, at least till next week. Larry
Re: more .method (was: Perl 6 Summary for 2005-07-05 through 2005-07-12)
On Thu, Jul 14, 2005 at 12:14:57PM -0600, John Williams wrote: : Actually I took his question to be: : : If I explicitly name my invocant in the method signature, does that give : the compiler enough assurance that I'm not going to use .method to mean : $?SELF.method, and it will allow me to safely use .method as $_.method in : for and given? That question also came up in the cabal's last telecon, and I basically decided that it doesn't. If you want those assurances, a single use self; would be sufficient, even if you don't use the default of "self", or whatever self defaults to. Or we might just go ahead and provide an explicit pragma dealing with the .foo construct, but I'll be switched if I can come up with a decent name for it. use topic; though arguably use topic "it"; would tend to mean that you want to always use "it" for the topic and leave .foo for $?SELF.foo. So maybe if you say use dot; it defaults to use dot '$_'; and in general says, "I know the heck what I'm doing about dot". [From there our discussion digressed/descended into whether there should be an "I am an expert" pragma. I was dubious about any sort of non-feature-based razor.] Anyway, the people who always want to use .foo for self calls could then say use dot '$?SELF'; and then such programs could be plagued by self-dot. Larry
Re: Method Resolution Order question
Larry, Thanks for the detailed reply. Just a few more questions and I think I can get this into the metamodel :) On Jul 14, 2005, at 3:40 PM, Larry Wall wrote: On Wed, Jul 13, 2005 at 07:27:52PM -0400, Stevan Little wrote: : The way I am viewing the notion of "current class" for submethods : currently is: : : From inside another method or submethod: : : - a submethod should only be called from the class which defines it. This doesn't sound right to me. There is no distinction between inside or outside. Yes, I am not sure what I was thinking there. Shortly after I wrote this mail I did some work on submethods in the metamodel and realized how silly that idea is :) I also realized that a sepereate submethod dispatch table made no sense either, so scratch that thought out as well. A submethod is simply a method that says "These aren't the droids you're looking for" if you call it via either SMD or MMD dispatch and the first invocant isn't of the exact run-time type of the lexical class. In other words, it just has an implicit next METHOD if $?SELF != $?CLASS; at the front. So the dispatch continues until it finds either a submethod that does have an exact match or a method that isn't a submethod. Now, the metamodel currently does not have MMD, and I think "next METHOD" is not as relevant in SMD. So would it make sense to do: next SUPER if $?SELF != $?CLASS; or something like that? Here is some example code which might encounter this: class Foo { method baz { ... } } class Bar is Foo { submethod baz { ... } } class FooBar is Bar {} my $foo_bar = FooBar.new(); $foo_bar.baz() # calls Foo::baz() basically the dispatch goes from Bar::baz, which says "next SUPER" and the dispatcher then goes to Foo::baz since it is a method. Is that correct? : This means that since Object::bless() calls Object::BUILDALL() it is : all well and good, assuming you have not overridden bless() in your : class, and are calling it $class.bless(). No, Object::bless() (which perhaps delegates to Class.meta.bless so that different meta classes can have different .bless primitives) Okay, this makes sense. calls MyClass.CREATE to create the type, while will be an opaque type if that normal method dispatch runs up the tree to Object::CREATE. (But user classes are allowed to define their own CREATE method to create non-opaque objects.) After the storage is allocated, .meta.bless then calls $newobj.BUILDALL as an ordinary method call on the instance. Again this is overridable by each class, but typically goes back to Object::BUILDALL (which, as usual, probably delegates at least some of the work to the meta class). You refer to CREATE and BUILDALL as methods here, but A12 calls them submethods. Which is correct? : (Object::BUILDALL of course then digs into the metaclass to call : BUILD() for all the superclasses in post-order. I am not sure how to do : that otherwise, submethod or not.) I believe there's pseudo-code for that in A12. The trick is that you can always force a call to a submethod of the "wrong" class by taking it as a sub reference and calling it like an ordinary subroutine. Okay, this is just as dirty a trick as sneaking up into the metamodel, so I will leave it that way for now, knowing I need to change it later :) : However, if you define MyClass::bless, then you will need to define : MyClass::BUILDALL as well. We did not intend that people redefined .bless. It's really intended to be a primitive like .meta. The occasional redefinables are CREATE and BUILDALL, but it's really only intended that BUILD be defined typically. Agreed, .bless should probably never be redefined, I will pull that up into the MetaClass. : > There's some kind of "yes I mean : >you" notion in the dispatcher. It comes out in user-visible terms : >in .*foo calls but not ordinary .foo calls, : : I am not familiar with .*foo calls? Can you elaborate? This is all pretty much straight from A12. I see now, I forgot about those :) : > which call a submethod : >only when the object is actually that type, and otherwise look for an : >ancestral method of that name. : : Yes, to expand upon my above statements. The method resolution would : begin looking in the local submethod table, then move onto the local : method table, and then on up the superclass hierarchy. Is that correct? There is no separate submethod table. From the standpoint of ordinary .foo method resolution they're ordinary methods that happen to say "next METHOD" as a form of failure. Yup, realized that as soon as I tried to implement it :) Thanks, Stevan
Re: WTF? - Re: method calls on $self
On Thu, Jul 14, 2005 at 12:55:26PM -0400, Nathan Gray wrote: : So long as .foo (pretty please) means $_.foo all the time (with sugar on : top?). It means that all the time, but only when unambiguous. If you say use dot; it'll always be construed as unambigous. You could go so far as to say method foo($x) { my $y = .bar; # $_ is self call because $_ := $?SELF given $y { use dot; # "yes I know what I'm doing" when 1 { .abc } # calls $y.abc when 2 { .bcd } # calls $y.bcd } .baz; # back to self.baz } It's a little klunky but does localize the override rather visibly. Doubtless people will generally put the "use dot" at the front though. Larry
Re: Method Resolution Order question
On Thu, Jul 14, 2005 at 04:31:07PM -0400, Stevan Little wrote: : > A submethod is simply a method that says "These : >aren't the droids you're looking for" if you call it via either SMD : >or MMD dispatch and the first invocant isn't of the exact run-time : >type of the lexical class. In other words, it just has an implicit : > : >next METHOD if $?SELF != $?CLASS; : > : >at the front. So the dispatch continues until it finds either a : >submethod : >that does have an exact match or a method that isn't a submethod. : : Now, the metamodel currently does not have MMD, and I think "next : METHOD" is not as relevant in SMD. So would it make sense to do: : : next SUPER if $?SELF != $?CLASS; : : or something like that? It comes out to that under single inheritance, but under MI it might well be that the next method that ought to be called is actually a sibling method. : Here is some example code which might encounter this: : : class Foo { : method baz { ... } : } : : class Bar is Foo { : submethod baz { ... } : } : : class FooBar is Bar {} : : my $foo_bar = FooBar.new(); : $foo_bar.baz() # calls Foo::baz() : : basically the dispatch goes from Bar::baz, which says "next SUPER" and : the dispatcher then goes to Foo::baz since it is a method. : : Is that correct? It says "next METHOD", which has the same effect under SI. But we don't know whether we're under MI, and we don't know if the dispatcher we're working under has some weird order of visitation, so it's clearer to say "next METHOD" and leave it up to the dispatcher to decide if the SUPER is the next method. It *usually* is, but... : You refer to CREATE and BUILDALL as methods here, but A12 calls them : submethods. Which is correct? The default versions are methods so that they can be inherited. The individual versions defined by classes are submethods unless they intend to be inherited, and force all their subclasses into a new set of default sematics. And they're always called as methods (except when things like .* cheat). : >I believe there's pseudo-code for that in A12. The trick is that you : >can always force a call to a submethod of the "wrong" class by taking : >it as a sub reference and calling it like an ordinary subroutine. : : Okay, this is just as dirty a trick as sneaking up into the metamodel, : so I will leave it that way for now, knowing I need to change it later : :) Of course, the metamodel can do whatever dirty tricks it likes, but in Perl 6 the metamodel might actually implement this particular operation by forcing a sub call through a reference, if the metamodel is implemented in Perl 6. It's the only way we've defined to defeat the .foo dispatcher so far, from a language point of view. (Though simply calling .meta could also be construed as cheating, I guess. Or at least an authorization of cheating on your behalf.) Larry
Re: Method Resolution Order question
Larry, Thanks much, this all makes sense. :) Thanks, Stevan On Jul 14, 2005, at 4:54 PM, Larry Wall wrote: On Thu, Jul 14, 2005 at 04:31:07PM -0400, Stevan Little wrote: : Now, the metamodel currently does not have MMD, and I think "next : METHOD" is not as relevant in SMD. So would it make sense to do: : : next SUPER if $?SELF != $?CLASS; : : or something like that? It comes out to that under single inheritance, but under MI it might well be that the next method that ought to be called is actually a sibling method. This is just to clarify for me (and anyone else paying attention), because this made more sense when I "saw" it. class Foo { method baz { ... } } class Bar { submethod baz { ... } } class FooBar is Foo is Bar {} my $foo_bar = FooBar.new(); $foo_bar.baz() # calls Foo::baz() No need to respond unless I got it wrong :) : Here is some example code which might encounter this: : : class Foo { : method baz { ... } : } : : class Bar is Foo { : submethod baz { ... } : } : : class FooBar is Bar {} : : my $foo_bar = FooBar.new(); : $foo_bar.baz() # calls Foo::baz() : : basically the dispatch goes from Bar::baz, which says "next SUPER" and : the dispatcher then goes to Foo::baz since it is a method. : : Is that correct? It says "next METHOD", which has the same effect under SI. But we don't know whether we're under MI, and we don't know if the dispatcher we're working under has some weird order of visitation, so it's clearer to say "next METHOD" and leave it up to the dispatcher to decide if the SUPER is the next method. It *usually* is, but... : You refer to CREATE and BUILDALL as methods here, but A12 calls them : submethods. Which is correct? The default versions are methods so that they can be inherited. The individual versions defined by classes are submethods unless they intend to be inherited, and force all their subclasses into a new set of default sematics. And they're always called as methods (except when things like .* cheat). : >I believe there's pseudo-code for that in A12. The trick is that you : >can always force a call to a submethod of the "wrong" class by taking : >it as a sub reference and calling it like an ordinary subroutine. : : Okay, this is just as dirty a trick as sneaking up into the metamodel, : so I will leave it that way for now, knowing I need to change it later : :) Of course, the metamodel can do whatever dirty tricks it likes, but in Perl 6 the metamodel might actually implement this particular operation by forcing a sub call through a reference, if the metamodel is implemented in Perl 6. It's the only way we've defined to defeat the .foo dispatcher so far, from a language point of view. (Though simply calling .meta could also be construed as cheating, I guess. Or at least an authorization of cheating on your behalf.) Larry
Re: WTF? - Re: method calls on $self
On Thu, Jul 14, 2005 at 01:39:44PM -0700, Larry Wall wrote: > On Thu, Jul 14, 2005 at 12:55:26PM -0400, Nathan Gray wrote: > : So long as .foo (pretty please) means $_.foo all the time (with sugar on > : top?). > > It means that all the time, but only when unambiguous. If you say If .method always means $_.method ($_ being the topic) then I don't see how it is ever ambiguous. Unless I missed where nested loops would also disallow .method because people might not be able to keep track of the topic. > use dot; > > it'll always be construed as unambigous. You could go so far as to > say > > method foo($x) { > my $y = .bar; # $_ is self call because $_ := $?SELF > > given $y { use dot; # "yes I know what I'm doing" > when 1 { .abc } # calls $y.abc > when 2 { .bcd } # calls $y.bcd > } > > .baz; # back to self.baz > } Why must anything special be done in the given block to allow .method if it is always $_.method? Since I know $y is the topic in this block I know to expect $y.abc to be called. There is no ambiguity. An error here would just be confusing. Now, for those who want .abc to call $?SELF.abc within the given block then I think it would be clearer if they spelled out that intention with something like given $y { use dot '$?SELF'; # or just 'use dot' with suitable default when 1 { .abc } # calls $?SELF.abc } -- Rick Delaney [EMAIL PROTECTED]
Re: WTF? - Re: method calls on $self
On Thu, Jul 14, 2005 at 13:39:44 -0700, Larry Wall wrote: > On Thu, Jul 14, 2005 at 12:55:26PM -0400, Nathan Gray wrote: > : So long as .foo (pretty please) means $_.foo all the time (with sugar on > : top?). > > It means that all the time, but only when unambiguous. If you say > > use dot; ICK! TOO MANY CHOICES! If we have pragmas for the 99 Perl6's that every wacko wants to have, we won't have any readability. The syntax needs to be consistent and useful, even at the price of some danger. I don't want to be using a language designed for idiots - I know what I'm doing, and I like the power that perl 5 has given me. How many times have you typed map { chr } map { lc } grep { defined } and then got bummed out that you can't have grep { .is_moose } since it's in a method. That really sucks. I'd rather have '.foo' not work on $?SELF at all than have that. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me dodges cabbages like macalypse log N: neeyah! pgpaUXI5Wijpd.pgp Description: PGP signature
Re: WTF? - Re: method calls on $self
Larry Wall skribis 2005-07-14 13:39 (-0700): > On Thu, Jul 14, 2005 at 12:55:26PM -0400, Nathan Gray wrote: > : So long as .foo (pretty please) means $_.foo all the time (with sugar on > : top?). > It means that all the time, but only when unambiguous. Thus it never means $?SELF.foo without $_ being the same thing, and thus it always means $_.foo, and thus there is no ambiguity about what .foo means, and .foo can mean $_.foo even if $_ isn't $?SELF, as $?SELF is never a factor in the decision what .foo means. Good, glad that's solved. We have normality. > It's a little klunky but does localize the override rather visibly. > Doubtless people will generally put the "use dot" at the front though. Doubtless if you really insist on this "feature", Perl 6 will see its first fork very shortly after its release... But have no fear, because it will run all standard Perl 6 code too, as the thing that the fork introduces used to be an error. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: WTF? - Re: method calls on $self
Yuval Kogman skribis 2005-07-15 1:09 (+0300): > > use dot; > If we have pragmas for the 99 Perl6's that every wacko wants to > have, we won't have any readability. > The syntax needs to be consistent and useful, even at the price of > some danger. Agreed. > I don't want to be using a language designed for idiots - I know > what I'm doing, and I like the power that perl 5 has given me. Me too. > I'd rather have '.foo' not work on $?SELF at all than have that. .foo never working on $?SELF is consistent with the initial design, the idea that the default variable is always $_ (as explained very well by Damian), and the design until a few days ago. I really do not understand why Larry has changed his mind about .foo, as the meaning of .foo has not been topic of discussion for a long time now. The syntax of ./foo did receive a lot of both negative and positive attention, and I could understand that ./foo, being found ugly by some people, would be pulled out of the language in favour of some yet to invent syntax, or perhaps without replacement. That, however, has nothing to do with .foo. Or at least HAD nothing to do with .foo, until Larry decided that if $_ := $?SELF, .foo would be special all of a sudden. If that is so, then "lc" without arguments would also need to be special, as that also defaults to $_, which would then be the same thing as $?SELF, which makes things special. "lc" without arguments would also need to be forbidden, following this way of thinking. We can only hope our dictator turns benevolent again, at least regarding the one thing we all agree about (and have agreed about for quite some time): that .foo must always mean $_.foo. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Type::Class::Haskell does Role
Haskell has this very nice consistency I'll diverge into perl terms... The 'Show' role provides consistent stringification semantics for any type that does the role. It can even 'derive' the role, getting a method autogenerated. The 'Ord' role provides semantics for ordered types. A typical structure that uses this is the map - it is a sorted collection of stuff, and the key must do the 'Ord' role. And so on and so forth. Meanwhile in perl 5 land we have: * eq vs == * stringifying objects is rarely meaningful * there isn't a culture of "functional programming" like reuse - we do it on an entirely different level. Can this fit into perl 6? As I see it == is the generic comparison, and 'eq' is == with coercing parameters (in Haskell it'd be eq :: (Show a) => a -> a -> Bool or so... Isn't that lovely?) Anywho, my point is - there's lots we can borrow to make our Prelude.pm prettier, and our code a little more generic. Mechanical conversion from perl 5 can use the fully qualified instances of '==' and 'eq' in the Str and Num roles. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me beats up some cheese: neeyah! pgpwRyt0U4VsD.pgp Description: PGP signature
Optimization pipeline
I'd like to document the optimization pipeline thing I brought up in the hackathon... The intent is to plan how to balance throughput with responsiveness for a language that has such a broad range of dynamic to static typing as Perl 6 will is. With such behavior the amount of optimization you can do is limitless, but the amount you actually want to do varies... The runtime engine, environment variables, or whatever control this, it doesn't matter what the interface is, but the concept is: - optimizers stack on top of each other - the output of each one is executable - optimizers work in a coroutine, and are preemptable - optimizers are small - optimizers operate with a certain section of code in mind Basically you transform the PIL structures, or the byte code, or the resulting machine code if any, as it's going to be executed. This is old news. Optimizers get time slices to operate on code as it is needed. They get small portions - on the first run only simple optimizations are expected to actually finish. However, as code is re-executed, a proportion of the time it took to run it is spent on optimizing it, so that if code is rerun often eventually the optimizers will finish optimizing that bit of code. The goal is to achieve good responsiveness for tight edit/debug cycles, but achieve good performance for mod_perl like apps. With really crazy optimizations in a coupled compile+run environment (where parrot and the perl 6 compiler can talk to each other and rewrite code for each other) slow but busy code will eventually have enough time spent on it so that it's fast enough, but results are still available ASAP. The scenarios in which this is pleasing is high uptime, long running applications, and short scripts. Of course, the proportion of time, size of data structures, various policies should all be under control, but as a guiding principal I think that a JIT pipeline approach is the most balanced. Nothing should stop anyone from disabling everything, or pre-optimizing everything during compilation - it's just that the default trigger should the actual execution of chunks of code. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me sushi-spin-kicks : neeyah pgpSLGwKeTOMi.pgp Description: PGP signature
Re: MML dispatch
Luke wrote: Thanks for your very detailed explanation of your views on the Pure MMD scheme, Damian. I finally understand why you're opposed to it. I could never really buy your previous argument: "Manhattan distance is better". That was never my *argument*, merely my statement-of-position. ;-) Indeed, pure MMD will be ambiguous in more cases. If you think narrowly, then it causes you to write many disambiguating cases which *usually* end up being what a manhattan metric would give you anyway. But you can get away from that terrible duplication by being more precise about your types. You can define type classes using empty roles[1], where you simply organize your type dag into abstractions that make sense to your dispatcher. The upshot of all this is that it forces you to think in a way so that the "*usually*" above becomes an "always". And it involves defining more (very small) types that make sense to humans, not gratuitously many MMD variants which are pretty hard to think about. I don't see how this is a big win. You're still be forced to explicitly disambiguate. Either by defining extra variants (which is tedious), or by defining extra types (which is subtle). You just made my primary argument against manhattan distance for me. If you change something in the middle of the class hierarchy, manhattan distance causes multimethods on the leaves to change semantics. You say that pure MMD causes them to break when a change occurs. Isn't that better than changing? No. If the dispatch behaviour changes under a Manhattan metric, then it only ever changes to a more specific variant. Since MMD is all about choosing the most specific variant, that's entirely appropriate, in the light of the new information. If you change type relationships, any semantics based on type relationships must naturally change. On the other hand, under a pure ordering scheme, if you change type relationships, any semantics based on type relationships immediately *break*. That's not a graceful response to additional information. Under pure ordering, if you make a change to the type hierarchy, you have to *keep* making changes until the dispatch semantics stabilize again. For most developers that will mean a bout of "evolutionary programming", where they try adding extra types in a semi-random fashion until they seem to get the result they want. :-( Perhaps I've made this argument before, but let me just ask a question: if B derives from A, C derives from A, and D derives from C, is it sensible to say that D is "more derived" from A than B is? Now consider the following definitions: class A { } class B is A { method foo () { 1 } method bar () { 2 } method baz () { 3 } } class C is A { method foo () { 1 } } class D is C { method bar () { 2 } } Now it looks like B is more derived than D is. But that is, of course, impossible to tell. Basically I'm saying that you can't tell the relative relationship of D and B when talking about A. They're both derived by some "amount" that is impossible for a compiler to detect. What you *can* say is that D is more derived than C. Huh. I don't understand this at all. In MMD you have an argument of a given type and you're trying to find the most specifically compatible parameter. That means you only ever look upwards in a hierarchy. If your argument is of type D, then you can unequivocally say that C is more compatible than A (because they share more common components), and you can also say that B is not compatible at all. The relative derivation distances of B and D *never* matter since they can never be in competition, when viewed from the perspective of a particular argument. What we're really talking about here is how do we *combine* the compatibility measures of two or more arguments to determine the best overall fit. Pure Ordering does it in a "take my bat and go home" manner, Manhattan distance does it by weighing all arguments equally. In conclusion, the reason that manhattan distance scares me so, and the reason that I'm not satisfied with "use mmd 'pure'" is that for the builtins that heavily use MMD, we require *precision rather than dwimmyness*. A module author who /inserts/ a type in the standard hierarchy can change the semantics of things that aren't aware that that type even exists. If you're going to go messing with the standard types, you'd better be clear about your abstractions, and if you're not, the program deserves to die, not "dwim" around it. That *might* be an argument that builtins ought to do "pure ordering" dispatch, but it isn't an argument in the more general case. Most people won't be futzing around with the standard type hierarchy, except at the leaves, where it doesn't matter. Most people will be using MMD for applications development, on their own type hierarchies. Someone who's (for example) building an image processing libra
Re: Optimization pipeline
Yuval Kogman wrote: - optimizers stack on top of each other - the output of each one is executable - optimizers work in a coroutine, and are preemptable - optimizers are small - optimizers operate with a certain section of code in mind > ... Optimizers get time slices to operate on code as it is needed. They get small portions - on the first run only simple optimizations are expected to actually finish. > ... A couple of thoughts spring to mind: in these coming times of ubiquitous multi-core computing with software transaction support, perhaps it would be realistic to place optimisation on a low-priority thread. So much code is single-threaded that anything we can do to make use of dual-cores is likely to improve system efficiency. The other thing that I thought of was the question of errors detected during optimisations. It is possible that an optimiser will do a more in-depth type inference (or dataflow analysis, etc.) and find errors in the code (e.g. gcc -O2 adds warnings for uninitialised variables). This would be a compile-time error that occurs while the code is running. If a program has been running for several hours when the problem is found, what do you do with the error? Would you even want to send a warning to stderr?
Re: Optimization pipeline
There may be some tie-in with STM here too, where a particular optimization doesn't commit if the optimization gives up in the middle, or is preempted before it gets done. But maybe it's all done with cooperative multitasking. (But maybe STM is how they cooperate...) Just a half-baked thought. It's just when you said "an optimization completes" I heard "an optimization commits", which implied that an optimization could also roll back if it needed to. Larry
Re: Optimization pipeline
On Thu, Jul 14, 2005 at 06:06:24PM -0700, Dave Whipp wrote: : Yuval Kogman wrote: : : > - optimizers stack on top of each other : > - the output of each one is executable : > - optimizers work in a coroutine, and are preemptable : > - optimizers are small : > - optimizers operate with a certain section of code in mind : > : > ... : >Optimizers get time slices to operate on code as it is needed. They : >get small portions - on the first run only simple optimizations are : >expected to actually finish. : > ... : : A couple of thoughts spring to mind: in these coming times of ubiquitous : multi-core computing with software transaction support, perhaps it would : be realistic to place optimisation on a low-priority thread. So much : code is single-threaded that anything we can do to make use of : dual-cores is likely to improve system efficiency. Yes, that's kind of what I was trying to say. : The other thing that I thought of was the question of errors detected : during optimisations. It is possible that an optimiser will do a more : in-depth type inference (or dataflow analysis, etc.) and find errors in : the code (e.g. gcc -O2 adds warnings for uninitialised variables). This : would be a compile-time error that occurs while the code is running. If : a program has been running for several hours when the problem is found, : what do you do with the error? Would you even want to send a warning to : stderr? Perl 6 already defines ways for dealing with interesting values of undef, so the particular case of an uninitialized variable is already something we know might happen, and if it does happen, we kind of ignore it unless you actually try to use the initialized variable. But I understand you're asking a more general question. So maybe what the optimizer wants to do is store such messages off in some kind of "I could have told you that" location and not bring it up unless you actually run into the problem, or you ask it to tell you what warnings it was sitting on somehow. If all else fails, some kind of log file maybe. On the other hand, if you aren't ready to deal with warnings on stderr, maybe you shouldn't be running an OS that supports it... Larry
Re: WTF? - Re: method calls on $self
On Fri, Jul 15, 2005 at 01:09:57AM +0300, Yuval Kogman wrote: > On Thu, Jul 14, 2005 at 13:39:44 -0700, Larry Wall wrote: > > On Thu, Jul 14, 2005 at 12:55:26PM -0400, Nathan Gray wrote: > > : So long as .foo (pretty please) means $_.foo all the time (with sugar on > > : top?). > > > > It means that all the time, but only when unambiguous. If you say > > > > use dot; > > I'd rather have '.foo' not work on $?SELF at all than have that. Um, that's what I was hoping for too. Let .foo mean $_.foo, and never $?SELF.foo, unless of course $_ happens to contain $?SELF at that moment. (sugar, anyone?) -kolibrie
Re: Type::Class::Haskell does Role
On Fri, Jul 15, 2005 at 02:38:22AM +0300, Yuval Kogman wrote: > As I see it == is the generic comparison, and 'eq' is == with > coercing parameters (in Haskell it'd be > eq :: (Show a) => a -> a -> Bool or so... Isn't that lovely?) There is a new generic comparison operator known as ~~. The dispatch for ~~ is governed by MMD that acts on the type classes -- I mean roles -- of both sides. I wonder if we can make eg: role SmartMatchEq { method sm_eq ($x: $y) { ... } } multi infix:<~~> (SmartMatchEq $x, SmartMatchEq $y) { $x.sm_eq($y) } Is that close to what you want? Thanks, /Autrijus/ pgpcsCh4xCa7z.pgp Description: PGP signature
Re: WTF? - Re: method calls on $self
On Thu, Jul 14, 2005 at 09:38:45PM +0200, Juerd wrote: > Nathan Gray skribis 2005-07-14 12:55 (-0400): > > Autrijus joked? about $?.method once (instead of ./method), in case we > > need any more bad alternatives for $?SELF.method. But I also trust > > @larry, or %larry, or even $larry, to make a decent choice that will > > serve the community well. > > Would this mean that $? is an alias for $?SELF, or only that "$?." comes > in "./"'s stead? The former. But this is strictly a joke in response to nothingmuch's "two characters shorthand" criteria on #perl6; please don't hold it against me, or invoke the famed joke-turned-into-reality p6l device! :) Thanks, /Autrijus/ pgpiqjSf1TXa2.pgp Description: PGP signature