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-Thread: 103376,8f802583e5c84fa X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!newscon06.news.prodigy.com!prodigy.net!newsfeed-00.mathworks.com!nntp.TheWorld.com!not-for-mail From: Robert A Duff Newsgroups: comp.lang.ada Subject: Re: String filtering Date: 02 Oct 2005 21:21:27 -0400 Organization: The World Public Access UNIX, Brookline, MA Message-ID: References: <1j92wa9843ylq.16j89wuqatbaj$.dlg@40tude.net> <1b54lwg8s1gk8.1t3jp1cmc2x32$.dlg@40tude.net> <1128236249.692858.50370@g14g2000cwa.googlegroups.com> NNTP-Posting-Host: shell01.theworld.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: pcls4.std.com 1128302488 3427 192.74.137.71 (3 Oct 2005 01:21:28 GMT) X-Complaints-To: abuse@TheWorld.com NNTP-Posting-Date: Mon, 3 Oct 2005 01:21:28 +0000 (UTC) User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 Xref: g2news1.google.com comp.lang.ada:5346 Date: 2005-10-02T21:21:27-04:00 List-Id: "Steve Whalen" writes: > > I'm an ARG member, and I agree with Randy here ... > > I have a feeling that more than 50% would allow 'out' parameters on functions, > > but the minority who disagree feel much more strongly about it. > > By the way, Tucker disagrees with Randy and I on this point. > > I'm curious why you and Randy and others want "out" parameters to be > allowed in functions. Since I have great respect for you and Randy > (and Tucker), I'd like to hear more about why you all want this. Well, thanks for saying so. :-) > I seem to have been brainwashed into thinking that functions with side > effects of any kind were a "bad thing", especially in a language like > Ada. I think that side effects in functions are usually a bad idea. But not always. I think the programmer, not the language designer, should make such decisions. I like restrictive rules that prevent me (as a programmer) from doing bad things by accident. But I don't like restrictive rules that try to prevent me from doing things I deliberately choose to do. Ada allows side effects in functions. Functions can write upon global variables. And you can pass pointers to functions, and they can write upon the referenced data. And you can pass objects (perhaps of a private type) containing pointers, and do the same thing. A limited private object can contain a pointer to itself (the "Rosen trick"). These side effects are hidden, and therefore (often) worse than an 'in out' parameter. That is, it makes no sense to me to tell programmers, "You can have side effects, but you're not allowed to make it clear in the code." If side effects on parameters are evil, side effects on globals are worse. Some abstractions have side effects on the implementation level, which are not visible to clients. For example, consider something like Lisp "symbols", implemented in Ada: function Intern(Table: in out Symbol_Table; -- illegal! X: String) return Symbol; Symbol is represented as an index into some table. The Intern function looks up X in a hash table, and returns the value found, if it's there. If it's not there, it adds X to the table. Thus, Intern(Table, "hello") will always return the same value as Intern(Table, "hello") called later. The "side effect" of adding X to the table the first time "hello" is interned is not really a side effect from the client's point of view. If Table is global, it works fine. But passing it as a parameter as above is illegal. I don't want language designers forcing such choices. We can solve this in Ada by adding various levels of indirection, which is rather a pain. For example, the "Rosen trick". Another example of side effects that I think are OK is when you're getting items from a stream. E.g. in a recursive-descent parser, you call a Get_Token routine that returns the next token from the stream. It has the side effect of consuming one item from the stream. It seems reasonable to me for each parsing routine to be a function that returns a syntax tree, and consumes the input represented by that tree. But these side effects are uniform throughout the parser, and fairly easy to understand. Initializing variables on their declaration is a Good Thing: Tok: Token := Get_Token(Stream); is better than: Tok: Token; ... Get_Token(Stream, Tok); because it's easier to understand that Tok is properly initialized, and because it's more consise. Constants are a good thing: Tok: constant Token := Get_Token(Stream); because you don't have to read all the code to find out where Tok is modified. There are cases where Ada forces use of functions instead of procedures. For example, a return type String means something completely different than an 'out' parameter of type String (perhaps another bad language design decision). So if you want to get the next line from a stream of characters, and you don't know how long it might be, you want: function Get_Line(S: in out Stream) return String; -- illegal! ... Line: constant String := Get_Line(...); If you try to turn Get_Line into a procedure, because you hate side-effecting functions, you will end up unnecessarily using the heap, or arbitrarily limiting line lengths, both of which are bad. All of these Get_Token and Get_Line sorts of functions work just fine if the stream is a global variable. But global variables are (usually) a bad idea -- parameters are (usually) better. Take a look at Ada's predefined random number generator. Would you prefer it to be a procedure? It's a function, and it requires either the Rosen trick, or gratuitous heap usage. It has a side effect, and I think it would be preferable to make that side effect clear in the code, by declaring the generator 'in out'. > Is there a class of problems that would be significantly clearer when > expressed in Ada if "out" parameters were allowed? Both 'out' and 'in out' should be allowed. If I ran the circus, I would also require some sort of syntactic indication on the _call_ for '[in] out' parameters. For both procedures and functions. - Bob P.S. "Side effect" is a pejorative term. (Some drug cures your disease, but makes you nauseous.) If the effect is intended by the programmer, and clear in the code, perhaps we should call it an "effect", without the "side".