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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ed4a5cc4016f9101 X-Google-Attributes: gid103376,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!feeder1-2.proxad.net!proxad.net!feeder2-2.proxad.net!newsfeed.arcor.de!newsspool4.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Default value for a record component Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <1185052757.500324.16860@22g2000hsm.googlegroups.com> Date: Sun, 22 Jul 2007 10:08:16 +0200 Message-ID: NNTP-Posting-Date: 22 Jul 2007 10:08:02 CEST NNTP-Posting-Host: ed432f07.newsspool4.arcor-online.net X-Trace: DXC=S2KHU^4jjDRYQ5E:l On Sat, 21 Jul 2007 14:19:17 -0700, Maciej Sobczak wrote: > Consider: > > package P is > type T is record > V : Integer := 5; > end record; > end P; > > Above, T.V will have 5 as a default value whenever the instance of T > is created without any explicit initialization. > > I would like extend it and do this: > > package P is > type T is record > V : Integer := Get_Default_Value; > end record; > private > function Get_Default_Value return Integer; > end P; > > without losing any of the properties of the original solution and > without "leaking" any implementation detail to the public view. The > idea is, of course, to compute the default value at run-time, each > time the new object is created - but without touching the general > "look&feel" of the original code (so that for example Controlled is > excluded). > Is it possible? Yes: package P is function Get_Default_Value return Integer; type T is record V : Integer := Get_Default_Value; end record; end P; or even like this: package P is Default_Value : Integer; type T is record V : Integer := Default_Value; end record; end P; The only problem with this design is that whatever things you wished to pass to an instance of T, they will be enclosed in P (or it parents). This is not a "closure." You could achieve a sort of closure, if you made P generic and passed Get_Default_Value as a formal parameter. But that would require an instantiation of P each time you wanted to change the things. In Ada 2005 you can come a bit closer to closures: package P is type T (Default_Value : access function return Integer) is limited record V : Integer := Default_Value.all; end record; end P; This looks awful because of pointers. There is still no true procedural types in Ada, alas. Because of pointers, T has to be limited. Yet it is almost closure and P can be pure: function Get_Default_Value return Integer; ... X : T (Get_Default_Value'Access); Feels much better than: X : T := (V => Get_Default_Value); !? (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de