Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!uunet!math.fu-berlin.de!unido!alfrat!roy From: roy@alfrat.uucp (Roy Phillips) Newsgroups: comp.lang.eiffel Subject: Re: Functions without side effects (was Old confusion) Summary: Arguments for side effects and against dogma Message-ID: <327@alfrat.uucp> Date: 1 Jun 91 15:52:21 GMT References: <1991May30.141218.3446@mstr.hgc.edu> Reply-To: roy@alfrat.UUCP (Roy Phillips) Organization: A+F System-Entwicklung, W-Germany Lines: 113 I've followed with interest the discussion on functions and side-effects, and one point that has'nt been mentioned (or that I've overlooked) is the aspect of readability of the application (assuming we wish to build an application sometime, and not just create examples for academic reasons). An importent criteria for me is that code be readable - that it represents the solution to the problem or the model of a system with very little `superfluous' text. This criteria is, for me, one of the most importent when designing a class or class cluster, and a major reason for using Eiffel over other languages. I refuse to pay homage to the mathematical god of `correctness' by sacrificing the understandability of the application - as in all things, rules are not the answer, but judgement should be used. Although agreeing in general to the principle of seperation of state-changing and state-querying features, I offer the two examples below in support of my argument that this should not of necessity be the rule. If one were to model a CPU, perhaps to create a simulator such as ITSIAC, it would be essential, from the point of view of understandability of the model, that the POP operation act just like the processor's POP - changing the state of the processor and returning the value from the stack top into the specified register. Having to perform two operations would be a unnecessary complication which could lead to misunderstanding and to errors. As a second case for functions with side effects, consider the interface of a mutual exclusion class, loosely based upon Djistra's P&V algorithm: -- -- MONITOR -- Resource Allocation Monitor providing mutual -- exclusion facilities -- -- %Z%%Y%:%M% %I% indexing date: "$Date: %D% %T% $"; revision: "$Revision: %R%.%L% $"; authors: roy; names: monitor; access: exclusive; deferred class MONITOR export free, test_and_set, request, release, got_resource feature free: BOOLEAN is -- is the resource we are managing available? deferred end; -- free test_and_set: BOOLEAN is -- is the resource we are managing available to us? deferred ensure Result = True implies got_resource; Result = False implies not free and not got_resource end; -- test_and_set request: BOOLEAN is -- return True when we have control of the resource require -- not free implies "wait until resource free" deferred ensure got_resource end; -- request release is -- make resource available again require free = False and then got_resource deferred ensure not got_resource end; -- release got_resource: BOOLEAN -- return True if we have successfully obtained -- exclusive accesss to resource deferred ensure Result = True implies not free end; -- got_resource end -- class MONITOR Seperate `request' and `release' operations are an obvious requirement (implemented as a function and a procedure respectively) but it is essential to provide a `test_and_set' routine, that returns a boolean `success/fail' status and grabs the resource if it is free - hysteresis between calling `free' and `request' could cause the application to perform an undesired wait inside of `request'. Care should be taken to provide comments, or better still, assertions that clearly outline any state changes that a routine may perform, be it a function or a procedure. Observing pre- and post-conditions is a lot more helpful than to rely on the rule: "it's a function so it won't change the object's state" Roy -- Roy Phillips A+F SystemEntwicklung D-4030 Ratingen West(ern) Germany roy@alfrat.UUCP