From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,31c63f07e48d5471 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-02-24 15:53:35 PST Path: archiver1.google.com!postnews1.google.com!not-for-mail From: mheaney@on2.com (Matthew Heaney) Newsgroups: comp.lang.ada Subject: Re: Ada to 'C' parameter passing problem Date: 24 Feb 2003 15:53:35 -0800 Organization: http://groups.google.com/ Message-ID: <1ec946d1.0302241553.24bc71f2@posting.google.com> References: <1ec946d1.0302191836.743eab91@posting.google.com> NNTP-Posting-Host: 66.162.65.162 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Trace: posting.google.com 1046130815 13062 127.0.0.1 (24 Feb 2003 23:53:35 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: 24 Feb 2003 23:53:35 GMT Xref: archiver1.google.com comp.lang.ada:34539 Date: 2003-02-24T23:53:35+00:00 List-Id: rod.chapman@praxis-cs.co.uk (Rod Chapman) wrote in message news:... > > Wow! This reflects somewhat of a gulf between our respective > views of language design! (Don't get me wrong, neither position > is necessarily right or wrong, just different...) > At the SPARK end of the spectrum functions calls are expressions > which return a value and never have a side-effect. Procedure > calls are statements which have side-effects - A rather > significant _semantic_ difference! Our disagreement is probably on how this is should be stated in the language. My model is that you only have subprograms, and different kinds of subprograms simply have a different syntax for returning values back to the caller. For example, if I say: O : T; declare Value : constant Value_Type := Get_Value (O); begin then that is exactly equivalent to this: declare Value : Value_Type; begin Get_Value (O, Value); Both of these sequences of statements have exactly the same effect, which is to return an object of type Value_Type, without modifying object O. The keyword used indicate to the compiler that Get_Value is a subprogram is not relevant, and I don't really care what its spelling is. I could change the example around. I can set the value like this: Value : Value_Type := ...; declare Status : Status_Type; begin Set_Value (O, Value, Status); Here, we wish change the state of object O, and Set_Value returns some information back to the caller to indicate whether the state change was successful. We can also rewrite the example like this: declare Status : constant Status_Type := Set_Value (O, Value); begin This has exactly the same effect as in the previous example. The *only* difference in this pair of examples is the syntax of subprogram invokation. Ada95 lets me do both. Apparently SPARK does not. To me this inconsistency seems odd. > If you do prefer the ability to allow a function to modify its > parameters, then it should at least be good enough to confess > this to the outside-world as part of its specifiction. The current > discussion for Ada0Y in AI231 (extending anonymous access > parameters) is welcome here, especially from a static-analysis > point of view. Yes, of course a function should be able to state that it modifies its parameters, especially if it modifies them! Realize, however, that there is a difference between the "logical" view of an abstraction and the "physical" view. For example, the model for the random number is that it is a stream of values, and invoking function Random simply returns the next value in the stream. In this case, it makes more sense that the function accept the generator as an in-only (not inout) parameter. The real issue is telling the compiler that the subprogram modifies its arguments, in a manner independent of subprogram parameter mode (again, because there are distinct views of the type). Ideally, you'd like to state this at the time of declaration of the type (instead of letting the compiler infer this when it sees the body of the package, which is necessarily later). C++ solved this problem by introducing a "mutable" keyword to inform the compiler that this variable is subject to modification, irrespective of whether the member function is declared as const: class C { mutable int i; public: void f() const; }; and where void C::f() const { ++i; } Ada doesn't always do a great job of separating the logical properties of the type from its physical properties, and it tends to conflate the two, e.g. package P is type T is range 0 .. 255; function "+" (L, R : T) return T; --clamped add end P; How should one implement "+" without getting infinite recursion? It seems to me that it would be better to have an explicit way of indicating to the compiler that a subprogram parameter is modified. (The spelling of the keyword that indicates to the compiler that this is a subprogram is not relevant). Now the compiler must sort of guess, by looking at the declaration, e.g. type T is limited record Handle : Handle_Type (T'Access); --Rosen Trick ... end record; Does that make it obvious to the compiler? I don't really know. Now of course I realize that some programmers do make a distinction between subprograms that are spelled "function" vs. spelled "procedure". I do not make such a distinction. If you decide that subprograms spelled "function" should not modify their arguments, then you are free to write your programs that way, and I won't try to stop you. However, where I must object is when those programmers try to tell *me* that that's how I should write *my* programs. What the original Ada83 language designer did was to overstep his authority, and legislate what I should do. But the locution I choose to invoke a subprogram that modifies its arguments should be none of his business. The purpose of a programming language is to make it easy for a programmer to write programs. The language designer should not decide by fiat how that should be done. Both the language and its designer should stay out of the programmer's way, and assume that it is the programmer himself who is in the best position to decide whether a value-returning subprogram is appropriate for the problem at hand. So I don't agree with your characterization of this as a "language design" issue. If you want to try to convince me (via forums like CLA, etc) that a function shouldn't modify its arguments, then you're free to do that. (And I would be interested in your arugments, even if I don't happen to agree with them.) But what you should NOT do is to force me to do it your way by designing the language such that subprogram parameter modification is prohibited by the rules of the language. You the language designer would be overstepping the limits of your authority, with the concomitant effect that programmers will either circumvent the rules, or simply chose another language. A programming language is the programmer's servent, not his master.