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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 2002:a02:8981:: with SMTP id p1-v6mr30240521jaj.7.1539986776755; Fri, 19 Oct 2018 15:06:16 -0700 (PDT) X-Received: by 2002:a9d:24e8:: with SMTP id z95mr660527ota.1.1539986776667; Fri, 19 Oct 2018 15:06:16 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!news.uzoreto.com!weretis.net!feeder6.news.weretis.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!z5-v6no110558ite.0!news-out.google.com!n199-v6ni116itn.0!nntp.google.com!x98-v6no110309ita.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Fri, 19 Oct 2018 15:06:16 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=96.247.204.201; posting-account=QF6XPQoAAABce2NyPxxDAaKdAkN6RgAf NNTP-Posting-Host: 96.247.204.201 References: <99f41210-6fe2-4b4d-90ad-21a0ab108f53@googlegroups.com> <39dec2d6-7da5-4421-bb50-e4effd5a1439@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: A function that cannot be called? From: Jere Injection-Date: Fri, 19 Oct 2018 22:06:16 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Xref: reader02.eternal-september.org comp.lang.ada:54664 Date: 2018-10-19T15:06:16-07:00 List-Id: On Friday, October 19, 2018 at 3:57:41 PM UTC-4, G.B. wrote: > On 19.10.18 19:06, AdaMagica wrote: > > I do not really understand what all this is about, but: > >=20 > > package What is > > type Void (<>) is private; > > function Create (Params: Some_Type) return Void is abstract; > > private > > type Void is null record; -- no values > > end What; > >=20 > > Void has no values (hm, a null record is a value, but it's irrelevant, = since no objects exist (there is none in the private part; a body is illega= l); no objects can be created because Create is abstract, so in effect Crea= te does not exist - so it cannot be called. >=20 >=20 > 41. Consume (What.Create'Access); > | > >>> prefix of "Access" attribute cannot be abstract >=20 > If the above package is placed in some private part, then, I think, > the language will guarantee that there is no way of introducing > objects anywhere. >=20 > From the docs of Haskell's Data.Void: >=20 > "A Haskell 98 logically uninhabited data type, > used to indicate that a given term should not exist." >=20 >=20 > One use of all this could be: any attempt at calling > the access-value passed to Consume will trigger some kind of > exceptional situation. > This implement works when Void is range 1..0 such that objects > can be declared, but is not available with either abstract > functions, as seen, or with a Void(<>) that cannot be constrained. Are you ok with runtime checks? If so, you can create a separate package for the void type: package Voids is type Void is limited private; private type Void is new Ada.Finalization.Limited_Controlled with null record; overriding procedure Initialize(Self : in out Void); end Voids; package body Voids is procedure Initialize(Self : in out Void) is begin raise Program_Error; end Initialize; end Voids; Here, if try to create a variable of type Void, it will raise Program_Error (or you can add a custom exception. Same for if you call a function that tries to return a Voids.Void variable. However, you can still create functions that return this type and take their 'Access or 'Address, you just cannot ever call them without also getting an exception. Example: procedure Hello is generic type T(<>) is limited private; package Client is function Impossible(V : T) return Voids.Void; end Client; package body Client is function Impossible(V : T) return Voids.Void is begin -- do something?? return Result : Voids.Void; end Impossible; end Client; =20 procedure Save(p : access function (V : Integer) return Voids.Void) is = null; =20 package Test is new Client(Integer); begin =20 begin declare a : Voids.Void; begin Put_Line("Variable Creation test failed"); end; exception when Program_Error =3D> Put_Line("Variable Creation test passed"); when others =3D> Put_Line("Variable Creation test still failed"); end; =20 begin Save(Test.Impossible'Access); Put_Line("Access usage test passed"); exception when others =3D> Put_Line("Access usage test failed"); end; =20 =20 end Hello; Output from my compiler: $gnatmake -o hello *.adb gcc -c hello.adb gnatbind -x hello.ali gnatlink hello.ali -o hello $hello Variable Creation test passed Access usage test passed If this doesn't give you what you want, would you consider generating some example usages you envision for the type? My understanding from what you have said so far is that you want: 1. Cannot create objects of the type 2. Can create functions that return the type 3. Cannot call those functions Side note: You can also simplify my Void type with a non controlled one if you use a private full declaration like: type Void is limited record Dummy : not null access Void; end record; Since Ada will default the access variable to null, it will raise a constraint_error. My initial way allows for a custom exception if you want it.