Xref: utzoo comp.lang.eiffel:1615 comp.object:3650 comp.software-eng:5848 Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!tut.cis.ohio-state.edu!seal.cis.ohio-state.edu!ogden From: ogden@seal.cis.ohio-state.edu (William F Ogden) Newsgroups: comp.lang.eiffel,comp.object,comp.software-eng Subject: Re: Functions without side effects (was Old confusion) Message-ID: <130242@tut.cis.ohio-state.edu> Date: 4 Jun 91 18:29:02 GMT References: <1991May30.141218.3446@mstr.hgc.edu> <327@alfrat.uucp> <1991Jun3.145924.28406@mstr.hgc.edu> Sender: news@tut.cis.ohio-state.edu Followup-To: comp.lang.eiffel Organization: The Ohio State University, Department of Computer and Information Science Lines: 69 In article <1991Jun3.145924.28406@mstr.hgc.edu> jcm@mstr.hgc.edu (James McKim) writes: ... >Let me try to summarize the discussion so far. The question before >the groups is "Should there exist a dichotomy between functions and procedures >within a class? In particular, should functions return information >about the state of an object _without_ changing that state (at least >as far as a user of the object can tell) while procedures are used >to change the state of the object _without_ returning a value. > >So far the two most extreme views are held by Craig Chambers and myself. > >Craig feels that procedures that return values are often extremely >useful and so should be designed into the class as a matter of course. >He cites Pop and Top in a stack class as a prime example. Top returns >the obvious item from the stack with no side effects. Pop removes the >top item _and_ returns it. His argument being, I believe, that the >vast majority of the time the user will want to use the item she just >popped. (Is that a fair summary Craig?) > >I feel that the separation of concerns that the proposed dichotomization >between functions and procedures is too important to give up lightly. >The designer of a class should expect to design procedures that don't >return values and functions without side effects, and only vary from >this heuristic when there is a _compelling_ reason to do so. Thus my >Pop would just remove the top element, not return it. There are a number of considerations that bear upon this issue, but comprehensibility and efficiency are probably the most important. Functions enjoy a prominent position in twentieth century mathematics, and thus in the educational background of most software professionals. It makes sense to exploit this shared knowledge when designing software. Now the principle feature of functions is that they can be composed into arbitrarily large expressions. If you don't anticipate clients forming expressions, then functions offer no particular advantage over procedures as class operations. The answer to the question of whether functions should have side-effects which are visible at the client level is clear when you observe that side-effects will make the value of experessions dependent upon the order of evaluation of subexpressions, and hence quite unapparent. On the other hand, side-effects which only affect the internal representationsof objects (such as changing the shape of a tree being used to realize a set)should be permitted for efficiency reasons. The pop/top discussion raises an important efficiency issue in class design. While we now give lip service to object-oriented design, we often fail to recognize some of the consequences of what we're advocating. If the object based software thesis is correct, then our software will be organized around increasingly large and sophisticated objects, yet when we design things like stacks, we persist in thinking of the objects being stored in stacks as being small objects like integers. Instead, we should recognize that the really serious uses of stacks will involve storing large objects ( sets, polygons, other stacks, etc. ), and that to achieve real reusability, our stack operations should be chosen with an eye to making them efficient for storing large objects. Probably the most significant feature of large objects, as opposed to small objects like integers, is that they are usually quite expensive (if not impossible) to replicate. Consequently operations like Top make poor choices as primary operations, since their implementation inevitably involves making a copy of a data structure entry. The proper choice of primary operation for the stack then is the procedure (not function -- see above) Pop which does return the top value, since this does not entail replicating an entry. Top can be provided as a secondary operation, but clients should be warned that it is potentially an expensive operation. -- /Bill