Re: Private contracts?
On Fri, 11 Oct 2002, Trey Harris wrote: : When you say subclass, do you mean below the current class in the : naming heirarchy, i.e. : : class BTree; : our class Node {...} : : would create BTree::Node? Or do you really mean *subclass*, i.e., our : class causes Node to inherit from BTree? I hope it's the former, but the : word subclass does usually imply inheritance Sorry, I meant a class named within the current package, not a derived class. Larry
Re: Private contracts?
Date: Sat, 12 Oct 2002 08:43:46 -0700 (PDT) From: Larry Wall [EMAIL PROTECTED] If we use | and as sugar for any() and all(), then their precedence should probably be the same as || and . Should they? I had in mind something just above comparisons. That way: if $x == 3 || $y == 4 {...} and if $x == 1 | 2 { ... } both DWIM. Is there a case for not doing this? Luke
Re: Private contracts?
On Sat, 12 Oct 2002, Larry Wall wrote: : The precedence is screwed up though. It'd have to be : : use Acme[ (1;17..) | (2;0..) ]; Or maybe this: use Acme[1;17..] | Acme[2;0..]; That doesn't, of course, express any preference for one version over another, since | logically happens in parallel universes, in constant time. It also doesn't let you pass different arguments to different versions. It does, however, let you try using differently named modules that provide the same interface: use Acle[1;17..] | Acme[1;13..] | Acne[1;14..]; That syntax doesn't, however, let you alias the interface to a single name. Hmm. class MyAc is really(Acle[1;17..] | Acme[1;13..] | Acne[1;14..]); use MyAc 1,2,3; Seems a little odd to do the use on the alias, but it seems like it could work. I'm not quite sure when a class wave function collapses though... Larry
Re: Private contracts?
On Sat, 12 Oct 2002, Luke Palmer wrote: : Date: Sat, 12 Oct 2002 08:43:46 -0700 (PDT) : From: Larry Wall [EMAIL PROTECTED] : : If we use | and as sugar for any() and all(), then their precedence : should probably be the same as || and . : : Should they? I had in mind something just above comparisons. That : way: : : if $x == 3 || $y == 4 {...} : : and : : if $x == 1 | 2 { ... } : : both DWIM. Is there a case for not doing this? Mmm, only a precedence simplification case. I'd forgotten about the comparison ops. Right above them is probably a good place. Larry
Re: Private contracts?
On Sat, 12 Oct 2002 08:43:46 -0700, Larry Wall wrote: On Sat, 12 Oct 2002, Graham Barr wrote: : Or even something like : : use Acme[1.0]; Hmm. Looks kinda like a subscript, which could be sliced to give an acceptable version range: use Acme[1;0..]; Might it be possible to say use any installed version of Acme below 2.0? use Acme[..2;0]; That could also be helpful. -- c
Re: Private contracts?
On Sat, 12 Oct 2002, Chris Dutton wrote: : On Saturday, October 12, 2002, at 01:10 PM, Luke Palmer wrote: : : Date: Sat, 12 Oct 2002 08:43:46 -0700 (PDT) : From: Larry Wall [EMAIL PROTECTED] : : If we use | and as sugar for any() and all(), then their precedence : should probably be the same as || and . : : Should they? I had in mind something just above comparisons. That : way: : : if $x == 3 || $y == 4 {...} : : and : : if $x == 1 | 2 { ... } : : both DWIM. Is there a case for not doing this? : : Just a thought, but don't we already have this with the smart match : operator? : : if $x =~ (1, 2) { ... } Yes, =~ implies an any() around a list. But | could leave out the parens, presuming the precedence is higher than =~. : Or would and | be a bit more strict in use, and thus easier for the : compiler to optimize? For instance, would we be able to: : : if $x == 1 | hello { ... } : : or would both operands have to be of the same type? I don't see why they'd have to be the same type. There could well be good reasons for superposing objects of different types. Larry
Re: Private contracts?
On Sat, 12 Oct 2002, Graham Barr wrote: : Or even something like : : use Acme[1.0]; Hmm. Looks kinda like a subscript, which could be sliced to give an acceptable version range: use Acme[1;0..]; Except slices aren't powerful enough to say what you really want to say: use Acme[1;17.. | 2;0..]; Er, or maybe they are now... The precedence is screwed up though. It'd have to be use Acme[ (1;17..) | (2;0..) ]; If we use | and as sugar for any() and all(), then their precedence should probably be the same as || and . But that still doesn't help for superposed slices or lists, since commas and semicolons are lower precedence yet. I'm afraid any() and all() don't help either. Please don't anyone suggest special low-precedence versions... Larry
Re: Private contracts?
On Saturday, October 12, 2002, at 01:10 PM, Luke Palmer wrote: Date: Sat, 12 Oct 2002 08:43:46 -0700 (PDT) From: Larry Wall [EMAIL PROTECTED] If we use | and as sugar for any() and all(), then their precedence should probably be the same as || and . Should they? I had in mind something just above comparisons. That way: if $x == 3 || $y == 4 {...} and if $x == 1 | 2 { ... } both DWIM. Is there a case for not doing this? Just a thought, but don't we already have this with the smart match operator? if $x =~ (1, 2) { ... } Or would and | be a bit more strict in use, and thus easier for the compiler to optimize? For instance, would we be able to: if $x == 1 | hello { ... } or would both operands have to be of the same type?
Re: Private contracts?
On Thu, 3 Oct 2002, Trey Harris wrote: : In a message dated Thu, 3 Oct 2002, Allison Randal writes: : So far, classes are uppercase and properties are lowercase, but that's : convention, not law. : : Do runtime (value) properties and compile-time (variable) properties share : the same namespace? In general, no. : That is, to go back to an earlier discussion, if there is a system-defined : value property Ctrue which marks a value as true in boolean contexts, : can I also define a compile-time property Ctrue that makes the variable : evaluate as true, whatever its value? No, I think the boolean test would probably ignore the variable at that point. Think of variable properties as more of a tie. The variable could contrive to always return a true value, but that's about it. There's unlikely to be any implicit relationship between variable properties and value properties. A major exception to that might be that the type declared on the variable is checked against the value's type at appropriate times. Larry
Re: Private contracts?
On Fri, Oct 11, 2002 at 05:50:55PM -0700, Larry Wall wrote: On Sat, 5 Oct 2002, Allison Randal wrote: : use Acme::N-1_0; # or whatever the format of the name is I don't see why it couldn't just be: use Acme::1.0; I agree thats better. But why not separate the version more by using a different separator than :: between the module name and the version. Or even something like use Acme[1.0]; After all, we don't have package names starting with numbers right now... Er, we do. http://search.cpan.org?perldoc?Pod::Simple::31337 It would seem that (currently) only the top-level namespace may not start with a number. But I would also not that CPAN only has 3 such modules, all by the same author and all ::31337 Graham.
Re: Private contracts?
* Larry Wall ([EMAIL PROTECTED]) [12 Oct 2002 10:51]: [...] use Acme::1.0; After all, we don't have package names starting with numbers right now... Well, there's than Pod::Simple::31337, which confused search.cpan.org for a bit. But none which _start_ with a number, no. cheers, -- Iain.
Re: Private contracts?
On Sat, 5 Oct 2002, Allison Randal wrote: : use Acme::N-1_0; # or whatever the format of the name is I don't see why it couldn't just be: use Acme::1.0; After all, we don't have package names starting with numbers right now... Larry
RE: Private contracts?
On Fri, 4 Oct 2002, Garrett Goebel wrote: : That wasn't the way I remembered it from Apoc 4... The following example is : not in A4, but its what I inferred from it... : : Class Foo { : method eat($food) is abstract { : PRE { ... } : POST { ... } : } : } A4 was proposing those for a different purpose, and confusing the issue with DBC. Those are now FIRST and LAST, and the pre/post syntax is still undecided. Larry
Re: Private contracts?
On Fri, 4 Oct 2002, Peter Haworth wrote: : This is the one nice thing about the Pascal-like syntax of Eiffel. It allows : this situation to be unambiguous and sensibly ordered (as well as giving each : condition labels, so that violations can be better reported): : : foo(this: ThisType, that: ThatType): FooType IS : REQUIRE : small: this = 42 : half: that = this / 2 : DO : -- implementation goes here : ENSURE : fooed_ok: RESULT = baz(this) + that : END : : If you're declaring an abstract feature, just replace the whole DO clause with : DEFERRED. That is exactly what a literal C {...} means in Perl 6, and why it's required on forward declarations of anything that takes a block, if you really mean it that way. You can't say sub foo; in Perl 6. You have to say sub foo {...} : Also notice how Eiffel's syntax also somehow makes statement : terminators completely optional. Yes, well, let's not go there... :-) : Aren't sub declarations in Perl 6 all expressions? Why couldn't we put the : post condition at the end, then? : : sub foo($this, $that) is memoized is something : is pre{ $this = 42 } : is pre{ $that == $this / 2 } : { : # implementation goes here : } is post{ : # postcondition 1 : } is post{ : # postcondition 2 : } : : If you want an abstract method, just omit the implementation block. The absence of something is hard to notice. Put {...} for an abstract method. Larry
Re: Private contracts?
On Thu, 3 Oct 2002, John Williams wrote: : On Thu, 3 Oct 2002, Trey Harris wrote: : : Incidentally, has there been any headway made on how you DO access : multiple classes with the same name, since Larry has (indirectly) promised : us that? I.e., I import two classes LinkedList and BTree, both of : which define a Node class? : : Hopefully, LinkedList defines a LinkedList::Node class, and BTree defines : a BTree::Node class. Either by explicitly naming them that or by virtue : of being defined as an inner class (which might also make it private). A private inner class: my class Node {...} A public inner class: our class Node {...} That last one actually declares a subclass of the current class, just as our $foo; puts $foo into the current package. Larry
Re: Private contracts?
On Thu, 3 Oct 2002, Michael G Schwern wrote: : On Thu, Oct 03, 2002 at 05:23:08PM -0500, Jonathan Scott Duff wrote: : I don't know, but I think it's supposed to be like this: : : # part of the signature : method turn($dir,$ang) is pre { $ang = 20 } { : ... : } : : # part of the implementation : method turn($dir,$ang) { : PRE { $ang = 20 } : ... : } : : turn() methods of derived classes would inherit the precondition in the : first case but not the second. I don't know why you'd want to do this : exactly, but it seems to me that perl should allow it. : : I see us already smashing too many things into the method signature as it : is. It will rapidly get messy if you have a method with a complex signature : and a handful of attributes and preconditions. : : Also, where do the postconditions go? In the signature at the front? That : doesn't make sense, it should go at the end so you can keep them in mind : when you're writing the return code. : : Consider... : : method foo($this, $that) is memoized is something : is pre { $this = 42 } : is pre { $that == $this / 2 } : is pre { a lot of code which is hard to :shove into a block of code :this close to the right margin } : is post { what is a post condition : doing at the front? } : { : ... : } : : They can, of course, be pulled back from the margin: : : method foo($this, $that) is memoized is something : is pre { $this = 42 } : is pre { $that == $this / 2 } : is pre { now we have a little bit more room to play with using : a differnt indentation style } : is post { but post conditions are still distanced from the :code which return()s } : { : ... : } : : I realize that conditions are technically part of the signature, but putting : them in there paints us into a stylistic corner. Hmm. It sounds like a cry for help. :-) method foo($this, $that) is memoized is something { ... } # Additionaly... also foo is pre { $this = 42 } is pre { $that == $this / 2 } is pre { now we have a little bit more room to play with using a differnt indentation style } is post { but post conditions are still distanced from the code which return()s }; One is tempted to make it: also note that foo is pre { ... } It might be possible to allow is after the {...} block, much like an Celse block. But an also would let us defer all the extras to the end of the class definition. : I'm also not fond of the pre/PRE distinction. Few of the other special : blocks (given, eval, try, invar, etc...) use all cap names. At least I hope : not. All caps indicates a BEGIN-like block that is not evaluated inline, but sets a property in the surrounding scope. It's a useful distinction. : Simply attaching an is private attribute to a pre condition block : seems the simplest way to go about it. Except that you'd have to parenthesize it: is pre ({...} is private) Otherwise it'd merely privatize whatever the first is is issing. : Just like any other private thing, : it's not inherited and not visible outside the current class. pre vs : PRE doesn't convey that meaning. Well, yes it does, because the pre is in the declaration, and the PRE is embedded in the implementation, albeit known at compile time. Not that we're necessarily going to have PRE/POST blocks anyway, but that's how they'd parse. I think it'd be kinda strange (but possible (but possibly useless)) to have a declaration like: sub foo { ... PRE { _ 0 } } That is, the precondition would go away as soon as you redefined the {...}. Larry
Re: Private contracts?
On 4 Oct 2002, Aaron Sherman wrote: : There are a very large number of good things that I think we should put : into properties for meta-programming purposes (e.g. constraints, : assertions, optimization hints, documentation, etc). : : For example: : : sub f(int $a is constrained($a=1,must be positive), : documented(an integer)) : is constrained(some_global_condition), : documented(applies transformation f to an integer) { : ... : } Another good reason to allow: sub f(int $a is constrained($a=1,must be positive), documented(an integer)) { ... } also f is constrained(some_global_condition), documented(applies transformation f to an integer); or possibly even sub f(int $a) { also $a is constrained($a=1,must be positive), documented(an integer); ... } also f is constrained(some_global_condition), documented(applies transformation f to an integer); One could argue that, given that is is always compile-time, the also is redundant. sub f(int $a) { $a is constrained($a=1,must be positive), documented(an integer); ... } f is constrained(some_global_condition), documented(applies transformation f to an integer); But maybe that's too weird. Larry
Re: Private contracts?
sub f(int $a is constrained($a=1,must be positive), documented(an integer)) { ... } I now realize I'm a little fuzzy on the yada-yada-yada operator. What exactly is it... or what does it do? Is it a statement, an expression? Could you say things like: foo(...); (Admittedly I have no idea what that would mean) Is it just something that does nothing? sub f() { print Don't see me\n; } sub f() { # do other stuff } f; Would do the same as using ... in the former? I hope not (though I suppose that's what Perl 5 does). Is it more special than that? Luke
Re: Private contracts?
In a message dated Fri, 11 Oct 2002, Larry Wall writes: A public inner class: our class Node {...} That last one actually declares a subclass of the current class, just as our $foo; puts $foo into the current package. When you say subclass, do you mean below the current class in the naming heirarchy, i.e. class BTree; our class Node {...} would create BTree::Node? Or do you really mean *subclass*, i.e., our class causes Node to inherit from BTree? I hope it's the former, but the word subclass does usually imply inheritance Trey
Re: Private contracts?
On Friday, October 4, 2002, at 06:23 PM, [EMAIL PROTECTED] wrote: On Fri, Oct 04, 2002 at 09:13:45AM -0400, Chris Dutton wrote: How exactly does one weaken a precondition? At least in Eiffel, if you redefine a method, you may not give it stringer preconditions than the original method, but you may have stronger postconditions. In essence, you're not requiring any more of the client, but you can ensure more to them on completion, thus maintaining the parent's contract. But what does it mean to be stronger? How does Eiffel figure out if a given precondition is stronger or weaker than another? Perhaps an example is the best way to demonstrate this: class FOO creation make feature make(input: SOME_OTHER_CLASS) is require input /= Void do -- something here ensure input /= Void end end -- Good: class BAR inherit FOO redefine make end creation make feature make(input: SOME_OTHER_CLASS) is -- no requirements, weaker precondition do -- yada yada ensure input /= Void old input.some_attribute /= input.some_attribute -- stronger postcondition is ok. end end -- Bad: class BAR inherit FOO redefine make end creation make feature make(input: SOME_OTHER_CLASS) is require input /= Void input.some_attribute = 1 -- requiring more than the parent's make procedure is bad. do -- yada yada -- Not ensuring anything to the client is bad. -- The parent honored that in its contract, so -- the child must also. end end
Re: Private contracts?
On Fri, Oct 04, 2002 at 12:03:44AM -0400, Trey Harris wrote: In a message dated Thu, 3 Oct 2002, John Williams writes: On Thu, 3 Oct 2002, Trey Harris wrote: Incidentally, has there been any headway made on how you DO access multiple classes with the same name, since Larry has (indirectly) promised us that? I.e., I import two classes LinkedList and BTree, both of which define a Node class? Hopefully, LinkedList defines a LinkedList::Node class, and BTree defines a BTree::Node class. Either by explicitly naming them that or by virtue of being defined as an inner class (which might also make it private). Ah, but that's the way you do it now--name the classes differently. (Easy--assuming you control the source code!) In Perl 6, we're supposed to be able to use multiple versions of the same class concurrently, which I think would imply also being able to use multiple classes that happened to be named the same thing. It doesn't imply that. The currently proposed solution is that the true name of a class will include at least the version. But, you can alias classes just like variables: # compile time class Foo is really (Acme::Kung::Foo-1_54); # runtime class Foo := Acme::Kung::Foo-1_54; # (the full classname format hasn't been hashed out yet, this is # just for sake of illustration) So, you could reuse the same short name for multiple different classes, as long as you lexically scoped your aliases. I wouldn't recommend it though, unless you're trying to confuse people. Even in the rare case when you need to use two different versions of the same class in the same code, there will be a clearer way to do it. More useful: keep a site-wide or company-wide file of version aliases to make sure everyone uses the same version, and to make upgrades to the next version as simple as editing a single file. Allison
Re: Private contracts?
In a message dated Sat, 5 Oct 2002, Allison Randal writes: More useful: keep a site-wide or company-wide file of version aliases to make sure everyone uses the same version, and to make upgrades to the next version as simple as editing a single file. Ah, but the usual case is this: You download from CPAN class A that depends on version 1.0 of class N. You then download class B that also depends on version 1.0 of class N. You create an application that uses both classes A and B (and thus N through the dependencies.) Some time later, you discover a bug that requires you to upgrade class B, but the upgrade now depends on class 1.1 of class N. Class A hasn't been upgraded yet, and turns out not to work well with version 1.1 of N. So you need both versions 1.1 and 1.0 of class N running in the application--preferably without having to modify any of your app, class A, or class B. This could be made to work (assuming that classes A and B both specify which version of N they need). Trey
Re: Private contracts?
On Thursday, October 3, 2002, at 05:19 PM, Michael G Schwern wrote: On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote: With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. How exactly does one weaken a precondition? At least in Eiffel, if you redefine a method, you may not give it stringer preconditions than the original method, but you may have stronger postconditions. In essence, you're not requiring any more of the client, but you can ensure more to them on completion, thus maintaining the parent's contract.
Re: Private contracts?
There are a very large number of good things that I think we should put into properties for meta-programming purposes (e.g. constraints, assertions, optimization hints, documentation, etc). For example: sub f(int $a is constrained($a=1,must be positive), documented(an integer)) is constrained(some_global_condition), documented(applies transformation f to an integer) { ... } So, when documentation is extracted from this: =item Cf($a) This function applies transformation f to an integer. It takes the following parameters: =over 5 =item C$a This parameter is an integer which must be positive. =back Walla! Self-documenting functions. -- Aaron Sherman [EMAIL PROTECTED]
Re: Private contracts?
On Thu, 3 Oct 2002 18:46:14 -0400, Michael G Schwern wrote: method foo($this, $that) is memoized is something is pre { $this = 42 } is pre { $that == $this / 2 } is pre { now we have a little bit more room to play with using a differnt indentation style } is post { but post conditions are still distanced from the code which return()s } { ... } I realize that conditions are technically part of the signature, but putting them in there paints us into a stylistic corner. This is the one nice thing about the Pascal-like syntax of Eiffel. It allows this situation to be unambiguous and sensibly ordered (as well as giving each condition labels, so that violations can be better reported): foo(this: ThisType, that: ThatType): FooType IS REQUIRE small: this = 42 half: that = this / 2 DO -- implementation goes here ENSURE fooed_ok: RESULT = baz(this) + that END If you're declaring an abstract feature, just replace the whole DO clause with DEFERRED. Also notice how Eiffel's syntax also somehow makes statement terminators completely optional. Aren't sub declarations in Perl 6 all expressions? Why couldn't we put the post condition at the end, then? sub foo($this, $that) is memoized is something is pre{ $this = 42 } is pre{ $that == $this / 2 } { # implementation goes here } is post{ # postcondition 1 } is post{ # postcondition 2 } If you want an abstract method, just omit the implementation block. -- Peter Haworth [EMAIL PROTECTED] Maybe that's [Java's] niche, its a language for people who like pain. -- Dean Wilson
Re: Private contracts?
On Thu, 3 Oct 2002 19:16:09 -0400, Michael G Schwern wrote: On Thu, Oct 03, 2002 at 04:47:26PM -0500, Garrett Goebel wrote: A derived interface can loosen input constraints... so it must be able to either satisfy all inherited pre-conditions _or_ its own pre-conditions. Looking around, this seems to be regarded as something of a compromise because truly determining what a real logical weaking is is hard. That *is* a logical weakening. Just because the inherited precondition is C x 10 , doesn't mean that the weakened condition has to be of the form C x 9 or any other value lower than 10. C a || b is weaker than C a Are there other ways to do it, just to mull them over? -- Peter Haworth [EMAIL PROTECTED] I remember being impressed with Ada because you could write an infinite loop without a faked up condition. The idea being that in Ada the typical infinite loop would be normally be terminated by detonation. -- Larry Wall
RE: Private contracts?
Michael G Schwern: Michael G Schwern wrote: I see us already smashing too many things into the method signature as it is. It will rapidly get messy if you have a method with a complex signature and a handful of attributes and preconditions. I think I have my own counter example. Consider defining an abstract class with an interface and I want to put some conditions onto an abstract method. class Abstract::Human is interface { attr head, shoulders, knees, toes; invar { .head == 1 } invar { .shoulders == .knees == .toes == 2 } method eat ($food) is pre { !$food.isa('Poison') } is post { .return eq 'Burp' } } since I have no method body for eat() I have no choice but to hang it off the signature as an attribute. That wasn't the way I remembered it from Apoc 4... The following example is not in A4, but its what I inferred from it... Class Foo { method eat($food) is abstract { PRE { ... } POST { ... } } } Class Bar is Foo { method eat { PRE { ... } ... implementation ... POST { ... } } } 'eat' may be an abstract method inherited by Bar from Foo... but the PRE and POST conditions are still inherited. Though I can see the issue that abstract precludes an implementation. But does that also require use to preclude the code block? Also if you rely on attributes to hang conditions... you're ruling out the ability to reference things in the lexical context of the code block. -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
Re: Private contracts?
-- On Thu, 3 Oct 2002 18:46:14 Michael G Schwern wrote: I see us already smashing too many things into the method signature as it is. It will rapidly get messy if you have a method with a complex signature and a handful of attributes and preconditions. This is the sort of creeping elegance which made me worry about is/but in the first place. Also, where do the postconditions go? In the signature at the front? Well, if pre and post conditions are blocks they don't have to go in the signature at all. We can affect a lexical scope outside of the lexical scope, so we can simply define the PRE and POST blocks lexically to the method _outside_ of the method. No need to put it in the signature. Assuming method foo foo.MY{ PRE } := sub { ... }; This is all contingent on the idea that we can name lexical scopes (such as with loop labels, named rules and subs, methods). The precondition here will refer to whatever method foo is defined, wherever it is defined in the inheritance heirarchy. If you want to point to a specific foo, use it's fully qualified name, if you want to point to a lexically scoped foo __FILE__.MY{ 'foo' }.MY{ PRE } := sub { ... }; #Ugly, ain't it? though why you wouldn't want to do it in the method definition itself is beyond me. Now this example syntax is ugly intentionally. It's ugly so that someone smarter than me will feel the need to fix it. The symbol table, taking a reference to a class, the %MY stash are all a little vague anyway, and I'd like to see someone propose good syntax for it. -Erik, of the evil mailer That doesn't make sense, it should go at the end so you can keep them in mind when you're writing the return code. Consider... method foo($this, $that) is memoized is something is pre { $this = 42 } is pre { $that == $this / 2 } is pre { a lot of code which is hard to shove into a block of code this close to the right margin } is post { what is a post condition doing at the front? } { ... } They can, of course, be pulled back from the margin: method foo($this, $that) is memoized is something is pre { $this = 42 } is pre { $that == $this / 2 } is pre { now we have a little bit more room to play with using a differnt indentation style } is post { but post conditions are still distanced from the code which return()s } { ... } I realize that conditions are technically part of the signature, but putting them in there paints us into a stylistic corner. I'm also not fond of the pre/PRE distinction. Few of the other special blocks (given, eval, try, invar, etc...) use all cap names. At least I hope not. Simply attaching an is private attribute to a pre condition block seems the simplest way to go about it. Just like any other private thing, it's not inherited and not visible outside the current class. pre vs PRE doesn't convey that meaning. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One AY! The ground beef, she is burning my groin! http://sluggy.com/d/990105.html Is your boss reading your email? Probably Keep your messages private by using Lycos Mail. Sign up today at http://mail.lycos.com
Re: Private contracts?
Peter Haworth wrote: That *is* a logical weakening. Just because the inherited precondition is C x 10 , doesn't mean that the weakened condition has to be of the form C x 9 or any other value lower than 10. C a || b is weaker than C a So what we are looking at is something like class Animal { method eat($food) is abstract { PRE { $food.isa(Edible); } POST { !$stomach.empty; } } ... } class Goat is Animal { method eat($food) { PRE { $food.isa(Can); } my $chewedfood = $teeth.chew($food); $stomach.add($chewefood); $teeth.brush() POST { $teeth.clean; } } ... } class Teeth { method brush {...}; method chew { ... POST { .clean == false; } } } my Animal $billy = new Goat; $billy.eat(Banana.new()); # succeeds because PRE for Animal.eat is met $billy.eat(Can.new()); # succeeds because PRE for Goat.eat is met $billy.eat(Rock.new()); # Fails because neither PRE is met class DirtyTeeth is Teeth { method brush {}; ... } $billy.teeth = DirtyTeeth.new(); $billy.eat(Banana.new()); # Fails because POST for Goat.eat is not met etc. Are there other ways to do it, just to mull them over?
RE: Private contracts?
Michael G Schwern: Garrett Goebel wrote: A derived interface can loosen input constraints... so it must be able to either satisfy all inherited pre- conditions _or_ its own pre-conditions. Looking around, this seems to be regarded as something of a compromise because truly determining what a real logical weaking is is hard. Are there other ways to do it, just to mull them over? I thought about this for a while while reading your post. There are certainly pre-conditions which you will want to be enforced all the way down the line. And running counter to this is the need to be able to weaken pre-condition constraints to handle a wider range of inputs. Which requires that the derived class not need to satisfy all inherited pre-conditions. So the following wouldn't necessarily DWIM (if you know what I mean): Class Foo { method count($from, $to) { PRE { $to 10 } PRE { $from = .lower_bound } } } Class Bar is Foo { method count { PRE { .to 100 } } } Class Baz is Bar { method count { ... implementation ... } } if you call Bar-count(-1, 99) you're no longer effectively constraining $from = .lower_bound. if you call Baz-count(-1, 99) you'll fail the Foo precondition. But since you haven't defined any pre-conditions for Baz does this mean you have to satisfy all inherited preconditions or that there are none? I.e. where's the boolean OR logic when inherited pre-conditions are defined, but the derived class' pre-conditions are undefined? So currently, you'll need to rewrite all applicable pre-conditions for each derived class, because you don't know if one of the existing or future refactorings of a super-classes will weaken the input constraints. So you can't assume you'll ever successfully pass all inherited pre-conditions. I.e. you can only trust the class' own pre-conditions. This is where I get pretty fuzzy. How to address the issue? -Assuming I've understood it correctly and that it really is an issue. Can anyone back me up with a yea or neh as to whether or not this is real problem... or just my misunderstanding? I wonder if it might be useful to somehow tag a pre-condition to be invariably enforced ('AND') like post and invariant conditions... or alternatively marked as overridable ('OR' --the default) to allow loosing input constraints. Perhaps replacing the Class Foo example above with: Class Foo { method count($from, $to) { PRE { $to 10 } # 'is OR' is default PRE is AND { $from = .lower_bound } } } Class Bar is Foo { method count { PRE { .to 100 } } } Class Baz is Bar { method count { ... implementation ... } } With two more semantic changes: o modifying the 'OR'ing of a class' inherited pre-conditions to be only one inheritence level deep o a class which has no pre-conditions would be required to satisfy the inherited pre-conditions (no OR if undef) So calling Bar-count(-1, 99) where the current class (Bar) has no pre-conditions would DWIM. I.e., it would have to satisfy the 'OR' pre-conditions from Bar and the 'AND' pre-condition from Foo. Have I walked off into la-la land on a foundation of misunderstandings? -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
RE: Delegation syntax? (was: Re: Private contracts)
John Williams: Reaction #2: Inheritance would automatically delegate all those methods, so again, in what way does inheritance _not_ solve the problem? What about when you want to be able to dynamically swap the objects to which you're delegating? -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
RE: Private contracts?
Michael G Schwern: Garrett Goebel wrote: Michael G Schwern: shouldn't we have private invariants and conditions? no. Ummm, why? Maybe I'm just grinding an ax... If you allow an interface's post conditions and invariants to be overlooked, then you've got a broken interface. If you derive an interface then you've got to garrauntee to satisfy the same output and invariant constraints. You can't pick and chose, or your not deriving an interface. You're coming up with a new one. I think my ax could rest more peacefully if I could see more clearly how the syntax would allow us to clearly disambiguate between the interface and the implementation; constraints on a method's inputs and outputs as separate from how its implemented. I hope we're not going to explicitly seperate interfaces from implementation. ie. That you can define an interface at the same time as you implement it. This is something I really like about Perl as opposed to other OO systems, class definition and implementation are not kept seperate. I hope we do when we explicitly flag a class as an interface. After all, a class which isn't explicitly qualified as an interface still has one. And you can still attach pre, post, and invariant conditionals to its methods and attributes. I'd be a whole lot more happy with your syntax if you weren't explicitly hanging the 'is Interface' attribute off them. How can you garrauntee the interface when you conflate it with the implementation? It becomes difficult to separate the two. But I suppose that is what your private idea is all about. In the context of a class private means just don't inherit this. In the context of an interface private means this is not part of the interface. It still looks like it'll be messy when deep inheritence is involved. I guess I'm kosher with private conditions and invariants in the sense that any conditions on a private method or attribute would implicitly not be inherited. So long as private method is not considered part of an interface. However, I would still disagree with allowing private conditions on non-private methods. At least not when you're tagging the class with a label declaring it to be an interface, since non-private methods are implicitly part of the interface. Of course, if interfaces in the Java sense are just classes with no implementation details, there's no reason why you can't do it seperately. TIMTOWTDI. But if you're going to explicitly label something as an interface, the bondage and discipline ought to be consistent with DBC principles. Interface is not quite simply the union of method signature, conditions and invariants. Interfaces are a combination of the three, true, but it's only a subset of their use. They're all useful beyond simply enforcing how subclasses are designed and implemented. Understood. But again, if you're hanging an Interface tag on a class, you ought to be constricted to using them according to what they mean in the context of an interface. In short, go ahead and write it in a single class. You know where the interface leaves off and the implementation begins. Just don't hang the 'Interface' attribute off it. -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
Re: Private contracts?
On Fri, Oct 04, 2002 at 09:13:45AM -0400, Chris Dutton wrote: How exactly does one weaken a precondition? At least in Eiffel, if you redefine a method, you may not give it stringer preconditions than the original method, but you may have stronger postconditions. In essence, you're not requiring any more of the client, but you can ensure more to them on completion, thus maintaining the parent's contract. But what does it mean to be stronger? How does Eiffel figure out if a given precondition is stronger or weaker than another? -- Michael G Schwern [EMAIL PROTECTED] http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One
Re: Private contracts?
In a message dated Fri, 4 Oct 2002, [EMAIL PROTECTED] writes: On Fri, Oct 04, 2002 at 09:13:45AM -0400, Chris Dutton wrote: How exactly does one weaken a precondition? At least in Eiffel, if you redefine a method, you may not give it stringer preconditions than the original method, but you may have stronger postconditions. In essence, you're not requiring any more of the client, but you can ensure more to them on completion, thus maintaining the parent's contract. But what does it mean to be stronger? How does Eiffel figure out if a given precondition is stronger or weaker than another? Like I said before, boolean logic. Preconditions are OR'd together (starting with the deepest subclass and working back to the most ancestral class, in order to short-circuit most effectively), postconditions are AND'd together (in the opposite order, same reason). You responded that it couldn't work that way in Perl because Perl has expressions that are more complicated than booleans. I asked you what you meant by that, since the only definition of passing a condition I'm aware of in Perl is a boolean expression returning true. You haven't responded to that one yet. :-) Trey
Re: Private contracts?
On Fri, Oct 04, 2002 at 02:44:24PM -0500, Garrett Goebel wrote: shouldn't we have private invariants and conditions? no. Ummm, why? Maybe I'm just grinding an ax... If you allow an interface's post conditions and invariants to be overlooked, then you've got a broken interface. *** But they're *not part of the interface* *** Just to make it clear. :) Conditions and invariants are part of but not exclusive to the interface of a class. They're just well-done assertions. When inherited, they're part of the interface. When private and used as assertions on implementation detail, they're just assertions. The ability to define conditions on a class which must remain true at all times (mod the details of DBC rules) is very powerful and shouldn't be limited to simply defining an interface. Pre/post conditions about implementation details may not be terribly useful, but class invariants will. I think my ax could rest more peacefully if I could see more clearly how the syntax would allow us to clearly disambiguate between the interface and the implementation; constraints on a method's inputs and outputs as separate from how its implemented. This is what I'm proposing. invar { .foo eq 'bar' } # interface invar { .wibble eq 'miff' } is private # implementation It's inherited by default, and not inherited if declared private. Same as a method. I hope we're not going to explicitly seperate interfaces from implementation. ie. That you can define an interface at the same time as you implement it. This is something I really like about Perl as opposed to other OO systems, class definition and implementation are not kept seperate. I hope we do when we explicitly flag a class as an interface. After all, a class which isn't explicitly qualified as an interface still has one. I think the trouble here is that not everyone is going to want method signatures strictly enforced on their subclasses. So what the default behavior will be is really a matter of the philosophy of our OO implementation. Right now I'm assuming signatures will not be enforced unless you specify the class with an 'interface' property, but I could go either way. Conditions and invariants, OTOH, will always be enforced (unless declared private) otherwise they have little purpose. But I suppose that is what your private idea is all about. In the context of a class private means just don't inherit this. In the context of an interface private means this is not part of the interface. It still looks like it'll be messy when deep inheritence is involved. Private, how I see it, means don't inherit this *and* it can't be used outside the scope of this class. That second bit implies it's not part of the interface. To clarify: class Foo { method _bar is private { ... } method something { ._bar(foo); # ok, we're inside Foo } } my $foo = Foo.new; $foo._bar; # not ok. Even though we've got a Foo object, # we're outside the class declaration and can't # call private methods. However, I would still disagree with allowing private conditions on non-private methods. At least not when you're tagging the class with a label declaring it to be an interface, since non-private methods are implicitly part of the interface. But the private conditions are not part of the interface, even when placed on a public method. It's just a fancy assertion. It might help if you mentally s/private (condition|invariant)/assertion/g to help think of how they can be used seperate from in an interface. Just to clarify, in my world implementation and interface do not have to be seperated. An interface is merely a class which enforces it's method signatures on it's subclasses. In short, go ahead and write it in a single class. You know where the interface leaves off and the implementation begins. Just don't hang the 'Interface' attribute off it. I think most of what we're arguing about is what baggage term interface carries with it. I'm neither from a DBC nor Java background, so to me interface just means how you use the thing and it happens to be inherited. I think you're reading more into it than my deliberately simplistic definition. The other part that's up in the air is if method signatures will be enforced on subclasses by default or if you have to turn this feature on. So far, I'm assuming it won't be enforced by default and using the is interface property to turn it on. Like I said, I could go either way and the choice of property name just happens to go with what I feel an interface is. -- Michael G Schwern [EMAIL PROTECTED] http://www.pobox.com/~schwern/ Perl Quality Assurance
Re: Private contracts?
On Fri, Oct 04, 2002 at 06:26:31PM -0400, Trey Harris wrote: But what does it mean to be stronger? How does Eiffel figure out if a given precondition is stronger or weaker than another? Like I said before, boolean logic. Preconditions are OR'd together (starting with the deepest subclass and working back to the most ancestral class, in order to short-circuit most effectively), postconditions are AND'd together (in the opposite order, same reason). I can see too many problems with that technique, I think one was already mentioned where subclasses can unintentionally weaken preconditions to the point of eliminating them. I'm sort of casting about looking for another way. -- Michael G Schwern [EMAIL PROTECTED] http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One
RE: Private contracts?
Michael G Schwern [EMAIL PROTECTED] wrote: I can see too many problems with that technique, I think one was already mentioned where subclasses can unintentionally weaken preconditions to the point of eliminating them. Which is, of course, why we OR them, yet AND the postconditions It is perfectly valid for an implementation to say I can meet the post-condition, no matter what input you give me i.e. it can eliminate the precondition, but not the postcondition. As code: class Math is interface { method sqrt (int $x) { PRE { $x = 0 } POST { sqrt($x) * sqrt($x) == $x } } } class KnowsAboutComplex is Math { method sqrt (int $x) { PRE { TRUE } # calc result, possibly complex } } Of course, KnowsAboutComplex would be invalid if the interface had required the result to be a Real. Dave.
Re: Private contracts?
In a message dated Fri, 4 Oct 2002, [EMAIL PROTECTED] writes: On Fri, Oct 04, 2002 at 06:26:31PM -0400, Trey Harris wrote: But what does it mean to be stronger? How does Eiffel figure out if a given precondition is stronger or weaker than another? Like I said before, boolean logic. Preconditions are OR'd together (starting with the deepest subclass and working back to the most ancestral class, in order to short-circuit most effectively), postconditions are AND'd together (in the opposite order, same reason). I can see too many problems with that technique, I think one was already mentioned where subclasses can unintentionally weaken preconditions to the point of eliminating them. I'm sort of casting about looking for another way. Could you illustrate a case? I don't know what you're talking about. It's completely valid to eliminate a precondition, because true is the weakest possible precondition. By definition, an assertion P is weaker than another assertion Q iff Q implies P. Requiring a computer to determine if some condition A, expressed in arbitrary computer code, is weaker than some condition B, also expressed in arbitrary computer code, is unsolvable in the general case and equivalent to the halting problem. So, you either abandon the general case and incorporate a theorem prover into the compiler (!) or you make use of the following theorem: (P or Q) is weaker than Q, because Q implies (P or Q). Trey
Re: Private contracts?
On Fri, Oct 04, 2002 at 08:21:55PM -0400, Trey Harris wrote: I can see too many problems with that technique, I think one was already mentioned where subclasses can unintentionally weaken preconditions to the point of eliminating them. I'm sort of casting about looking for another way. Could you illustrate a case? I don't know what you're talking about. It's completely valid to eliminate a precondition, because true is the weakest possible precondition. I thought someone had posted an example, but now I can't find it and I can't remember what it was. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One It sure is fun masturbating. http://www.unamerican.com/
Re: Private contracts?
On Thu, Oct 03, 2002 at 02:46:38PM -0400, Michael G Schwern wrote: class ATV is Car, interface { Hmmm. That should probably be class ATV isa Car is interface { -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Help, help! A Heffalump, a Horrible Heffalump! Help, help, a Herrible Hoffalump! Hoff, Hoff, a Hellible Horralump!
Re: Private contracts?
I've been mucking about a bit more with this whole interface thing. So if we make method signatures only enforced on subclasses if the parent class or method has the interface property... except private methods, obviously. And if we make pre/post conditions and class invariants always enforced... shouldn't we have private invariants and conditions? Semi-tangential to the point of your message... With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. The postcondition is not really a problem since one can always add additional checks. However, if the parent's preconditions apply to the child invariably, it would be rather difficult to make your subclass accept a wider variety of input. I'm not proposing a solution, but rather just a problem to keep in mind. Mike Lambert
Re: Private contracts?
On Thu, Oct 03, 2002 at 03:00:21PM -0400, Michael G Schwern wrote: On Thu, Oct 03, 2002 at 02:46:38PM -0400, Michael G Schwern wrote: class ATV is Car, interface { Hmmm. That should probably be class ATV isa Car is interface { That's: class ATV is Car is interface { We haven't finally decided how properties will be defined. They may be subs: sub *PropertyName is property ($referent, $data) {...} they may be methods: method PropertyName is property ($self: $data) {...} they may be classes: class PropertyName is Property {...} # or, like grammar definitions property PropertyName {...} or they may be some variation on these or something else entirely. However they're defined, they will be clearly marked internally as properties, so there's little risk of confusing property attachment with inheritance. Allison
Re: Private contracts?
On Thu, Oct 03, 2002 at 03:45:33PM -0500, Allison Randal wrote: On Thu, Oct 03, 2002 at 03:00:21PM -0400, Michael G Schwern wrote: On Thu, Oct 03, 2002 at 02:46:38PM -0400, Michael G Schwern wrote: class ATV is Car, interface { Hmmm. That should probably be class ATV isa Car is interface { That's: class ATV is Car is interface { Wouldn't this mean that class names and property names will inevitably clash, so you can't have a class and a property with the same name? -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One The key, my friend, is hash browns. http://www.goats.com/archive/980402.html
Re: Private contracts?
On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote: With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. How exactly does one weaken a precondition? -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Home of da bomb
Re: Private contracts?
Makes sense, no? I like that quite a lot. One question I still have is the syntax of pre/post conditions, e.g: method turn($direction, $how_sharp) { pre { $how_sharp = 20 } is private; ...implementation... } This is obviously how it would fall out from Apocalypse 4, pre/post being basically types of exception, but I keep having nagging concerns about it. To me, this keeps looking like pre { ... } is a precondition attached to the _implementation_ of the given method, not the _signature_ of a given method... For the is private case above, it doesn't make much difference, but I keep thinking something like the below just feels wonky (?)... class Vehicle is interface { attr $tilt; attr $min_sharpness; method turn($direction, $how_sharp) { pre { $how_sharp = $self.min_sharpness } ... a default implementation, if desired ... } } class Car is Vehicle { method turn { # this calls the precondition ... $self.SUPER.turn( ... );# ... hopefully not twice? ... ... a derived implementation ... } } class Cycle is Vehicle { method turn { # does this call the precondition? YES? ... a completely alternative implementation that doesn't call super } } Do you think it's sufficiently clear to newbies that the pre { } is associated with the signature of the turn() interface method, and not just the _implementation_ of turn() in Vehicle? e.g. I want a precondition associated with turn() that is called for _all_ subclasses, whether they call the superclass implementation of turn() or not, is it clear that that's going on? _IS_ it going on, in the above? On Thursday, October 3, 2002, at 01:11 PM, Allison Randal wrote: BTW, that's: attr $.tilt; Attributes are private by default. (As a lame aside, are we going to have a concept of private vs. protected vs. public, or just private/public? (In other words, does private permit access by subclasses?) Not recommending it, just wondering if anyone thinks we need it.) MikeL
Re: Private contracts?
In a message dated Thu, 3 Oct 2002, Michael G Schwern writes: On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote: With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. How exactly does one weaken a precondition? You weaken a precondition by adding ORs; you strengthen a postcondition by adding ANDs. Trey
Re: Private contracts?
On Thu, Oct 03, 2002 at 05:14:22PM -0400, Michael G Schwern wrote: On Thu, Oct 03, 2002 at 03:45:33PM -0500, Allison Randal wrote: On Thu, Oct 03, 2002 at 03:00:21PM -0400, Michael G Schwern wrote: On Thu, Oct 03, 2002 at 02:46:38PM -0400, Michael G Schwern wrote: class ATV is Car, interface { Hmmm. That should probably be class ATV isa Car is interface { That's: class ATV is Car is interface { Wouldn't this mean that class names and property names will inevitably clash, so you can't have a class and a property with the same name? Yes. But if properties are classes (the generally favored solution, at least until Zurich), that's to be expected. So far, classes are uppercase and properties are lowercase, but that's convention, not law. Allison
RE: Private contracts?
Michael G Schwern: I've been mucking about a bit more with this whole interface thing. So if we make method signatures only enforced on subclasses if the parent class or method has the interface property... except private methods, obviously. And if we make pre/post conditions and class invariants always enforced... no. post-conditions and invariants are always enforced, but pre-conditions are different. A derived interface can loosen input constraints... so it must be able to either satisfy all inherited pre-conditions _or_ its own pre-conditions. shouldn't we have private invariants and conditions? no. I should inject that I disagree with the use of term private as meaning non-inheritable. I think of private as an methods and attributes accessible only within the namespace of that class or its descendants. Perhaps a better term would be something like: method foo is disinherited { ... } I also need to separate out the DBC topic from the interface one. For instance I have a hard time thinking about attributes in the context of interfaces. For me, interfaces should be limited to a bunch of abstract methods with conditions. Any other declarations within an interface IMO should be errors. I.e., all other declarations belong in the implementation class... If you want to have a public and private inheritable interfaces that's fine. But what's the point of a non-inheritable interface? Myself, I call non-inheritable methods functions. class ATV is Car, interface { attr _tilt is private; invar { ._tilt = 20 } is private; method turn($direction, $how_sharp) { pre { $how_sharp = 20 } is private; ...implementation... } } An interface shouldn't have attributes. And per above, private pre-conditions are pointless. I would rewrite the above as: class ATV is Car, interface { invar { .tilt = 20 }; method tilt() is private; # in the to class heirachy sense method turn($direction, $how_sharp) { pre { $how_sharp = 20 }; } } I've implemented an ATV where I've put in a saftey protection against rolling over in a turn as both an invariant and a pre-condition. It will not allow you to turn the car too sharply, else it simply blows up. Wait second... ;) But I don't want my subclasses to be constrained by that. It's just an implementation detail that I only wish to enforce upon ATV and not it's children. So they're private. Makes sense, no? No. Per DBC, pre-conditions are satisfied if either the inherited pre-conditions _or_ its own pre-conditions are satisfied. Thus allowing the loosening of input constraints which I believe is what you're after. -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
Re: Private contracts?
In a message dated Thu, 3 Oct 2002, Allison Randal writes: So far, classes are uppercase and properties are lowercase, but that's convention, not law. Do runtime (value) properties and compile-time (variable) properties share the same namespace? That is, to go back to an earlier discussion, if there is a system-defined value property Ctrue which marks a value as true in boolean contexts, can I also define a compile-time property Ctrue that makes the variable evaluate as true, whatever its value? Trey
RE: Private contracts?
Garrett Goebel: Michael G Schwern: But I don't want my subclasses to be constrained by that. It's just an implementation detail that I only wish to enforce upon ATV and not it's children. implementation details don't belong in interfaces
Re: Private contracts?
On Thu, Oct 03, 2002 at 02:29:57PM -0700, Michael Lazzaro wrote: (As a lame aside, are we going to have a concept of private vs. protected vs. public, or just private/public? No protected. Even Stroustrup admits it was a mistake in DE. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net
Re: Private contracts?
On Thu, Oct 03, 2002 at 02:29:57PM -0700, Michael Lazzaro wrote: One question I still have is the syntax of pre/post conditions, e.g: method turn($direction, $how_sharp) { pre { $how_sharp = 20 } is private; ...implementation... } This is obviously how it would fall out from Apocalypse 4, pre/post being basically types of exception, but I keep having nagging concerns about it. To me, this keeps looking like pre { ... } is a precondition attached to the _implementation_ of the given method, not the _signature_ of a given method... I don't know, but I think it's supposed to be like this: # part of the signature method turn($dir,$ang) is pre { $ang = 20 } { ... } # part of the implementation method turn($dir,$ang) { PRE { $ang = 20 } ... } turn() methods of derived classes would inherit the precondition in the first case but not the second. I don't know why you'd want to do this exactly, but it seems to me that perl should allow it. On Thursday, October 3, 2002, at 01:11 PM, Allison Randal wrote: BTW, that's: attr $.tilt; Attributes are private by default. (As a lame aside, are we going to have a concept of private vs. protected vs. public, or just private/public? (In other words, does private permit access by subclasses?) Not recommending it, just wondering if anyone thinks we need it.) I don't think we should be actively reproducing C++'s mistakes :-) With the constructs shown so far, I can guess that it should be possible for someone to implement protected if they wanted it. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Private contracts?
On Thu, Oct 03, 2002 at 04:54:13PM -0500, Garrett Goebel wrote: Garrett Goebel: Michael G Schwern: But I don't want my subclasses to be constrained by that. It's just an implementation detail that I only wish to enforce upon ATV and not it's children. implementation details don't belong in interfaces It's encoded as a private condition, so it's not part of the interface. I see class invariants and conditions as just powerful, well organized assertions, so naturally I'm going to want to use them for more than just specifying an interface contract. In this case, I'm using them to ensure that internal details of my implementation are kept in order. It would be silly to have to define a whole new syntax for that purpose, so I just make them private. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One The eye opening delightful morning taste of expired cheese bits in sour milk!
Re: Private contracts?
On Thu, Oct 03, 2002 at 05:23:08PM -0500, Jonathan Scott Duff wrote: I don't know, but I think it's supposed to be like this: # part of the signature method turn($dir,$ang) is pre { $ang = 20 } { ... } # part of the implementation method turn($dir,$ang) { PRE { $ang = 20 } ... } turn() methods of derived classes would inherit the precondition in the first case but not the second. I don't know why you'd want to do this exactly, but it seems to me that perl should allow it. I see us already smashing too many things into the method signature as it is. It will rapidly get messy if you have a method with a complex signature and a handful of attributes and preconditions. Also, where do the postconditions go? In the signature at the front? That doesn't make sense, it should go at the end so you can keep them in mind when you're writing the return code. Consider... method foo($this, $that) is memoized is something is pre { $this = 42 } is pre { $that == $this / 2 } is pre { a lot of code which is hard to shove into a block of code this close to the right margin } is post { what is a post condition doing at the front? } { ... } They can, of course, be pulled back from the margin: method foo($this, $that) is memoized is something is pre { $this = 42 } is pre { $that == $this / 2 } is pre { now we have a little bit more room to play with using a differnt indentation style } is post { but post conditions are still distanced from the code which return()s } { ... } I realize that conditions are technically part of the signature, but putting them in there paints us into a stylistic corner. I'm also not fond of the pre/PRE distinction. Few of the other special blocks (given, eval, try, invar, etc...) use all cap names. At least I hope not. Simply attaching an is private attribute to a pre condition block seems the simplest way to go about it. Just like any other private thing, it's not inherited and not visible outside the current class. pre vs PRE doesn't convey that meaning. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One AY! The ground beef, she is burning my groin! http://sluggy.com/d/990105.html
Re: Private contracts?
On Thu, Oct 03, 2002 at 02:29:57PM -0700, Michael Lazzaro wrote: Do you think it's sufficiently clear to newbies that the pre { } is associated with the signature of the turn() interface method, and not just the _implementation_ of turn() in Vehicle? The rule would be pretty simple to teach and remember, conditions and invariants are inherited unless made private. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One It's Flypaper Licking time!
Re: Private contracts?
On Thu, Oct 03, 2002 at 05:30:49PM -0400, Trey Harris wrote: In a message dated Thu, 3 Oct 2002, Michael G Schwern writes: On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote: With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. How exactly does one weaken a precondition? You weaken a precondition by adding ORs; you strengthen a postcondition by adding ANDs. As expressions in Perl run a tad beyond simple boolean logic, could you give a concrete example? -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One My beverage utensil experiences a volume crisis.
Delegation syntax? (was: Re: Private contracts)
On Thursday, October 3, 2002, at 03:18 PM, Paul Johnson wrote: (As a lame aside, are we going to have a concept of private vs. protected vs. public, or just private/public? No protected. Even Stroustrup admits it was a mistake in DE. Oh, thank God. I was hoping people would say that. OK, for an entirely different thread... Is there an accepted preliminary syntax for OO delegation? (I've looked and can't find anything definitive.) By delegation, I mean two different things (you can tell OO programming has firmly arrived by the fact that, Babel-like, no group of people can ever agree on the meaning of any given term, making all conversations painful). 1) Delegation through inheritance: (a.k.a. mixin classes, hard delegation, concrete interfaces, etc., etc.) Example: I want to say that a class DataManager has the capabilities of the interfaces DataStrategy and CacheStrategy, but is not strictly a subclass of either. In other languages, this might appear like: class DataManager implements DataStrategy, CacheStrategy { ... } - or - class DataManager mixin DataStrategy, CacheStrategy { ... } (yes, I know you probably wouldn't do a Manager/Strategy like that. it's just an example, and my mind is blanking right now...) 2) Delegation through attribute: (a.k.a soft delegation, instance-based delegation, etc., etc.) The ability to specify that, if an instance of an object DataSnippet is affiliated with a specific, runtime instance of a DataManager, e.g. class DataSnippet { attr $data_manager is DataManager; } ... then [some, all] public methods of $self.data_manager can automatically be delegated by the DataSnippet to that specific instance, eliminating the need for code that makes you want to kill yourself: method foo (...) { $self.data_manager.foo( ... ) } method bar (...) { $self.data_manager.bar( ... ) } # ... repeat until carpel tunnel syndrome sets in ... I have no *good* syntax proposals for this, I don't think I've ever seen the problem solved with syntax that I really ever liked. MikeL
RE: Private contracts?
Michael G Schwern: On Thu, Oct 03, 2002 at 05:30:49PM -0400, Trey Harris wrote: In a message dated Thu, 3 Oct 2002, Michael G Schwern writes: On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote: With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. How exactly does one weaken a precondition? You weaken a precondition by adding ORs; you strengthen a postcondition by adding ANDs. As expressions in Perl run a tad beyond simple boolean logic, could you give a concrete example? all inherited pre-conditions pass or class' own pre-conditions pass -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
Re: Private contracts?
On Thu, Oct 03, 2002 at 04:47:26PM -0500, Garrett Goebel wrote: And if we make pre/post conditions and class invariants always enforced... no. post-conditions and invariants are always enforced, but pre-conditions are different. Right, right. A derived interface can loosen input constraints... so it must be able to either satisfy all inherited pre-conditions _or_ its own pre-conditions. Looking around, this seems to be regarded as something of a compromise because truly determining what a real logical weaking is is hard. Are there other ways to do it, just to mull them over? shouldn't we have private invariants and conditions? no. Ummm, why? I should inject that I disagree with the use of term private as meaning non-inheritable. I think of private as an methods and attributes accessible only within the namespace of that class or its descendants. Isn't that protected? As I understand it, Perl 6's private will be non-inheritable methods accessable only inside the class which defined it. Ruby does it this way, AFAIK. Perhaps a better term would be something like: method foo is disinherited { ... } is disowned is get_a_haircut_and_a_job is i_have_no_son ;) I also need to separate out the DBC topic from the interface one. For instance I have a hard time thinking about attributes in the context of interfaces. For me, interfaces should be limited to a bunch of abstract methods with conditions. Any other declarations within an interface IMO should be errors. I.e., all other declarations belong in the implementation class... I hope we're not going to explicitly seperate interfaces from implementation. ie. That you can define an interface at the same time as you implement it. This is something I really like about Perl as opposed to other OO systems, class definition and implementation are not kept seperate. class Human is interface { attr head, shoulders, knees, toes; invar { .head == 1 } invar { .shoulders == 2 } invar { .knees == 2 } invar { .toes == 10 } method talk ($say,$how_loud) { $say.uc if $how_loud = 10: print $say\n; } } Of course, if interfaces in the Java sense are just classes with no implementation details, there's no reason why you can't do it seperately. class AbstractHuman is interface { attr head, shoulders, knees, toes; invar { .head == 1 } invar { .shoulders == 2 } invar { .knees == 2 } invar { .toes == 10 } method talk ($say,$how_loud); } class Human isa AbstractHuman { method talk ($say,$how_loud) { $say.uc if $how_loud = 10: print $say\n; } } The above would result in the same thing. The latter explicitly seperates the interface from the implementation, as some like, while the former does them all in one class, as others like. If you want to have a public and private inheritable interfaces that's fine. But what's the point of a non-inheritable interface? Myself, I call non-inheritable methods functions. Interface is not quite simply the union of method signature, conditions and invariants. Interfaces are a combination of the three, true, but it's only a subset of their use. They're all useful beyond simply enforcing how subclasses are designed and implemented. Method signatures are obviously used to define how methods are to be called by outside users of the object, as well as change the contexts in which the arguments are parsed. Pre/post conditions and invariants, when private (ie. not inherited) can be used like assertions, guaranteeing that internal state and implementation details are kept sane. My ATV example may not have been clear enough in that I considered the tilt check to be an internal state check and not a documented feature of the object. A clearer example might be something like checking that an internal data structure used by the object is not circular. A class invariant, yet not something I want to enforce on my children. They're tools that when combined form an interface but are still useful seperately. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One The key, my friend, is hash browns. http://www.goats.com/archive/980402.html
Re: Private contracts?
On Thu, Oct 03, 2002 at 06:46:14PM -0400, Michael G Schwern wrote: I see us already smashing too many things into the method signature as it is. It will rapidly get messy if you have a method with a complex signature and a handful of attributes and preconditions. I think I have my own counter example. Consider defining an abstract class with an interface and I want to put some conditions onto an abstract method. class Abstract::Human is interface { attr head, shoulders, knees, toes; invar { .head == 1 } invar { .shoulders == .knees == .toes == 2 } method eat ($food) is pre { !$food.isa('Poison') } is post { .return eq 'Burp' } } since I have no method body for eat() I have no choice but to hang it off the signature as an attribute. So conditions do have to go on the signature, but I still like the option of their being in the body as well, especially given the problem of wanting to put post conditions at the end. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Cottleston, Cottleston, Cottleston Pie. A fly can't bird, but a bird can fly. Ask me a riddle and I reply: Cottleston, Cottleston, Cottleston Pie.
Re: Delegation syntax? (was: Re: Private contracts)
On Thu, 3 Oct 2002, Michael Lazzaro wrote: 1) Delegation through inheritance: (a.k.a. mixin classes, hard delegation, concrete interfaces, etc., etc.) Example: I want to say that a class DataManager has the capabilities of the interfaces DataStrategy and CacheStrategy, but is not strictly a subclass of either. In other languages, this might appear like: class DataManager implements DataStrategy, CacheStrategy { ... } - or - class DataManager mixin DataStrategy, CacheStrategy { ... } Aside from runtime mixin', in what way does inheritance _not_ do what you want? 2) Delegation through attribute: (a.k.a soft delegation, instance-based delegation, etc., etc.) The ability to specify that, if an instance of an object DataSnippet is affiliated with a specific, runtime instance of a DataManager, e.g. class DataSnippet { attr $data_manager is DataManager; } ... then [some, all] public methods of $self.data_manager can automatically be delegated by the DataSnippet to that specific instance, eliminating the need for code that makes you want to kill yourself: method foo (...) { $self.data_manager.foo( ... ) } method bar (...) { $self.data_manager.bar( ... ) } # ... repeat until carpel tunnel syndrome sets in ... Reaction #1: Only on a perl list would it occur to people to complain about that. :) Reaction #2: Inheritance would automatically delegate all those methods, so again, in what way does inheritance _not_ solve the problem? Finally, a question about interfaces: In what way is an interface different from a pure abstract class (i.e. containing only method declarations, but no code)? ~ John Williams DISCLAIMER: This post assumes perl6 will have multiple inheritance.
Re: Private contracts?
On Thu, 3 Oct 2002, Trey Harris wrote: Incidentally, has there been any headway made on how you DO access multiple classes with the same name, since Larry has (indirectly) promised us that? I.e., I import two classes LinkedList and BTree, both of which define a Node class? Hopefully, LinkedList defines a LinkedList::Node class, and BTree defines a BTree::Node class. Either by explicitly naming them that or by virtue of being defined as an inner class (which might also make it private). ~ John Williams
Re: Private contracts?
In a message dated Thu, 3 Oct 2002, John Williams writes: On Thu, 3 Oct 2002, Trey Harris wrote: Incidentally, has there been any headway made on how you DO access multiple classes with the same name, since Larry has (indirectly) promised us that? I.e., I import two classes LinkedList and BTree, both of which define a Node class? Hopefully, LinkedList defines a LinkedList::Node class, and BTree defines a BTree::Node class. Either by explicitly naming them that or by virtue of being defined as an inner class (which might also make it private). Ah, but that's the way you do it now--name the classes differently. (Easy--assuming you control the source code!) In Perl 6, we're supposed to be able to use multiple versions of the same class concurrently, which I think would imply also being able to use multiple classes that happened to be named the same thing. Trey
Re: Delegation syntax? (was: Re: Private contracts)
On Thu, Oct 03, 2002 at 07:59:33PM -0600, John Williams wrote: Reaction #2: Inheritance would automatically delegate all those methods, so again, in what way does inheritance _not_ solve the problem? I don't think p6l is the right place to discuss the merits of delegation, let's just say it's a Good Thing to have in your OO toolbelt. Solves a lot of problems which would otherwise require hairy, ambiguous multiple inheritance situations. If you're curious I can explain more off-list. Finally, a question about interfaces: In what way is an interface different from a pure abstract class (i.e. containing only method declarations, but no code)? An interface requires subclassers to implement all abstract methods and they must match the method signatures, conditions and invariants of the interface. A pure abstract class doesn't necessarily require subclasses to do anything, at least not in Perl. So an interface is simply a class, maybe abstract, which requires its subclasses to conform to its signature. At least that's how I see it. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One It's Airplane Glue sniffing time!
Re: Private contracts?
Michael G Schwern wrote: How exactly does one weaken a precondition? Say I define a mathematical mod() function in my parent number class. precondition: $a 0, $b 0, $b is int mod( $a, $b ) Then in my subclass, I want to make it work in a wider variety of contexts. I change the definition to: precondition: $b is int, $b != 0 mod( $a, $b ) It now properly supports modulo arithmetic for negative numbers, because the requirements for running the function have been weakened. It is still completely substitutable anywhere that the parent implementation would work, but if code is dealing with my subclass it is allowed to work with the weakened precondition. Since your proposal was based upon the idea of having every parent condition apply to child implementations, the possibility for strengthened postconditions falls out of the proposal nicely. But since preconditions work in the opposite direction, they don't quite gel with that particular proposal. Mike Lambert
RE: Private contracts?
In a message dated Thu, 3 Oct 2002, Garrett Goebel writes: Michael G Schwern: On Thu, Oct 03, 2002 at 05:30:49PM -0400, Trey Harris wrote: In a message dated Thu, 3 Oct 2002, Michael G Schwern writes: On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote: With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. How exactly does one weaken a precondition? You weaken a precondition by adding ORs; you strengthen a postcondition by adding ANDs. As expressions in Perl run a tad beyond simple boolean logic, could you give a concrete example? I don't know what you mean. How can a precondition be anything but boolean? all inherited pre-conditions pass or class' own pre-conditions pass I'm afraid I'm a bit lost here. What does pass mean besides evaluates to true in a boolean context? And if that's what pass means, then can't you just OR the preconditions together, in subclass-to-superclass order? Trey