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,103b407e8b68350b X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-01-25 08:05:22 PST Path: archiver1.google.com!news2.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!64.152.100.70.MISMATCH!sjc70.webusenet.com!news.webusenet.com!wn11feed!worldnet.att.net!204.127.198.204!attbi_feed4!attbi_feed3!attbi.com!sccrnsc01.POSTED!not-for-mail Message-ID: <3E32B5C0.5090004@attbi.com> From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20021120 Netscape/7.01 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Anybody in US using ADA ? One silly idea.. References: <1041908422.928308@master.nyc.kbcfp.com> <1041997309.165001@master.nyc.kbcfp.com> <1042086217.253468@master.nyc.kbcfp.com> <1042477504.547640@master.nyc.kbcfp.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit NNTP-Posting-Host: 24.62.164.137 X-Complaints-To: abuse@attbi.com X-Trace: sccrnsc01 1043510710 24.62.164.137 (Sat, 25 Jan 2003 16:05:10 GMT) NNTP-Posting-Date: Sat, 25 Jan 2003 16:05:10 GMT Organization: AT&T Broadband Date: Sat, 25 Jan 2003 16:05:10 GMT Xref: archiver1.google.com comp.lang.ada:33424 Date: 2003-01-25T16:05:10+00:00 List-Id: As I read through this thread, I noticed widespread ignorance on both sides of the way Ada generics actually work. This is not surprising, as the essential magic is "hidden" in plain sight in what seems like a textual substitution shorthand. But as anyone who actually implements Ada generics can tell you, it is anything but textual substitution. Ada generics have four places where binding of parameters occurs. At the point of the generic declaration, any bindings that occur are compile time bindings with respect to names, and can be to static or dynamic values: generic function Foo(X: in Integer := Read) return Integer is... The second set of bindings occurs in the body. Although it is possible for the binding in the body of a generic to be to a different instance of a name than in the specification, good programming practice strongly deprecates that possibility. However, it is common for new names to be visible in the body, and to be used. The third set of bindings occurs at the point of instantiation. This is where the generic parameters are bound. A classic example of using this binding occurs with sorts: generic type Element is private; type Element_Array is array (Integer range <>) of Element; function ">" (L,R: Element) return Boolean; procedure Sort(EA: in out Element_Array); Now an instantiation of Sort passing "<" instead of ">" will sort in descending instead of ascending order. Of course for convenience, the specification above is normally written as: generic type Element is private; type Element_Array is array (Integer range <>) of Element; function ">" (L,R: Element) return Boolean is <>; procedure Sort(EA: in out Element_Array); The 'is <>' allows the function ">" to be defaulted and left out of the instantiation. This is where the magic--or snakepit--occurs, depending on whether you are a user or implementor. Instead of 'is <>' I could have written 'is Standard.">"' and insured that the default would be to the predefined greater than operation for Integer. But with the 'is <>', I get the ">" function for Integer visible at the point of instantiation. This can be in a nested call, and the binding can actually be to some ">" in a (run-time) enclosing declarative part. In other words, implementing the 'is <>' notation correctly requires support for upward closures. But there is worse (from an implementors point of view) to come. The fourth point of binding is at the call. This is where the names of the formal parameters are bound to the actuals. But notice that the environment of the call need not be that of instantiation, in fact, quite often it is not. This means that if you try to implement Ada using displays, generics sometimes require passing multiple displays as implicit parameters. (Ouch! Ask Randy Brukardt for details, he has actually implemented it.) Should you use this Lisp style richness of closures when programming in Ada? I have found very few cases where the power was worth the documentation effort to make sure any maintainers understood what was going on. The one exception has been in displaying appropriate error messages during debugging of parsers. ;-)