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: Delegation syntax?
At 12:37 AM -0400 10/4/02, Michael G Schwern wrote: Delegation is a basic OO technique. We definately should have fast, well-designed core support for it. I'm pretty sure we will. I certainly need it internally... -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
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: Security model for Perl with good support in Parrot (Safe/Opc ode etc.)
--- David Whipp [EMAIL PROTECTED] wrote: Kv Org [mailto:[EMAIL PROTECTED]] wrote I believe Perl6 needs a facility to run compartmented code (object-oriented and module-loading) that is tagged as to its permissions and owner ID. The goal would be to let such code use harmful actions only by calling permitteed outside functions that implement permission checks before calling potentially harmful code. I'm not an expert in this area, but I think that a capabilities based model is probably better than compartments. Capabilities are a more generalised term for what is done with OpCode masks in Perl5. Compartments introduce a very important new concept: they provide a way to specify specially restricted capabilities for a part of code inside a given program, giving essentially a chrooted namespace. Code inside a Safe compartment can't get at any data outside of the compartment unless it is given special premission. That means that a part of your program can run without any restrictions, while another part is heavily restricted. That only begins to make sense when you imagine that other part being written by another user, read into the running perl, evaled and then called at appropriate time. The model would be that a program starts with a set of capabilities; and then any code that it calls (or thread that it starts) would inherit these capabilies -- a function call (or thread start) could explicity deny some capabilities to the code that it calls; also, a function could return additional capabilities to the caller. Capabilities could be stored as a hash in the %MY pad. The capability to add stuff to that hash would, of course, be highly restricted. A capability is probably just an object: any module can define any number of capabilities; but only it (not its subclasses) has the right to create instances of that capability (which it can then return to a requesting caller). When a function later trys to use a protected method, that method would check that its Ccaller has an appropriate capability I am a bit unsure about specification details here. I suspect Parrot will somehow need to have access to data about what parts of Perl (or other) source generated the current bytecode to generate error messages. I suspect a similar mechanism could be used to store information about _ownership_ of a part of code and use that in the capability granting methods. Many things are unclear here since the only reference specification (for lack of any RFCs dealing with the problem) is OpCode.pm and Safe.pm combo, which has problems and is very perl5 specific. I think a perl (and a parrot) program should be able to assign an user identity to parts of code (similar but not directly mapped to unix user ids, of course) and then be able to do capability/security decisions based on that. In this way I might be able to insert code into a running system but have it run with restricted permissions so it could not mess with the running program, only process data it gets handled to its functions and return results. Such code should be able to load modules and call functions in other modules, but probably only through securtiy-enforcing proxies. LPC, the C-like scripting language of LP Muds, was the most interesting implementation I have been able to find. It needs to deal with the problem of a multi-user programming environment running under a single unix user ID and inside a single process. It solves the problem with an object-oriented structure and file-based user/group ID system. It uses real user ID inside the MUD system to keep track of things and an effective user ID to grand extra permissions. Objects of one user can only communicate with other users's objects via root id objects that implement permission checks etc, or, in some implementations, the objects can do security checks themselves since object data can only be handled through accessor (get-set) methods and all communication between two objects is thus limited to method calls and system calls that themselves call method calls on other objects. It is a simple and very efficient system that has been used in multi-user gaming environments for over 10 years. But while it fulfills most of the requests I mentioned it maps badly to the perl6 paradigm of byte-compiled platform without a well-defined code-file relationship and non-blackbox object implementation where there are no restrictions to changing variables or even function definitions in other namespaces. From perl's point of view, restricted code parts should probably be put under a special namespace hierarchy with all the capability checking and granting hidden well away. A clear semanitcs for interaction with non-restricted and other restricted modules would need to be specified to enable such restricted code to call functions in other parts of code and, above all, use module libraries. Unfortunately, that is a nontrivial itch I can't scratch myself. Fortunatelly it
RE: Security model for Perl with good support in Parrot (Safe/Opc ode etc.)
--- David Whipp [EMAIL PROTECTED] wrote: Kv Org [mailto:[EMAIL PROTECTED]] wrote I believe Perl6 needs a facility to run compartmented code (object-oriented and module-loading) that is tagged as to its permissions and owner ID. The goal would be to let such code use harmful actions only by calling permitteed outside functions that implement permission checks before calling potentially harmful code. I'm not an expert in this area, but I think that a capabilities based model is probably better than compartments. Capabilities are a more generalised term for what is done with OpCode masks in Perl5. Compartments introduce a very important new concept: they provide a way to specify specially restricted capabilities for a part of code inside a given program, giving essentially a chrooted namespace. Code inside a Safe compartment can't get at any data outside of the compartment unless it is given special premission. That means that a part of your program can run without any restrictions, while another part is heavily restricted. That only begins to make sense when you imagine that other part being written by another user, read into the running perl, evaled and then called at appropriate time. The model would be that a program starts with a set of capabilities; and then any code that it calls (or thread that it starts) would inherit these capabilies -- a function call (or thread start) could explicity deny some capabilities to the code that it calls; also, a function could return additional capabilities to the caller. Capabilities could be stored as a hash in the %MY pad. The capability to add stuff to that hash would, of course, be highly restricted. A capability is probably just an object: any module can define any number of capabilities; but only it (not its subclasses) has the right to create instances of that capability (which it can then return to a requesting caller). When a function later trys to use a protected method, that method would check that its Ccaller has an appropriate capability I am a bit unsure about specification details here. I suspect Parrot will somehow need to have access to data about what parts of Perl (or other) source generated the current bytecode to generate error messages. I suspect a similar mechanism could be used to store information about _ownership_ of a part of code and use that in the capability granting methods. Many things are unclear here since the only reference specification (for lack of any RFCs dealing with the problem) is OpCode.pm and Safe.pm combo, which has problems and is very perl5 specific. I think a perl (and a parrot) program should be able to assign an user identity to parts of code (similar but not directly mapped to unix user ids, of course) and then be able to do capability/security decisions based on that. In this way I might be able to insert code into a running system but have it run with restricted permissions so it could not mess with the running program, only process data it gets handled to its functions and return results. Such code should be able to load modules and call functions in other modules, but probably only through securtiy-enforcing proxies. LPC, the C-like scripting language of LP Muds, was the most interesting implementation I have been able to find. It needs to deal with the problem of a multi-user programming environment running under a single unix user ID and inside a single process. It solves the problem with an object-oriented structure and file-based user/group ID system. It uses real user ID inside the MUD system to keep track of things and an effective user ID to grand extra permissions. Objects of one user can only communicate with other users's objects via root id objects that implement permission checks etc, or, in some implementations, the objects can do security checks themselves since object data can only be handled through accessor (get-set) methods and all communication between two objects is thus limited to method calls and system calls that themselves call method calls on other objects. It is a simple and very efficient system that has been used in multi-user gaming environments for over 10 years. But while it fulfills most of the requests I mentioned it maps badly to the perl6 paradigm of byte-compiled platform without a well-defined code-file relationship and non-blackbox object implementation where there are no restrictions to changing variables or even function definitions in other namespaces. From perl's point of view, restricted code parts should probably be put under a special namespace hierarchy with all the capability checking and granting hidden well away. A clear semanitcs for interaction with non-restricted and other restricted modules would need to be specified to enable such restricted code to call functions in other parts of code and, above all, use module libraries. Unfortunately, that is a nontrivial itch I can't scratch myself. Fortunatelly it
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: We need an OO issue list tutorial!
From: Michael Lazzaro [EMAIL PROTECTED] Proposed Remedy: We need to better document our discussions so that we don't keep having them. That's a groovy idea. It'll help us all by defining terms and providing examples to wrap our brains around. An idea to add to the general concept of Perl6 cookbooks: we could use a lot more of Damian's And now for something completely similar concept. There's a growing fear out there that Perl6 is going to crumble everyone's houses in an earthquake of shifting paradigms. Every Perl6 cookbook would do well to start with some delightfully childlike examples like this: # Perl5 blah(); # Perl6 blah(); Stuff like that eases people into the Perl6 world by starting with the familiar. Perhaps to go with Apocalypses and Exegeses we could have Psalms, a bunch of bitsize perls of wisdom. Except, um, psalms are, by definition, sacred, so, um, I dunno, just a thought. Larry? -Miko mail2web - Check your email from the web at http://mail2web.com/ .
Re: We need an OO issue list tutorial!
On Friday, October 4, 2002, at 12:52 PM, [EMAIL PROTECTED] wrote: Perhaps to go with Apocalypses and Exegeses we could have Psalms, a bunch of bitsize perls of wisdom. Except, um, psalms are, by definition, sacred, so, um, I dunno, just a thought. Larry? Perhaps Prophecies. Or Genisii. Or Caffeine-Induced Fever Visions... And Lo, it shall come to pass that Objects shall spring forth as Patterns on the water. Inheritance shall be multiple, and duplicitous. He who walks the path of Inheritance shall avert his eyes, or I shall smite thee... MikeL
RE: We need an OO issue list tutorial!
On Fri, 4 Oct 2002, [EMAIL PROTECTED] wrote: Perhaps to go with Apocalypses and Exegeses we could have Psalms, a bunch of bitsize perls of wisdom. Except, um, psalms are, by definition, sacred, so, um, I dunno, just a thought. Larry? Proverbs?
Re: We need an OO issue list tutorial!
On Fri, 4 Oct 2002, Michael Lazzaro wrote: Observation: We're doing a *lot* of talking past each other. Proposed Remedy: We need to better document our discussions so that we don't keep having them. --- I volunteer (*shudder*) to be another grunt secretary and start compiling a preliminary document, written as a tutorial for newbies (because we are *all* newbies when it comes to perl6 OO) that covers perl6 OO philosophies as they evolve -- if everyone is ok with that idea, and if nobody else is already doing it. Yeah! Derived from the RFCs and subsequent discussions, here is a proposed OO Bill of Rights: fundamental truths that I *think* are already agreed upon, and from which all other OO laws must be derived: (OO Article 1) It should be possible, in general, to do anything you did in perl5 in perl6. (OO Article 2) perl6 should not be geared towards any one OO methodology. (OO Article 3) There should no longer be any hint of the implementation of perl objects as hashes. (OO Article 4) perl6 objects must be able to be used *universally* as fully-fledged built-in types: scalars, arrays, hashes, etc. (OO Article 5) perl6 OO -- at least, some definable subset of it -- needs to be runtime-friendly. (OO Articles 6) Also considered drop-deads: interfaces, assertions (of various sorts), multiple inheritance, complex delegation. Can we at least agree on these? Are there other basic tenets that should be included? Bravo! I suspect everything mentioned in article 6 except multiple inheritance could be delegated (no pun intended) to the zealots mentioned in article 2. If we can reach some consensus, the next step is to start presenting the ~10 (by my rough count) fundamental open issues that are screwing everything else up. I think it would help immensely if we knew some details of the implementation of is properties. From the plethora of things they are expected to do, it seems like every variable access or subroutine/method call or maybe even block invocation will need to be able to be intercepted by property classes (or whatever they are). This would certainly make perl5 'tie's easy to abolish. But there may be sticky issues about who gets called first when something has multiple properties. A think a lot of the syntax discussions could be narrowed down better if we had some inkling of the implementations. (Since properties are completely new in perl6, which apocalypse do they belong to anyway?) ~ John Williams
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
Draft Proposal: Attributes: public vs. private
(Disclaimer: My purpose in proposing this is not to recommend it, but to document whether the idea should be endorsed, or shot down, and any proposed canonical syntax. Note that the later implications of these choices are quite substantial. Please discuss!) [Draft Proposal: Attributes: public vs. private] It is proposed that attributes are considered by default to be private to a class, but may optionally be made public on an attribute-by-attribute basis. Definition: public: A public attribute is an attribute which may be accessed without restriction both inside and outside the class. Definition: private: A private attribute is an attribute whose scope is restricted such that it may be accessed only within the class in which it has been declared. It is not available to subclasses, nor to code outside the class. [But see an alternative possible definition, below] Example: class Zap { attr $foo; # private, by default attr $foo2 is private; # explicitly private attr $bar is public;# explicitly public method meth1 { $.foo } # allowed method meth2 { $.bar } # allowed } class Zot is Zap { method meth1 { $.foo } # NOT ALLOWED, private to Zap method meth2 { $.bar } # allowed, is public } $my_zot.foo;# NOT ALLOWED, private to Zap $my_zot.bar;# allowed [Discussion] Attributes are typically considered to be private variables for use by the class (or more precisely, by each separate instance of the class.) They cannot be accessed outside the class; to do so would violate the oft-referenced principles of encapsulation intrinsic to most OO methodologies. Note that an alternate definition of private is often used, as follows: A private attribute is an attribute whose scope is restricted such that it may be accessed only within the class in which it has been declared, OR WITHIN ANY CLASS THAT INHERITS FROM THAT CLASS. Many programmers in fact expect private attributes to work this way. Some languages recognize all three definitions, calling the above protected access. The notion of public attributes is controversial within the OO world. In general, public attributes may be better implemented as public accessor methods to an attribute that remains private. (It typically depends on how the language in question uses attributes, and whether the language treats attributes and methods in a roughly symmetric fashion.) Under the principle of TMTOWTDI, perl allows public attributes within a class. However, you must explicitly declare an attribute to be public. [PROS] - Allows substantial flexibility in the use of class attributes. - Similar usage exists in other OO languages, so people are familiar with the notions. - perl5 migrants -- used to the notions of objects-as-hashes, and all attributes being public -- might find the ability to declare public attributes comforting. [CONS] - Making publicly accessible attributes at all is considered Bad Form in most OO methodologies (which advocate the use of explicit accessor methods.) We may wish to discourage or even prohibit this behavior. - Using the alternative definition of private (e.g., protected) given above may be what many programmers expect, and may be more in line with perl's philosophy. It seems especially wonky to allow the cootie-infested public but not allow the more liberal interpretation of private. [Related Issues, Known Implications] - Proposal: Declaring Class Attributes - Proposal: Symmetry between Attributes and Accessors - Proposal: Attributes may contain automatically dereferenced Closures - Proposal: Use of Attributes within Interfaces - Whether accessor methods are automatically generated for attributes. MikeL
Draft Proposal: Declaring Classwide Attributes
(Disclaimer: My purpose in proposing this is not to recommend it, but to document whether the idea should be endorsed, or shot down, and any proposed canonical syntax. Note that the later implications of these choices are quite substantial. Please discuss!) [Draft Proposal: Declaring Classwide Attributes] Within a class, classwide attributes are declared using the standard my and our. Example: class Zap { my %zap_cache; # a private classwide attribute our $zap_count = 0; # a public classwide attribute attr $foo; attr $bar; } [Discussion] Many OO-based languages have the concept of classwide attributes; that is, attributes that only exist once, for the class (and all subclasses?), as opposed to existing one for each instance of a class. You can use these attributes as counters, or caches, or any other common ground for use by all instances of the class. Within a class definition, Perl simply uses the my/our keywords for this purpose. If any value is to be assigned to a classwide attributes, that assignment is done once, upon initialization of the class. [PROS] - Obvious utility. No new syntax introduced. [CONS] - ? [Related Issues, Known Implications] - This hinges on our definitions of private and public. my vs. our may in fact mean private vs. protected, or perhaps protected vs. public. - What the heck does initialization of the class really mean? That needs to be clearer. MikeL
Draft Proposal: Symmetry between Attributes and Accessors
(Disclaimer: My purpose in proposing this is not to recommend it, but to document whether the idea should be endorsed, or shot down, and any proposed canonical syntax. Note that the later implications of these choices are quite substantial. Please discuss!) [Draft Proposal: Symmetry between Attributes and Accessors] It is proposed that class attributes may be treated as functionally equivalent to an identically named accessor method. In this manner, it shall become irrelevant to callers whether a public attribute of an object is implemented as an attribute, or an lvalue method. Subclasses may implement either form, at will: class Bar { attr $foo is public, Integer; # a value } class Zap is Bar { method foo is Integer is lvalue { ... a calculation ... }; } ... my $v1 = $my_bar.foo = 5; my $v2 = $my_zap.foo = 5; # no difference [Discussion] Perl6 has identical syntax for accessing methods and attributes. If this remains the case, than an attribute can be thought of as being symmetric (from the caller's point of view) with an lvalue-based accessor: method foo is Integer is lvalue { ... } As such, there may be no need for the users of a class to differentiate between the two. The usefulness of this approach lies in the ability to extend aspects of a class that were not originally intended to be dynamic, i.e., to apply a calculation to an otherwise static attribute, and vice versa. Note that in languages that differentiate between $obj.foo and $obj.foo(), changing a public attribute to a method clearly violates the public interface of the class, and can involve search-and-replaces in large libraries of code. An alternative approach to this proposal is typically implemented using explicit accessor methods: class Bar { attr $_foo is Integer; method foo is Integer is lvalue { $._foo }; } class Zap is Bar { method foo is Integer is lvalue { ... a calculation ... } } This approach is predicated on class Bar being constructed with the appropriate accessor methods in the first place. The question is, should the proposed symmetry be introduced to allow better subclassing of classes that do _not_ follow this recommended practice. [PROS] - Allows substantial flexibility in the use of public attributes. - Similar usage exists in other OO languages, so people are familiar with the notion. - perl5 migrants -- used to the notions of objects-as-hashes, and all attributes being public -- might find this feature comforting. [CONS] - Making publicly accessible attributes at all is considered Bad Form in most OO methodologies, which advocate the use of explicit accessor methods. We may wish to discourage or even prohibit the behavior. - An attribute and a method are _not_ typically implemented in the same manner. Treating the two as interchangeable might imply runtime overhead. [Related Issues, Known Implications] - Proposal: Attributes: public vs. private - Proposal: Attributes may contain automatically dereferenced Closures - Proposal: Use of Attributes within Interfaces - Whether accessor methods are automatically generated for attributes. MikeL
Re: We need an OO issue list tutorial!
On Fri, Oct 04, 2002 at 03:42:49PM -0600, John Williams wrote: Derived from the RFCs and subsequent discussions, here is a proposed OO Bill of Rights: fundamental truths that I *think* are already agreed upon, and from which all other OO laws must be derived: (OO Article 1) It should be possible, in general, to do anything you did in perl5 in perl6. (OO Article 2) perl6 should not be geared towards any one OO methodology. (OO Article 3) There should no longer be any hint of the implementation of perl objects as hashes. (OO Article 4) perl6 objects must be able to be used *universally* as fully-fledged built-in types: scalars, arrays, hashes, etc. (OO Article 5) perl6 OO -- at least, some definable subset of it -- needs to be runtime-friendly. (OO Articles 6) Also considered drop-deads: interfaces, assertions (of various sorts), multiple inheritance, complex delegation. Can we at least agree on these? Are there other basic tenets that should be included? Bravo! AOLMe, too!/AOL -- 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.
Slots [was Re: Draft Proposal: Attributes: public vs. private]
This all looks good to me. I seem to have gone off on a tangent about slots, so I've mercifally changed the subject. On Fri, Oct 04, 2002 at 04:39:40PM -0700, Michael Lazzaro wrote: [CONS] - Making publicly accessible attributes at all is considered Bad Form in most OO methodologies (which advocate the use of explicit accessor methods.) We may wish to discourage or even prohibit this behavior. I believe that since we're going with the notion of slots (to use the term from Self) this problem goes away. Though I think I'm getting ahead of things. In the spirit of the thing, I'll define what I mean by slot. A style of OO syntax in which an attribute access and a method call are syntactically indistinguishable. Another way to look at it... Every attribute comes with a default accessor/mutator method which is the only way to access that attribute. Private attributes have private accessors, public are public. Here's an example. class Foo { attr this; # private by default attr that is public; attr thing; method foo is private { # the two are indistinguishable .bar('something'); # method call .this('wiffle');# set the 'this' attribute } method bar ($arg) { ... } } my $obj = Foo.new; $obj.that('wibble');# perfectly ok. The caller does not know # they're directly accessing an attribute (I've explicitly avoided the issue of lvalue method calls. That's a whole 'nother subject. If they're in Perl 6, they'll definately be applied to the above) Slots, by making method calls and attribute accesses indistinguishable to the user, effectively wrap every attribute in an accessor method. So, in a sense, you're just using accessor methods but you just don't have to go through all the trouble of writing it all out. Slots merely exploit the fact that while a public attribute is considered bad, a private attribute accessed via a public accessor method is fine. So slots simply make all public attributes the moral equivalent of a private attribute with a public accessor. Furthermore, slots promote extendability like normal accessors in that the default behavior can be overriden by simply defining a method with the same name as the attribute. I believe Damian has sketched out something like this using attribute properties but with some flexiiblity in how the default accessors behave like is readonly or is readwrite. Details aside, if you make attribute and method access indistinguishable, the problem of public attributes goes away. - Using the alternative definition of private (e.g., protected) given above may be what many programmers expect, and may be more in line with perl's philosophy. It seems especially wonky to allow the cootie-infested public but not allow the more liberal interpretation of private. This sounds like two wrongs make a right to me. -- 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 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: Slots
Thanks, if it's looking like lvalues are really out I'll edit that draft to take out the lvalue stuff and do it the other way. (And if Damian's happy with slots, that probably means we can get a lot of the other attribute recipies out of the way pretty quick. Huzzah!) I had mixed feelings about defining and using a term like slots in a draft that could mutate into a faq/tutorial, and went back and forth on it (haven't done Self in years, and never in a non-academic setting.) Think, think... Well, no, screw it: the best philosophy is to present and (re)define the terms ourselves, as many as we need, but perhaps with a footnote on language of origin. We don't want to invent new terminology, we want to reuse it. Duh. :-P If no objections, we'll use the term slots to mean the aforementioned attribute/method symmetry. I'll edit the text to give a proposed perl6 glossary definition. MikeL
Re: Draft Proposal: Attributes: public vs. private
At 4:39 PM -0700 10/4/02, Michael Lazzaro wrote: Under the principle of TMTOWTDI, perl allows public attributes within a class. However, you must explicitly declare an attribute to be public. There won't be any direct access to attributes outside class methods of the class that defines the attributes, unless Larry changes his mind in a big way. (And, honestly, probably not even then) Instead it'll all be accessed via lvalue methods. If an attribute is exposed there's just an lvalue method created, if it's not exposed there isn't. Inside the class, we'll just cheat and smack straight into the slots of the attribute array, and if you've inherited from a perl 6 class we'll be doing Evil Things with that array and all, but that's an internal matter. :) Though, of course, there's nothing to stop you from using Introspection (A power so great, it can only be used for good or evil!) to go peeking around, but that's another matter entirely. Don't forget that we'll potentially be inheriting from *non* perl classes, at least non-perl-6 classes (and more if I manage to pull it off), so there's a limit to how much knowledge we want to require of the semantics that get exposed. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk