RE: Some Apocalypse 4 exception handling questions.
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Larry == Larry Wall [EMAIL PROTECTED] writes: Larry I think our terminology is getting sloppy here. What Larry do you mean by inherit from that method? If the Larry derived method overrides the base method, it will Larry manage its own resources, and doesn't need the base Larry method's LAST. If the derived method calls the base Larry method, the LAST of the base method will naturally Larry come along for the ride. If there is no derived Larry method, the base method also calls its own LAST as Larry a matter of course. I don't see any problem here. That's why I'm still puzzled about what it means to inherit PRE/POST as well. A block of code doesn't have a superclass. What exactly are you inheriting from? I don't think PRE/POST are going to be part of the resources of a code block. They are part of the resources of a method. I don't know if they have any value in procedures. Perhaps only methods will be allowed PRE/POST? If you call super from a method, surely the super will have its own PRE/POST, and then there's no need to inherit it. If you don't call super, how do you know the PRE/POST of a similar subroutine in a superclass that you're completely overriding should even apply? For DBC you want to inherit the SUPER's PRE/POST conditions even if you override the method's implementation. I don't thing PRE/POST apply to procedure subroutine, just the subroutines which are methods. Assuming we confine talk of PRE/POST to classes and methods... I think the latter statement about knowing when the PRE/POST of an inherited method/subroutine applies resolves itself. So, does it make any sense at all to talk about inheriting PRE/POST as a separate act, other than the natural block start/end from calling super at the right time? Yes. As you might override the super's implementation, but still need to satisfy its PRE/POST conditions.
RE: Some Apocalypse 4 exception handling questions.
From: Glenn Linderman [mailto:[EMAIL PROTECTED]] Graham Barr wrote: But the base class may be just an interface class. And thus by inheriting the pre conditions you are enforcing the API. So I can see a use for it, but I can also see where you don't want it too. So if the base class is just an interface class, then you cannot usefully inherit the methods, without winding up with just another interface class. Of course, that sometimes is useful too. Yes. For instance when making an implementation of the interface. The interface class can define the interface using abstract methods with PRE/POST conditions to specify what inputs are required and guarantee the output that will result. The implementation classes pick it up and go on from there. So maybe your point was that when you replace a method from a base class that you only have 1 subroutine for that method, the replacement one, because there wasn't really one there in the interface class to inherit? Exactly. I'd still like to hear Larry comment on the benefits vs dangers of having the PRE and POST conditions defined within the implementation block of a method, as opposed to defined outside. The more I think about it, the more convinced I am that the natural place to define the pre and post conditions is outside the implementation block, to prevent them from referencing lexically scoped variables of the implementation... or have a compiler rule preventing it. Otherwise they could be impossible to evaluate in the context of an inherited (replacement) method. I think this has already been covered by the no-side effects rule for PRE-/POST- Conditions. Which Damian suggested could be implemented by: Damian Conway wrote: By prohibiting mutation of variables not lexical to the block, forbidding I/O, allowing calls only to already-defined subs, and applying the same restrictions recursively to those subs.
RE: Some Apocalypse 4 exception handling questions.
From: Garrett Goebel [mailto:[EMAIL PROTECTED]] From: Glenn Linderman [mailto:[EMAIL PROTECTED]] So maybe your point was that when you replace a method from a base class that you only have 1 subroutine for that method, the replacement one, because there wasn't really one there in the interface class to inherit? Exactly. Well, I should probably qualify that a bit. There'd still be only one implementation for a single-dispatch method in the derived class, even if the one derived from the super wasn't just an abstract. And this is just looking at it in the simple case. When multiple-dispatch comes into the picture, then we'll have different invokations of the same method being dispatched to different implementations depending on the parameter list. I wonder how PRE/POST will work once that can of worms has been opened? So which Apoc will be the OO one?
RE: Some Apocalypse 4 exception handling questions.
On Thu, 2002-01-24 at 08:48, Garrett Goebel asked: So which Apoc will be the OO one? Apoc 12, to go by the chapters of the 3rd Camel. David -- David Wheeler AIM: dwTheory [EMAIL PROTECTED] ICQ: 15726394 Yahoo!: dew7e Jabber: [EMAIL PROTECTED]
Re: Some Apocalypse 4 exception handling questions.
On Wed, Jan 23, 2002 at 06:00:21PM -0500, Melvin Smith wrote: final and private are completely different concepts as I understand them. I wouldn't say completely different. They are both used for enforcement of similar means, but you are correct, they are different. I view final as being most useful in an optimization sense. A final method may be safely inlined, and does not require a vtable entry. - Damien
Re: Some Apocalypse 4 exception handling questions.
Garrett Goebel writes: : And this is just looking at it in the simple case. When multiple-dispatch : comes into the picture, then we'll have different invokations of the same : method being dispatched to different implementations depending on the : parameter list. I wonder how PRE/POST will work once that can of worms has : been opened? I strongly suspect that DbC and multimethods are, at best, orthogonal. My gut level feeling is that multimethod calls look like ordinary subroutine calls, and the method eventually selected evaluates only its own PRE/POST conditions, which could perhaps explicitly delegate to other PRE/POST conditions. If you want more than that, you'll have to give me a PhD. :-) Larry
Re: Some Apocalypse 4 exception handling questions.
Damien Neil writes: : On Wed, Jan 23, 2002 at 06:00:21PM -0500, Melvin Smith wrote: : final and private are completely different concepts as I understand : them. : : I wouldn't say completely different. They are both used for enforcement : of similar means, but you are correct, they are different. : : I view final as being most useful in an optimization sense. A final : method may be safely inlined, and does not require a vtable entry. That may be a choice that is best left up to the user code, not the class. As a class designer, you really can't know if someone is going to want to derive from your class someday, but as a mere mortal writing a specific application, you can sometimes be pretty sure that you're not interested in dealing with more derived data. Plus you know where your tight loops are, and where you're willing to trade off future generality for current performance. Larry
Re: Some Apocalypse 4 exception handling questions.
On Thu, Jan 24, 2002 at 10:48:45AM -0600, Garrett Goebel wrote: When multiple-dispatch comes into the picture, then we'll have different invokations of the same method being dispatched to different implementations depending on the parameter list. I wonder how PRE/POST will work once that can of worms has been opened? Me too. I'm sure it'll be something like this (only better :-) sub bar is pre { ... }; # precondition for all bars sub bar is pre { ... } ($foo) { ... } # precondition for this bar with an is multi thrown in there probably. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
RE: Some Apocalypse 4 exception handling questions.
From: Larry Wall [mailto:[EMAIL PROTECTED]] Garrett Goebel writes: : And this is just looking at it in the simple case. When : multiple-dispatch comes into the picture, then we'll : have different invokations of the same method being : dispatched to different implementations depending on : the parameter list. I wonder how PRE/POST will work : once that can of worms has been opened? I strongly suspect that DbC and multimethods are, at best, orthogonal. My gut level feeling is that multimethod calls look like ordinary subroutine calls, and the method eventually selected evaluates only its own PRE/POST conditions, which could perhaps explicitly delegate to other PRE/POST conditions. If you want more than that, you'll have to give me a PhD. :-) I thought I had ;) That is after all, one of the reasons why I'm a continuing contributor to the Damian Conway fund. Would it be as easy as allowing global PRE/POST condition blocks to be associated with an abstract method, and having a derived multimethod's implementation inherit the PRE/POST conditions from those inherited implementations which match the same parameter list? Er... for some definition of match. That's a gross oversimplification isn't it?
Re: Some Apocalypse 4 exception handling questions.
Garrett Goebel writes: : --_=_NextPart_001_01C1A506.D9BE78D0 : Content-Type: text/plain; : charset=iso-8859-1 : : From: Larry Wall [mailto:[EMAIL PROTECTED]] : : Garrett Goebel writes: : : And this is just looking at it in the simple case. When : : multiple-dispatch comes into the picture, then we'll : : have different invokations of the same method being : : dispatched to different implementations depending on : : the parameter list. I wonder how PRE/POST will work : : once that can of worms has been opened? : : I strongly suspect that DbC and multimethods are, at best, orthogonal. : My gut level feeling is that multimethod calls look like ordinary : subroutine calls, and the method eventually selected evaluates only : its own PRE/POST conditions, which could perhaps explicitly : delegate to other PRE/POST conditions. If you want more than that, : you'll have to give me a PhD. :-) : : I thought I had ;) : : That is after all, one of the reasons why I'm a continuing contributor to : the Damian Conway fund. And that is very much appreciated by all of us! : Would it be as easy as allowing global PRE/POST condition blocks to be : associated with an abstract method, and having a derived multimethod's : implementation inherit the PRE/POST conditions from those inherited : implementations which match the same parameter list? Er... for some : definition of match. That's a gross oversimplification isn't it? Every statement about DbC is oversimplified. Every statement about multimethods is oversimplified. Every statement about both is doubly oversimplified. Whether that's gross is simply a matter of taste. Larry
Re: Some Apocalypse 4 exception handling questions.
Larry wrote: : I strongly suspect that DbC and multimethods are, at best,. : orthogonal My gut level feeling is that multimethod calls look : like ordinary subroutine calls, and the method eventually : selected evaluates only its own PRE/POST conditions, which could : perhaps explicitly delegate to other PRE/POST conditions. If you : want more than that,you'll have to give me a PhD. :-) : : I thought I had ;) : : That is after all, one of the reasons why I'm a continuing : contributor to the Damian Conway fund. And that is very much appreciated by all of us! I'll say! ;-) And yes, I am thinking (deeply, I hope) about these issues. The first point to bear in mind is that multimethods do not enjoy the same well-ordered inheritance relationships that singly dispatched methods do. In fact, in the general case, it does not make sense to talk of one multimethod variant inheriting from another. A multimethod does not belong to a particular class (not even the one it happens to be defined in). Moreover, that definitional class plays no role in determining which variant of a multimethod is invoked on a particular set of arguments. I certainly agree that multiply dispatched subroutines should have PRE and POST blocks, but it I see no need to, means of, or sense in attempting to define relationships between variants that would permit inheritance of those constraints. As far as I am concerned, Larry's gut level reaction is spot on. Damian
Re: Some Apocalypse 4 exception handling questions.
On Tue, 22 Jan 2002 10:03:08 -0800 (PST), Larry Wall wrote: At the moment, I see this: -2. PRE in order, inherited, no side effects -1. FIRST in order 0. inline code normal flow 1. CATCH, CONTROLsingular 2. NEXT, LAST, KEEP, UNDOin reverse order 3. POST in reverse order, inherited, no side effects This is all very sensible, and I completely agree with it. However, don't we need some restrictions on what can go in PRE and POST blocks to ensure that they are still valid in inherited methods? class A; sub foo($bar,$baz){ PRE{ $bar10 } my $qux=$baz; POST{ $qux==$baz } } class B is base(A); # I forget the syntax for inheritance sub foo($x,$y){ # Insert any old random code here } Presumably, PRE/POST blocks will only be able to access their sub's arguments, since the derived class' sub may not declare the same variables as the base class (see $qux above). Or, maybe you just can't inherit from methods with such conditions, but I think that's putting the restriction in the wrong place. Or, you only inherit conditions which are inheritable, but that defeats the whole scheme. Also, these references have to be compiled into accesses to the argument list, rather than to the lexicals, otherwise they won't be any use at all to the derived class. Of course, this might be how references to sub arguments are compiled anyway, in which case there's no problem. -- Peter Haworth [EMAIL PROTECTED] Master, does Emacs have the Buddha nature? the novice asked. The Chief Priest had been in the temple for many years and could be relied upon to know these things. He thought for several minutes before replying, I don't see why not. It's got bloody well everything else.
RE: Some Apocalypse 4 exception handling questions.
Peter Haworth [mailto:[EMAIL PROTECTED]] wrote: This is all very sensible, and I completely agree with it. However, don't we need some restrictions on what can go in PRE and POST blocks to ensure that they are still valid in inherited methods? There's another issue: sometimes we don't want to inherit PRE conditions. DBC allows a derived method to strengthen (add) post-conditions; but to weaken (remove) preconditions. I haven't (yet) seen how this weakening would be accomplished. Perhaps the mechanism that controls inheritance of preconditions may have a more general applicability? Dave.
Re: Some Apocalypse 4 exception handling questions.
The problem I see with inheriting subblocks such as FIRST/LAST/etc, is that they are tied in with the logic ... of their enclosing block... Surely this is an argument *for* it being pretty odd *not* to inherit them. Let's say you add a LAST block to a method. In the LAST block you write clean up code that frees some resources. If you inherit from that method, and do not inherit the LAST block, then you've got a leak. This is obviously a mild example. --me
RE: Some Apocalypse 4 exception handling questions.
From: Me [mailto:[EMAIL PROTECTED]] The problem I see with inheriting subblocks such as FIRST/LAST/etc, is that they are tied in with the logic ... of their enclosing block... Surely this is an argument *for* it being pretty odd *not* to inherit them. Let's say you add a LAST block to a method. In the LAST block you write clean up code that frees some resources. If you inherit from that method, and do not inherit the LAST block, then you've got a leak. This is obviously a mild example. Methods can be inherited. Their implementations may include LAST blocks, which will be invoked along with the inherited method if the method is not redefined in a subclass. However, if the method is redefined in a subclass, neither the superclass' method's implementation or its associated LAST block would be invoked. In contrast, pre- and post-conditions _are_ inherited and separate from the method implementation itself. If an inherited method is redefined in a subclass, it must still satisfy pre- and post-conditions.
RE: Some Apocalypse 4 exception handling questions.
From: David Whipp [mailto:[EMAIL PROTECTED]] Peter Haworth [mailto:[EMAIL PROTECTED]] wrote: This is all very sensible, and I completely agree with it. However, don't we need some restrictions on what can go in PRE and POST blocks to ensure that they are still valid in inherited methods? There's another issue: sometimes we don't want to inherit PRE conditions. DBC allows a derived method to strengthen (add) post-conditions; but to weaken (remove) preconditions. I haven't (yet) seen how this weakening would be accomplished. In regard to Design-by-Contract, Larry did say more on that later. -Didn't he? In Class::Contract, pre-conditions are allowed to weaken by allowing either the satisfaction of the subclassed method's pre-conditions or by satisfying the pre-conditions of all classes from which it is derived.
Re: Some Apocalypse 4 exception handling questions.
Me writes: : The problem I see with inheriting subblocks such as : FIRST/LAST/etc, is that they are tied in with the logic : ... of their enclosing block... : : Surely this is an argument *for* it being pretty odd : *not* to inherit them. : : Let's say you add a LAST block to a method. In the : LAST block you write clean up code that frees some : resources. If you inherit from that method, and do not : inherit the LAST block, then you've got a leak. This is : obviously a mild example. I think our terminology is getting sloppy here. What do you mean by inherit from that method? If the derived method overrides the base method, it will manage its own resources, and doesn't need the base method's LAST. If the derived method calls the base method, the LAST of the base method will naturally come along for the ride. If there is no derived method, the base method also calls its own LAST as a matter of course. I don't see any problem here. Larry
Re: Some Apocalypse 4 exception handling questions.
Me wrote: The problem I see with inheriting subblocks such as FIRST/LAST/etc, is that they are tied in with the logic ... of their enclosing block... Surely this is an argument *for* it being pretty odd *not* to inherit them. Let's say you add a LAST block to a method. In the LAST block you write clean up code that frees some resources. If you inherit from that method, and do not inherit the LAST block, then you've got a leak. This is obviously a mild example. Methinks (that's me, not you) that if me thinks (that's you, not me) that my argument is an argument *for* it being pretty odd *not* to inherit them, that there is an assumption by me or me (that's one or the other of us) that is clearly wrong about the way inheritance of methods (should) work. In my mind, the idea of inheriting a method is that the subclass and the superclass have a common subroutine that is invoked whether the message is sent to the subclass or to the superclass. In Perl6 terms, that subroutine may include PRE/POST blocks, FIRST/LAST/NEXT/CATCH/UNDO/KEEP blocks, embedded closures and other statements, whatever the implementation needs to be to get the job done correctly. The whole she-bang subroutine implementation comes along for the inheritance ride. The idea that has been mentioned of having PRE and POST blocks be inherited is a slightly different concept... in that case, the method itself is NOT being inherited, and NONE of the code of the method in the superclass is used by the subclass... Except the PRE and POST conditions, as implemented by the PRE and POST blocks. They would get inherited to allow the design by contract invariants required by the superclass to be enforced in spite of subclassing. This separate type of inheritance is another reason that perhaps the PRE and POST blocks should not be included within the block of the subroutine that implements a method, but perchance should be defined outside of them... perhaps as properties of the method definition? I would be extremely doubtful of Larry's lucidity if I thought that he was suggesting that none of the FIRST/LAST/NEXT/CATCH/UNDO/KEEP blocks were included with an inherited method, but I don't think that. Such blocks are an inherent part of the implementation of the method, not an inherit part of subclassing. What do you think, me? --me -- Glenn = Due to the current economic situation, the light at the end of the tunnel will be turned off until further notice.
Re: Some Apocalypse 4 exception handling questions.
David Whipp writes: : Peter Haworth [mailto:[EMAIL PROTECTED]] wrote: : This is all very sensible, and I completely agree with it. : However, don't we : need some restrictions on what can go in PRE and POST blocks : to ensure that they are still valid in inherited methods? : : : There's another issue: sometimes we don't want to inherit PRE : conditions. DBC allows a derived method to strengthen (add) : post-conditions; but to weaken (remove) preconditions. I : haven't (yet) seen how this weakening would be accomplished. Damian told me you just handle that by ORing together the preconditions, but ANDing the postconditions. : Perhaps the mechanism that controls inheritance of : preconditions may have a more general applicability? Underneath it's all just block properties that happen to be closures. We can do whatever we want with them--as long as we agree on the definitions of we and want. Or at least agree to disagree such that we keep out of each other's way. Larry
Re: Some Apocalypse 4 exception handling questions.
Melvin Smith wrote: Methinks (that's me, not you) that if me thinks (that's you, not me) that my argument is an argument *for* it being pretty odd *not* to inherit them, that there is an assumption by me or me (that's one or the other of us) that is clearly wrong about the way inheritance of methods (should) work. Eek. In my mind, the idea of inheriting a method is that the subclass and the superclass have a common subroutine that is invoked whether the message is sent to the subclass or to the superclass. In Perl6 terms, that I'm not comfortable with this sort of concept. Typically inheritance is going to either take the base implementation or _replace_ the implementation. The replacement can decide to {call|ignore} the base method. I think you just said the same thing I did. To be more explicit, using the terminology you seem to want to use, I'll point out that I was only talking about the case of an inherited method, not a _replacement_ method. In other words, when you inherit a method, you are taking the base implementation for that method. But if you replace a method, you are not inheriting that method, but rather replacing it; yes, the replacement method may choose to call the base implementation's method as part of the replacement implementation. When you replace a method, you have 2 subroutines, the base implementation, and the replacement implementation, but when you inherit a method, you have only 1 subroutine, which may be called 2 different ways. If you have hidden side effects that makes things scary, (and potentially costly in the long run) I think. I wasn't positing hidden side effects. I was trying to not inherit fragments of the base implementation, as me seemed to be trying to do. If you wouldn't want the base implementation to be ignore there is usually some mechanism in C++ and Java for this, how it applies to Perl6 I'm not sure. I'm not sure either. In fact, I'm not sure what you mean by this sentence at all. If it matters, please rephrase it, so we can talk more about it. -Melvin -- Glenn = Due to the current economic situation, the light at the end of the tunnel will be turned off until further notice.
Re: Some Apocalypse 4 exception handling questions.
At 02:25 PM 1/23/2002 -0800, Glenn Linderman wrote: Melvin Smith wrote: I'm not comfortable with this sort of concept. Typically inheritance is going to either take the base implementation or _replace_ the implementation. The replacement can decide to {call|ignore} the base method. I think you just said the same thing I did. To be more explicit, using the terminology you seem to want to use, I'll point out that I was only talking about the case of an inherited method, not a _replacement_ method. In other words, when you inherit a method, you are taking the base implementation for that method. But if you replace a method, you are not inheriting that method, but rather replacing it; yes, the replacement method may choose to call the base implementation's method as part of the replacement implementation. When you replace a method, you have 2 subroutines, the base implementation, and the replacement implementation, but when you inherit a method, you have only 1 subroutine, which may be called 2 different ways. After re-reading your piece by itself I see we did say the same thing. The confusion set in when I read 'Me's' post inline with yours. If you wouldn't want the base implementation to be ignore there is usually some mechanism in C++ and Java for this, how it applies to Perl6 I'm not sure. I'm not sure either. In fact, I'm not sure what you mean by this sentence at all. If it matters, please rephrase it, so we can talk more about it. Referring to final, private, etc. modifiers that you can use in C++/Java whenever you don't want someone reimplementing or overriding something. Will there be such a thing in Perl6? I think this is meant more for Me (not me) than you. -Melvin
Re: Some Apocalypse 4 exception handling questions.
Melvin Smith wrote: If you wouldn't want the base implementation to be ignore there is usually some mechanism in C++ and Java for this, how it applies to Perl6 I'm not sure. I'm not sure either. In fact, I'm not sure what you mean by this sentence at all. If it matters, please rephrase it, so we can talk more about it. Referring to final, private, etc. modifiers that you can use in C++/Java whenever you don't want someone reimplementing or overriding something. Will there be such a thing in Perl6? I think this is meant more for Me (not me) than you. final and private are completely different concepts as I understand them. At least, I think I understand private to be stuff used by the implementation of methods, that is not available for the general public to see. This is considered a good thing in compiled code where users code to the interface, and cannot see the implementation. In Perl, the implementation is generally visible, and privacy would be somewhat fictitious, albeit perhaps a useful one at times. Final seems to be a way of sealing off a class or method from future inheritance. Generally, the arguments I've seen on OO lists seem to indicate that regardless of how omniscient the original designer is, someone will get an idea for a useful subclass for the class or method, but run into the problem of not being able to extend it because of the superclass implementor's choice to make it final. Hence, final seems to be a concept that is rather un-Perl-ish. -- Glenn = Due to the current economic situation, the light at the end of the tunnel will be turned off until further notice.
Re: Some Apocalypse 4 exception handling questions.
On Wed, Jan 23, 2002 at 02:25:35PM -0800, Glenn Linderman wrote: I think you just said the same thing I did. To be more explicit, using the terminology you seem to want to use, I'll point out that I was only talking about the case of an inherited method, not a _replacement_ method. In other words, when you inherit a method, you are taking the base implementation for that method. But if you replace a method, you are not inheriting that method, but rather replacing it; yes, the replacement method may choose to call the base implementation's method as part of the replacement implementation. When you replace a method, you have 2 subroutines, the base implementation, and the replacement implementation, but when you inherit a method, you have only 1 subroutine, which may be called 2 different ways. But the base class may be just an interface class. And thus by inheriting the pre conditions you are enforcing the API. So I can see a use for it, but I can also see where you don't want it too. Graham.
Re: Some Apocalypse 4 exception handling questions.
I think our terminology is getting sloppy here. Ok, I (think I) understand. It's simple: If you declare a derived method, then preconditions and postconditions may or may not be inherited, and independently, the code may or may not be inherited. By default, the conditions are inherited and the code is not. One can optionally not inherit the conditions (at least preconditions, from another post I just read). And one can optionally inherit the code (by calling it). Right? Btw, are you going to have an equivalent of super? --me
Re: Some Apocalypse 4 exception handling questions.
[final, private] I detest what these modifiers have done to me in the past. They seem very unperlish to me.
Re: Some Apocalypse 4 exception handling questions.
On Wed, Jan 23, 2002 at 02:45:21PM -0800, Glenn Linderman wrote: Final seems to be a way of sealing off a class or method from future inheritance. Generally, the arguments I've seen on OO lists seem to indicate that regardless of how omniscient the original designer is, someone will get an idea for a useful subclass for the class or method, but run into the problem of not being able to extend it because of the superclass implementor's choice to make it final. Hence, final seems to be a concept that is rather un-Perl-ish. Hmm. It would be un-Perl-ish to not provide a mechanism for the fascist to implement final if they wanted it. Which leads me to wonder if a way unfolds from the syntax already revealed or if we have to wait for the OOP-Apocalypse to see how to put our PRE conditions on the isa mechanism. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Some Apocalypse 4 exception handling questions.
At 05:01 PM 1/23/2002 -0600, Jonathan Scott Duff wrote: On Wed, Jan 23, 2002 at 02:45:21PM -0800, Glenn Linderman wrote: Final seems to be a way of sealing off a class or method from future inheritance. Generally, the arguments I've seen on OO lists seem to indicate that regardless of how omniscient the original designer is, someone will get an idea for a useful subclass for the class or method, but run into the problem of not being able to extend it because of the superclass implementor's choice to make it final. Hence, final seems to be a concept that is rather un-Perl-ish. Hmm. It would be un-Perl-ish to not provide a mechanism for the fascist to implement final if they wanted it. Which leads me to wonder if a way unfolds from the syntax already revealed or if we have to wait for the OOP-Apocalypse to see how to put our PRE conditions on the isa mechanism. I agree totally. Ive never bought into arguments about why available, non-default behavior is so oppressive. Else use strict would have to go. :) Glenn's point is correct about these mechanisms - when you don't have access to source code, it can be frustrating, but I think its the availability of source + the design decision of the author, not the keyword that is the problem. -Melvin
Re: Some Apocalypse 4 exception handling questions.
Graham Barr wrote: On Wed, Jan 23, 2002 at 02:25:35PM -0800, Glenn Linderman wrote: I think you just said the same thing I did. To be more explicit, using the terminology you seem to want to use, I'll point out that I was only talking about the case of an inherited method, not a _replacement_ method. In other words, when you inherit a method, you are taking the base implementation for that method. But if you replace a method, you are not inheriting that method, but rather replacing it; yes, the replacement method may choose to call the base implementation's method as part of the replacement implementation. When you replace a method, you have 2 subroutines, the base implementation, and the replacement implementation, but when you inherit a method, you have only 1 subroutine, which may be called 2 different ways. But the base class may be just an interface class. And thus by inheriting the pre conditions you are enforcing the API. So I can see a use for it, but I can also see where you don't want it too. So if the base class is just an interface class, then you cannot usefully inherit the methods, without winding up with just another interface class. Of course, that sometimes is useful too. So maybe your point was that when you replace a method from a base class that you only have 1 subroutine for that method, the replacement one, because there wasn't really one there in the interface class to inherit? It was not my intention in the paragraph I quoted to say anything about pre and post conditions, but neither was it my intention to imply that they shouldn't be inherited, if they exist. I'd still like to hear Larry comment on the benefits vs dangers of having the PRE and POST conditions defined within the implementation block of a method, as opposed to defined outside. The more I think about it, the more convinced I am that the natural place to define the pre and post conditions is outside the implementation block, to prevent them from referencing lexically scoped variables of the implementation... or have a compiler rule preventing it. Otherwise they could be impossible to evaluate in the context of an inherited (replacement) method. -- Glenn = Due to the current economic situation, the light at the end of the tunnel will be turned off until further notice.
Re: Some Apocalypse 4 exception handling questions.
Larry == Larry Wall [EMAIL PROTECTED] writes: Larry I think our terminology is getting sloppy here. What do you mean by Larry inherit from that method? If the derived method overrides the base Larry method, it will manage its own resources, and doesn't need the base Larry method's LAST. If the derived method calls the base method, the LAST Larry of the base method will naturally come along for the ride. If there is Larry no derived method, the base method also calls its own LAST as a matter Larry of course. I don't see any problem here. That's why I'm still puzzled about what it means to inherit PRE/POST as well. A block of code doesn't have a superclass. What exactly are you inheriting from? If you call super from a method, surely the super will have its own PRE/POST, and then there's no need to inherit it. If you don't call super, how do you know the PRE/POST of a similar subroutine in a superclass that you're completely overriding should even apply? So, does it make any sense at all to talk about inheriting PRE/POST as a separate act, other than the natural block start/end from calling super at the right time? -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 [EMAIL PROTECTED] URL:http://www.stonehenge.com/merlyn/ Perl/Unix/security consulting, Technical writing, Comedy, etc. etc. See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Re: Some Apocalypse 4 exception handling questions.
Tony Olekshy writes: : In Apocalypse 4, Larry Wall wrote: : | : | In fact, a CCATCH of the form: : | : | CATCH { : | when xxx { ... } # 1st case : | when yyy { ... } # 2nd case : | ... # other cases, maybe a default : | } : | : |means something vaguely like: : | : | BEGIN { : | %MY.catcher = { : | given current_exception() - $! { : | : | when xxx { ... } # 1st case from above : | when yyy { ... } # 2nd case from above : | ... # other cases, maybe a default : | : | die;# rethrow $! as implicit default : | } : | $!.markclean; # handled cleanly, in theory : | } : | } : : Beautiful. The synthesis of CATCH, BEGIN blocks, %MY, given, when, : break, dwim =~, die, $!, $!.clean, and $!.stack is awe-inspiring. : The way proto-exceptions, fail, and use fatal work together is also : brilliant. Thanks. I'm the proof that nearly anyone can be brilliant if they don't have to do it in real-time. :-) : I particularly enjoyed this one: : :CATCH { when @$! =~ Foo { ... } } It was actually in trying to translate that very example that I realized that most of the arrays in the =~ table had an implied any() around them (just as all the lists have an implied any() around them). It hadn't occurred to me before then that Damian's special array intersection dwim was the same as any(@foo) =~ any(@bar). From there it was easy to generalize that @foo =~ Class really means any(@foo) =~ Class So, thanks! : I do have a few questions. : :1. Does this example: : : { : my $p = P.new; LAST { $p and $p.Done; } : foo(); : my $q = Q.new; LAST { $q and $q.Done; } : ... : } : : effectively get compiled into something like: : : { : my $p; my $q; : $p = P.new; LAST { $p and $p.Done; } : foo(); : $q = Q.new; LAST { $q and $q.Done; } : ... : } : : If not, how can we evaluate $q in the LAST block if foo() dies? : Or are LASTs not handled by a magic BEGIN mechanism? Or are the : LASTs converted into a BEGIN plus some run-time state variable : that is only set when the LAST is encountered during execution? : Or am I missing the point entirely ;-? All the LASTs run always. The compiler has to take responsibility one way or another to make sure unelaborated variables still evaluate to undefined. It can, for instance, hoist the allocation to the front, something like your example. It's not something that's possible to write an example of in Perl, since you can't separate the allocation from the name introduction in Perl. Maybe with two pseudo-ops indicating the two aspects of my: { myalloc $p; myalloc $q; myintro $p = P.new; LAST { $p and $p.Done; } foo(); myintro $q = Q.new; LAST { $q and $q.Done; } ... } Alternately, the compiler can keep track of how far the elaboration has proceeded, and compile down to something like: { my $p = P.new; LAST { maybe($p) and maybe($p).Done; } foo(); my $q = Q.new; LAST { maybe($q) and maybe($q).Done; } ... } where maybe() is smart enough to know whether the variable in question has been allocated. As yet another way, the code searching for the LAST to execute could make sure any unallocated variables get allocated before calling the LAST block, much like { goto X; my $p = 2; X: print $p; } would need to make sure that $p gets created en passant if it were not already created before the goto. I expect the first way is the easiest, though perhaps it's not the most efficient way for non-exceptional code. :2. Consider the following example: : : for my $file ( @files ) { That's obsolete syntax, by the way... : my $f is last { close } = open $file or next; : foo($f); : CATCH { default { print foo($f) failed\n } } : } : : The last and CATCH blocks must be invoked at the end of each : time around the for block, no? Or should I be writing: : : for my $file ( @files ) { : try { : my $f is last { close } = open $file or next; : foo($f); : CATCH { default { print foo($f) failed\n } } : } : } That would be better if you want any exception to go to the next file. Alternately, and perhaps more clearly, you could write: for @files - $file { my $f = open $file or die; foo($f); CATCH { default { print foo($f) failed\n; next } } NEXT { $f.close } } or equivalently for @files - $file { my $f is
Some Apocalypse 4 exception handling questions.
In Apocalypse 4, Larry Wall wrote: | | In fact, a CCATCH of the form: | | CATCH { | when xxx { ... } # 1st case | when yyy { ... } # 2nd case | ... # other cases, maybe a default | } | |means something vaguely like: | | BEGIN { | %MY.catcher = { | given current_exception() - $! { | | when xxx { ... } # 1st case from above | when yyy { ... } # 2nd case from above | ... # other cases, maybe a default | | die;# rethrow $! as implicit default | } | $!.markclean; # handled cleanly, in theory | } | } Beautiful. The synthesis of CATCH, BEGIN blocks, %MY, given, when, break, dwim =~, die, $!, $!.clean, and $!.stack is awe-inspiring. The way proto-exceptions, fail, and use fatal work together is also brilliant. I particularly enjoyed this one: CATCH { when @$! =~ Foo { ... } } I do have a few questions. 1. Does this example: { my $p = P.new; LAST { $p and $p.Done; } foo(); my $q = Q.new; LAST { $q and $q.Done; } ... } effectively get compiled into something like: { my $p; my $q; $p = P.new; LAST { $p and $p.Done; } foo(); $q = Q.new; LAST { $q and $q.Done; } ... } If not, how can we evaluate $q in the LAST block if foo() dies? Or are LASTs not handled by a magic BEGIN mechanism? Or are the LASTs converted into a BEGIN plus some run-time state variable that is only set when the LAST is encountered during execution? Or am I missing the point entirely ;-? 2. Consider the following example: for my $file ( @files ) { my $f is last { close } = open $file or next; foo($f); CATCH { default { print foo($f) failed\n } } } The last and CATCH blocks must be invoked at the end of each time around the for block, no? Or should I be writing: for my $file ( @files ) { try { my $f is last { close } = open $file or next; foo($f); CATCH { default { print foo($f) failed\n } } } } 3. Would the following execute the Cdie? When do I have to worry about accidentally catching control exceptions? sub ... { return if 1; fragile(); CATCH { default { die Couldn't fragile. } } } 4. The test for block exited successfully is C !$! || $!.clean , for the purposes of the block-end handing code, correct? So KEEP is like LAST { if ( !$! || $!.clean ) { ... } } and UNDO is like LAST { unless ( !$! || $!.clean ) { ... } } in which case CATCH is actually like UNDO with an implied given, die, and $!.markclean, except it's handled in a different end- block order, yes? 5. What is the order of processing all these special blocks at the end of their containing block? Is it: 1. CONTINUE 2. CATCH 3. KEEP 4. UNDO 5. LAST 6. POST or some other fixed order, or is there some sort of order-of- encounter interleaving of some of the kinds of blocks? 6. What is the value of my $x = try { 1 CATCH { default { 2 } } LAST { 3 } }; What happens for each permutation of replacing n by die n? 7. Is there any particular reason why multiple CATCH blocks can't simply be queued in some fashion like multiple LAST blocks? Yours, c, Tony Olekshy