rick@tetrauk.UUCP (Rick Jones) (06/10/91)
In article <131691@tut.cis.ohio-state.edu> ogden@seal.cis.ohio-state.edu (William F Ogden) writes: |>> ... Now the problem, rephrased in these terms, |>>is that our small object bias leads us to design classes with operations |>>like Top which create multiple references to the same object. One of |>>the challenges of object oriented programming is still to design classes |>>so that excess copying can be avoided or (if you insist on reference |>>semantics) so that multiple references can be avoided. | |In article <1178@tetrauk.UUCP> I wrote: | |>I strongly disagree that reference semantics are inherently a bad thing. There |>are a large number of real problems which require multiple references in order |>to produce a reasonable soultion. | ... |>Although good OO design and programming systems can emphasise abstract concepts |>and isolate a programmer from implementation details, it should never attempt |>to hide the distinction between value and reference. This is something that |>both the designer and programmer must understand, and use both to best |>advantage. | |Bill Ogden replied: | |The issue is not that reference semantics are inherently a bad thing any |more than that dynamite is an inherently bad thing. Neither, however, is |intended for every day or casual use. The problem is that building classes ^^^^^^^^^ ^^^^^^ - see below |which force clients to use operations like Top that just return a reference |to a stack entry is rather like building hardware stores which supply |customers with sticks of dynamite whenever they ask for something with |which to remove a tree from their lawns. If clients are careful or lucky |they achieve their objectives. If not, you're left with a bloody mess. | |There's no problem with using multireference objects (or dynamite) and |passing out references with a Top operation, if you like. The problem |is with making this the normal rather than the exceptional way of |doing business. We clearly have a fundamental disagreement. I would be interested to hear if you can quote any case histories to support your view - i.e. where programmers have implemented a design in a language where reference is the default (and presumably therefore well supported), and screwed up as a result. I confess that I can't do likewise for my own point of view, since our use of Eiffel is currently confined to a small team, where we are building a toolkit. I have not found Eiffel's default reference semantics create any unpleasant problems personally, but perhaps that is because I am particularly aware of what is going on. I am genuinely interested in this issue, since at some point our toolkit is going to be in "everyday use" by less experienced programmers (although I don't think any proper software project should ever treat programming as "casual"). Am I heading for trouble? Pointers in C do cause problems, and we have the experience of that, but it is very easy to make a lot of mistakes in C with pointers because the language doesn't help you handle them properly. References in an OOPL are a whole different issue. What about Smalltalk? I only have a very limited knowledge of it, but does it not generally employ reference semantics? Of all languages, its object model is probably least obvious, so if reference semantics are going to lead to problems, I would expect it to be apparent in Smalltalk. Can any experienced Smalltalk users comment on this (I am widening this thread to comp.object for this reason). -- Rick Jones, Tetra Ltd. Maidenhead, Berks, UK rick@tetrauk.uucp Chairman, NICE (Non-profit International Consortium for Eiffel) Any fool can provide a solution - the problem is to understand the problem
johnson@cs.uiuc.EDU (Ralph Johnson) (06/11/91)
As a longtime Smalltalk programmer, I don't see how its use of reference semantics causes problems. Reference semantics and copy semantics are not just different styles of programming, they are different *semantics*. They mean different things. Sometimes a programmer wants to have stateless values, and sometimes a programmer wants to have objects with state. A language should support both. I've tried functional programming in C, and it is hard, mostly because of the lack of garbage collection. Programming with immutable objects and without side effects is not hard in Smalltalk. I usually partition a system into the "stateless" parts and the "stateful" parts. I usually consider it an improvement when I can convert mutable objects to immutable objects. That doesn't happen often, because it is usually pretty obvious which is which. I can understand how someone who dosen't understand reference semantics (or copy semantics, for that matter) will have problems when they first start to use it. People have trouble with nearly anything when they first start to use it, including procedures, side effects, recursion, inheritance: in short, programming! Improper use of references can certainly cause problems, but improper use of anything can cause problems. I shudder when I see someone passing a "store" in a functional language to simulate reference semantics. Reference semantics makes many programs simpler.
kentb@argosy.UUCP (Kent Beck) (06/11/91)
After a year and a half working on a project containing 50K non-comment source lines of Smalltalk I just got my first defect that was a result of improper aliasing. I marked it at the time because I could not remember seeing many such bugs in code I have worked on previously. Kent Beck
ogden@seal.cis.ohio-state.edu (William F Ogden) (06/12/91)
In article <1181@tetrauk.UUCP> rick@tetrauk.UUCP (Rick Jones) writes: ... >Pointers in C do cause problems, and we have the experience of that, (Yes, and the safety problems with nitroglycerin made dynamite a welcome discovery too. :-) > but it is >very easy to make a lot of mistakes in C with pointers because the language >doesn't help you handle them properly. References in an OOPL are a whole >different issue. Somehow I'm getting this deja vu sensation that we're back in the late 60's discussing Go To's. One side is saying that Go To's (object references) have an excessively complex semantics which can easily lead to programming errors. On the other side, a few people concede that computed Go To's (C pointers) might be a problem. However, most argue that since the jump instruction (pointer) is essential for low level programming (basic data structuring), it must be retained, perhaps slightly syntactically sugared, as a central feature of high level programming structuring (reusable object design). -- /Bill
ogden@seal.cis.ohio-state.edu (William F Ogden) (06/12/91)
In article <1991Jun10.215822.28034@m.cs.uiuc.edu> johnson@cs.uiuc.EDU (Ralph Johnson) writes: ... >Improper use of references can certainly cause problems, but >improper use of anything can cause problems. Improper use of GoTo's can certainly cause problems also, but we don't use them much any more. We observed that there was a problem and that there were efficient alternatives, and we changed our ways. -- /Bill
sakkinen@jyu.fi (Markku Sakkinen) (06/14/91)
I am cross-posting this article and the following one to comp.object because the question is interesting not only to the Eiffel community. In article <133644@tut.cis.ohio-state.edu> ogden@seal.cis.ohio-state.edu (William F Ogden) writes: >In article <1991Jun12.072557.7282@jyu.fi> sakkinen@jyu.fi (Markku Sakkinen) writes: >> ... >It's true that analogies only suggest, but don't prove. In this case, >the analogy suggests strongly that we examine very carefully whether >the visible use of references is really that central to object oriented >design. A good example or two showing where references are fundamentally >necessary could perhaps expose the deficiencies of the proposed [dangerous?] >analogy. class person export ... inherit ... feature mother: person; heart: human_heart; ... end It is essential that several persons can have the same mother. On the opposite, a heart cannot be shared. I consider it a deficiency of languages such as Lisp, Smalltalk, and Eiffel that this important semantic difference cannot be expressed; and the main reason is that references are used for "everything". (Arrrgh: I already wrote and submitted something like this yesterday, but some testing of the news system here caused all articles to get lost.) ---------------------------------------------------------------------- "All similarities with real persons and events are purely accidental." official disclaimer of news agency New China Markku Sakkinen (sakkinen@jytko.jyu.fi) SAKKINEN@FINJYU.bitnet (alternative network address) Department of Computer Science and Information Systems University of Jyvaskyla (a's with umlauts) PL 35 SF-40351 Jyvaskyla (umlauts again) Finland ----------------------------------------------------------------------
sakkinen@jyu.fi (Markku Sakkinen) (06/14/91)
In article <1991Jun13.074318.337@tkou02.enet.dec.com> diamond@jit533.enet@tkou02.enet.dec.com (Norman Diamond) writes: >In article <1991Jun12.072557.7282@jyu.fi> sakkinen@jyu.fi (Markku Sakkinen) writes: >> ... >>I think that the need to share some objects is much more fundamental >>for object modelling than is the need to jump for imperative programming. >>The (visible) use of references should be restricted to a minimum, >>but accepted without remorse whenever it is necessary. > >I agree with that conclusion, but think that the reasoning and application >are backwards. Sharing and aliasing are sometimes necessary and should be >kept to a minimum, yes. I think the sharing and aliasing should be visible, >so that readers will know what to expect. The invisible aliasing generated >by reference semantics is worse than a label that is a target of multiple >gotos. An object gets changed when the user didn't expect it, and has to >do a lot of tracing to find out where.... Incidentally, I think similarly. I would have said: "I share your opinions", but of course my opinions do not change automatically if you change yours :-) What I meant by 'visible' was 'affecting semantics': it does not harm programmers if references are used only as an implementation device, which can be efficient for large objects. >Part of the problem with C pointers is that they are overused and abused >as a result of C's treatment of arrays. (A garbage collection in C can be >declared with [].) A fairer comparison would be Pascal-style pointers (or >even PL/I-style pointers) vs. the invisible sharing generated by reference >semantics. We agree even here. Pointer arithmetic has no place in a language that wants to be considered high-level. Also the fact that pointers in C and C++ can be made to point at any object of their referent type (as opposed to the restrictions of Pascal and Ada) makes them harder to manage, although it offers some advantages, too. To make my position clear: I regard it as a _good_ feature of C and C++ that 'widget' and 'pointer to widget', i.e. '*widget', are clearly distinct types. (Arrrgh: I already wrote and submitted something like this yesterday, but some testing of the news system here caused all articles to get lost.) ---------------------------------------------------------------------- "All similarities with real persons and events are purely accidental." official disclaimer of news agency New China Markku Sakkinen (sakkinen@jytko.jyu.fi) SAKKINEN@FINJYU.bitnet (alternative network address) Department of Computer Science and Information Systems University of Jyvaskyla (a's with umlauts) PL 35 SF-40351 Jyvaskyla (umlauts again) Finland ----------------------------------------------------------------------
ogden@seal.cis.ohio-state.edu (William F Ogden) (06/15/91)
In article <1991Jun14.073249.1469@jyu.fi> sakkinen@jyu.fi (Markku Sakkinen) writes: ... >> A good example or two showing where references are fundamentally >>necessary could perhaps expose the deficiencies of the proposed [dangerous?] >>analogy. >class person > export ... inherit ... > feature > mother: person; > heart: human_heart; > ... end >It is essential that several persons can have the same mother. >On the opposite, a heart cannot be shared. I consider it a deficiency >of languages such as Lisp, Smalltalk, and Eiffel that this important >semantic difference cannot be expressed; and the main reason is that >references are used for "everything". An amusing note on this example is that Markku's earlier warning about how dubious analogies might lead our thinking astray is applicable to so many of the prototypical examples used to develop the designs for various object oriented programming systems. In this case, the intended analogy is to a familiar world filled with people having mothers and hearts. What one would want to do (e.g. what operations) in the imperative world of computing which is related to the this everyday world is, of course, central to deciding how the computational objects should be structured but is left unspecified (as is traditional in such examples). Depending upon what we're really supposed to do in this example, some sort of structure which supports finding mothers efficiently is probably needed. However,if there are going to be operations on individuals that modify their mothers, then it's not clear that we're looking at the cleanest possible design here. Without more detail, the example just doesn't make a compelling case for using reference semantics routinely. -- /Bill
phil@abccam.abcl.co.uk (Phillip Yelland) (06/18/91)
I hope you'll forgive me if I barge in this thread, but I thought I'd throw in my h'a'p'eth worth (two cents' worth---substitute currency as appropriate) and a plug. I've recently defended (successfully, deo gratias) a thesis which examines the implications of the use of references in OOL's on their formal semantics. I wouldn't insist my findings were conclusive, but the models I came up with did rather undermine the naive conception of objects in such languages as neat, encapsulated parcels of state with a finely circumscribed interface. An abbreviated summary of part of the thesis appears in the recently-published Springer LNCS 489 ("Foundations of Object-Oriented Languages"---de Bakker, de Roever, Rozenberg). I'd be happy to provide copies of either of the above, though I'm afraid I'll need postage as my present employer is unlikely to subsidize such activity. I'm particularly intrigued by Kent Beck's insistence (in an earlier message) that aliasing bugs occur in his Smalltalk code with relative infrequency. Could he enlighten us as to how onery/hard-to-locate he actually finds such bugs? We've recently signed off a 50K-line Smalltalk project; while they weren't all that common, we did experience aliasing bugs that were both very well hidden and the cause of the most bizzare consequences (windows crawling spontaneously around the screen, etc.). (I'd not like to insist, of course, that our Smalltalk skills are comparable to Kent's.) --Phillip Yelland P.S. I'm trying to locate one William Cook, late of HP Labs Palo Alto, who---it is commonly held---has disappeared into the maw of Apple research. Could anyone provide any pointers (:-)?
kers@hplb.hpl.hp.com (Chris Dollin) (06/19/91)
If I may add my views to others ... My ``normal'' language (ie the one I use by preference) is Pop11 (which for the purposes of discussion you can take to be a Lisp-like language); compound objects (sorry, things; Pop isn't OO) are references, ie, aliasing abounds. My experience is that this presents no particular problem. The occasional nasty is no worse than the occasional nasties you get from other kinds of logical errors. Sharing and object identity open up just as many idioms as they close. -- Regards, Chris ``GC's should take less than 0.1 second'' Dollin.
rick@tetrauk.UUCP (Rick Jones) (06/19/91)
>It is essential that several persons can have the same mother. >On the opposite, a heart cannot be shared. I consider it a deficiency >of languages such as Lisp, Smalltalk, and Eiffel that this important ^^^^^^ >semantic difference cannot be expressed; and the main reason is that >references are used for "everything". Sorry, Markku, you're not up to date with Eiffel. From Eiffel 2.2 onwards (that's nearly 2 years ago), a class variable can be declared as "expanded". This means it gets value semantics - i.e. every assignment is a copy. Eiffel 3 allows a _class_ to be declared as expanded, so every instance is distinct. In fact, in ISE's version of Eiffel 3, expanded objects will be _implemented_ using references, but the compiler will enforce _value_ semantics - i.e. it will guarantee no aliasing. You can do it both ways, it just happens that the default semantics are reference. I think this is quite reasonable, since I have found in practice that extensive use of reference in Eiffel does not in fact cause problems, despite the concerns raised by several people in this thread. The comments from Smalltalk users also confirm that references are not a real problem. It is not difficult to build systems where references are the norm, and to identify exceptions where alisasing must not be allowed. The use of "expanded" means these cases can be dealt with elegantly. I believe this is a better approach than taking value semantics as the norm, and then identifying cases where aliasing is either required, or can be allowed for efficiency, and using an appropriate syntax to make these the exceptions. -- Rick Jones, Tetra Ltd. Maidenhead, Berks, UK rick@tetrauk.uucp Chairman, NICE (Non-profit International Consortium for Eiffel) Any fool can provide a solution - the problem is to understand the problem
kentb@argosy.UUCP (Kent Beck) (06/20/91)
While not claiming that my Smalltalk skills are up to Phillip Yelland's stature (:^) there are some aspects of my style which minimize aliasing errors. First I strictly partition my objects into real objects and values (objects whose state is set at instance creation time and never changed). I always use Rectangles and Points as values- if I ever have to modify one in place because I can't add a lower level protocol I use a strict copy in/copy out protocol. Similarly with real objects- if I give one visibility I make a copy, and copy it when I get it back (the practice of safe objects). If I am ever tempted to share objects in contradiction to these rules for performance sake during early development I smack myself. "Ah, but don't you do lots of object allocation and isn't it a performance problem?" the straw man says. Yes and no, respectively. The style I have described above deliberately spends time in the garbage collector so that the resulting program is simpler and more robust. In my experience, however, when a well factored program needs performance and object allocation is a problem it is always possible to recast it so that the performance critical portion is in one object. I can't prove that this will always be the case, but I do bet my livelihood on it daily, so I'm pretty sure of it. Kent Beck
phil@abccam.abcl.co.uk (Phillip Yelland) (06/21/91)
I'd like to thank those who followed up my recent article with such cogent and reasoned responses. I'm especially grateful to Kent Beck for receiving my rather back-handed compliment in such good humour. In mitigation, I'd like to emphasize that I was attempting to make a constructive point (which I believe has also been expressed by Kai Henningsen and others); I know that Kent is a very skilled Smalltalk programmer, and it's evident from his reply that he adopts an approach to design which will bar many of the problems which aliasing might produce. By analogy with structured programming and the use of GOTO: could it be that there is a collection such strategies meet to deal with the majority of sharing requirements? Would it be worth expressing these devices explicitly in a object-oriented programming language, so as to promote disciplined engineering amongst the rest of us? --Phil P.S. To those people who expressed an interest in publications: I'll try to mail you a (latex) copy of a recent paper electronically from another site, (though I'm afraid I can't guarantee 100% success, and may need to pursue matters at greater length). I've also had a word with the great panjandrums, and my thesis should be available in due course as a technical report from the University of Cambridge Computer Laboratory (Library), New Museums Site, Pembroke St., Cambridge, Cambs. U.K. If you feel you can't possibly wait that long for the real McCoy, prod me again, and I'll be off to the Post Office to get some cost estimates. Thanks again.
knight@mrco.carleton.ca (Alan Knight) (06/23/91)
In article <1991Jun21.215959.13966@cis.ohio-state.edu> ogden@seal.cis.ohio-state.edu (William F Ogden) writes: >In article <1991Jun19.001829.28317@syacus.acus.oz.au> ian@syacus.acus.oz.au (Ian Joyner) writes: > ... >>As object oriented programming reflects the real world, it seems that >>references will be inevitable. > >At the risk of getting back into those dangerous analogies, note that >referencs semantics really entail multiple larger objects routinely sharing >possesion of smaller objects. For very good reasons, this rarely happens >in the real world. Imagine, for example, several people in a room each >possesing a remote tuner for the room's only television set. The chaos >that would normally result makes it clear why we avoid such situations in >the real world, and by analogy why we would be prudent to do so in our >programming world. The phrase "larger objects ... sharing possession of smaller objects" implies a physical part-of relationship, sharing of which doesn't often happen in the real world. That doesn't mean that objects aren't shared. In fact, in the "real" world that I live in, objects are usually shared, and copying is fairly rare. At my house, we have one television set which is shared between all the residents. It's true that there's only one remote control, but if my wife decides to change the state of the television set, it certainly affects the copy that I'm referencing. Copying semantics (in which as soon as I walk into the room I get my own television to look at) would be rather disconcerting. Copy-on-write would be rather entertaining, if anyone who changed the channel got a new television set. I'd soon be able to open my own electronics store. I'm not sure what would happen to the reference to the TV from the bookcase it sits on, though. We might need to clone quite a bit of stuff. To actually make a point: The real world has state and reference semantics all over the place. There may be good arguments for avoiding them, but the claim that they are not used in the real world is not one of them. -- -- Alan Knight knight@mrco.carleton.ca +1 613 788 5783 Support Dept. of Mechanical and Aeronautical Engineering the Carleton University, Ottawa, Ontario, Canada, K1S 5B6 LPF
barmar@think.com (Barry Margolin) (06/24/91)
In article <1991Jun22.175434.21450@cunews.carleton.ca> knight@mrco.carleton.ca (Alan Knight) writes: >In article <1991Jun21.215959.13966@cis.ohio-state.edu> ogden@seal.cis.ohio-state.edu (William F Ogden) writes: >>At the risk of getting back into those dangerous analogies, note that >>referencs semantics really entail multiple larger objects routinely sharing >>possesion of smaller objects. For very good reasons, this rarely happens >>in the real world. Imagine, for example, several people in a room each >>possesing a remote tuner for the room's only television set. > In fact, in the "real" world that I live in, objects are usually >shared, and copying is fairly rare. At my house, we have one >television set which is shared between all the residents. It's true >that there's only one remote control And reference semantics still make sense for the remote control as well, precisely *because* there's only one. If you give the remote control to your wife, then you must drop your reference to it and she must add her reference to it. However, it's still the same remote control, and any state (its color, the strength of its battery, its serial number, and, most importantly, its *identity* (in languages that support identity, rather than equivalence, testing)) must be maintained when moving it. -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
jcm@mstr.hgc.edu (James McKim) (06/26/91)
In article <1193@tetrauk.UUCP> rick@tetrauk.UUCP (Rick Jones) writes: > From Eiffel 2.2 onwards >(that's nearly 2 years ago), a class variable can be declared as "expanded". >This means it gets value semantics - i.e. every assignment is a copy. Eiffel 3 >allows a _class_ to be declared as expanded, so every instance is distinct. In >fact, in ISE's version of Eiffel 3, expanded objects will be _implemented_ >using references, but the compiler will enforce _value_ semantics - i.e. it >will guarantee no aliasing. > Rick, In version 2.3 there is a restriction on the base class of an expanded type. Namely its Create routine can have no parameters. Also, declaring and using an instance of an expanded type is legal without explicitly calling Create, but does not automatically result in the initialization of the expanded object's attributes or the execution of the Create routine. Consequently I have restricted my use of expanded types mainly to stateless objects such as those containing only constants and simple queries. Does version 3 address these issues? > >-- >Rick Jones, Tetra Ltd. Maidenhead, Berks, UK rick@tetrauk.uucp >Chairman, NICE (Non-profit International Consortium for Eiffel) > >Any fool can provide a solution - the problem is to understand the problem -- Jim *------------------------------------------------------------------------------* Jim McKim (203)-548-2458 _Give_ people fish and they eat for a day. Internet: jcm@mstr.hgc.edu _Teach_ people to fish and they eat for a lifetime.
ogden@seal.cis.ohio-state.edu (William F Ogden) (06/27/91)
In article <1991Jun22.175434.21450@cunews.carleton.ca> knight@mrco.carleton.ca (Alan Knight) writes: >>>As object oriented programming reflects the real world, it seems that >>>references will be inevitable. >>At the risk of getting back into those dangerous analogies, note that >>referencs semantics really entail multiple larger objects routinely sharing >>possesion of smaller objects. For very good reasons, this rarely happens >>in the real world. Imagine, for example, several people in a room each >>possesing a remote tuner for the room's only television set. The chaos ... > The phrase "larger objects ... sharing possession of smaller >objects" implies a physical part-of relationship, sharing of which >doesn't often happen in the real world. That doesn't mean that >objects aren't shared. The issue here certainly wasn't that objects aren't and shouldn't be shared -- both in the programming and in the real world. The concern was that multireferences to objects entails the simultaneous _shared possession_ of those objects by other entities in the system. > In fact, in the "real" world that I live in, objects are usually >shared, and copying is fairly rare. At my house, we have one >television set which is shared between all the residents. It's true >that there's only one remote control, but if my wife decides to change >the state of the television set, it certainly affects the copy that >I'm referencing. In your world then there is only one television object whose use is shared by several other entities. The entities are aware of each other and that in order to function properly, they must set up and obey certain conventions regarding the use of the television. [Supposing that a remote controller is an adequate analogue of a reference to a TV object,] you then follow the simplifying convention of only having ONE reference to your TV and of sharing (at different times) the use of that reference. If you had several TV's and remote tuners which could selectively control any TV, then the physical situation here might begin to approach the complexity inherent in reference semantics. > Copying semantics (in which as soon as I walk into the room I get my >own television to look at) would be rather disconcerting. >Copy-on-write would be rather entertaining, if anyone who changed the >channel got a new television set. ... As I said early in this discussion, copying of large objects is difficult and expensive, and it should be avoided if at all possible. > To actually make a point: The real world has state and reference >semantics all over the place. There may be good arguments for >avoiding them, but the claim that they are not used in the real world >is not one of them. Objects in the real world certainly have state. Actual examples of reference semantics, however, seem to be hard to come up with. Objects are visible and accessible to multiple entities in a physical environment, just as variables are in a programming environment, but that's clearly not analogous to having multiple references.
barmar@think.com (Barry Margolin) (06/27/91)
In article <1991Jun26.204549.27784@cis.ohio-state.edu> ogden@seal.cis.ohio-state.edu (William F Ogden) writes: >Objects in the real world certainly have state. Actual examples of reference >semantics, however, seem to be hard to come up with. Objects are visible >and accessible to multiple entities in a physical environment, just as >variables are in a programming environment, but that's clearly not analogous >to having multiple references. Why isn't it? To continue the TV analogy, consider a class TV-WATCHER (representing people who watch TV), with a slot TV-BEING-WATCHED, and a class TELEVISION-SET. If several TV-WATCHERs are in the same room, they would all be watching the same TV, so they would have references to the same TELEVISION-SET in their TV-BEING-WATCHED slots. Sharing this reference is necessary to deal with state changes in the TELEVISION-SET. For instance, if one TV-WATCHER changes the channel, all the TV-WATCHERs are now watching a different channel. If each TV-WATCHER had a copy of the TELEVISION-SET object, propagating these state changes would be harder (you'd have to maintain a list of all the equivalent TELEVISION-SETs). -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar