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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!feeder.erje.net!eu.feeder.erje.net!bloom-beacon.mit.edu!bloom-beacon.mit.edu!newsswitch.lcs.mit.edu!nntp.TheWorld.com!.POSTED!not-for-mail From: Robert A Duff Newsgroups: comp.lang.ada Subject: Re: Generic instantiation before actual subprogram body Date: Thu, 04 Dec 2014 10:49:40 -0500 Organization: The World Public Access UNIX, Brookline, MA Message-ID: References: NNTP-Posting-Host: shell01.theworld.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: pcls7.std.com 1417708150 9205 192.74.137.71 (4 Dec 2014 15:49:10 GMT) X-Complaints-To: abuse@TheWorld.com NNTP-Posting-Date: Thu, 4 Dec 2014 15:49:10 +0000 (UTC) User-Agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.3 (irix) Cancel-Lock: sha1:LkDctOahbRQAIyeoFE+FxGh6Xmg= Xref: news.eternal-september.org comp.lang.ada:23863 Date: 2014-12-04T10:49:40-05:00 List-Id: Natasha Kerensikova writes: > Hello, > > I have fallen into the pattern of refactoring common using generics > instead of cut-and-paste. One of my earliest example of this is > https://github.com/faelys/natools/blob/trunk/src/natools-s_expressions-interpreter_loop.adb > > I think it's a good thing, even for only a few tens of lines of code, > mostly for readers who discover the code: explicit common patterns reduce > (I think) the cognitive overhead. > Please enlighten me if I'm wrong on this. I didn't look at your code, but you seem to be advocating the DRY principle, which is usually a good idea. > On a related but almost out-of-topic point, I have always instantiated > generic on a nesting level as shallow as possible. This is due to some > superstitious fear about trampolines and accessibility levels and a few > other nesting-related concept I don't understand. In recent versions of GNAT, trampolines are very rare. Search the GNAT docs for "trampoline" to see when they're used. And you can use the No_Implicit_Dynamic_Code restriction to make sure you don't use them. I don't see anything in your code that would involve trampolines -- nested instantiations don't involve trampolines. If you avoid anonymous access types, you won't get dynamic accessibility checks. You might get compile-time errors when doing 'Access, but that's just an annoyance -- it won't cause bugs. So yes, I think you're being "superstitious". ;-) > In the particular case of my alternative-to-cut-and-paste generics, it's > often a generic procedure, whose instances are each called only once, in > a public subprogram whose body consists of almost only the generic > instance call, sometimes with a little bit of argument shuffling or type > adjustments to fit the generic model when the API has a slightly > different logic. > > For example I have somewhere code similar to: > > package body Whatever is > > procedure Append (...); > procedure Render_Page_Element (...); > > procedure Render_Page is new Natools.S_Expressions.Interpreter_Loop > (Output_Accumulator, Page_Type, Render_Page_Element, Append); > > procedure Public_Render > (Page : in Page_Type; > Output : in out Output_Accumulator; > Template : in out Natools.S_Expressions.Lockable.Descriptor'Class) is > begin > Render_Page (Template, Output, Page); > end Public_Render; > > end Whatever > > Wouldn't it be better in such a case to instantiate the generic inside > Public_Render? That would solve any elaboration issue, and that would > limit the scope of the generic instance to where it is actually use, > which I find is generally a good guideline to follow. > I guess the compiler can easily tell there is no special nesting > mechanism needed, since all actual parameters have a large scope. I'm not sure what special mechanisms you're worried about, but yes, you can move Render_Page inside Public_Render, and yes that has the advantage of limiting its scope. I don't see any trampoline or accessibility issues in the above code. > Is there any particular rational reason to prefer top-level > instantiation to nested instantiation, or vice versa? If you're using the static elab model, and you only have one call to the instance, then you can (should?) nest the instance. No big deal either way. - Bob