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: a07f3367d7,2078ce7aac45af5b X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Received: by 10.224.105.205 with SMTP id u13mr9463311qao.6.1352882347771; Wed, 14 Nov 2012 00:39:07 -0800 (PST) Received: by 10.52.66.235 with SMTP id i11mr107074vdt.7.1352882347749; Wed, 14 Nov 2012 00:39:07 -0800 (PST) Path: gf5ni56274882qab.0!nntp.google.com!u2no1358071qal.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Wed, 14 Nov 2012 00:39:07 -0800 (PST) In-Reply-To: <094f94ed-dbcc-4dba-bd9d-894a75f69037@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=20.133.0.8; posting-account=g4n69woAAACHKbpceNrvOhHWViIbdQ9G NNTP-Posting-Host: 20.133.0.8 References: <0114d327-9f9f-4ad2-9281-56331d11a90c@googlegroups.com> <2bb9e5fa-04a2-4073-bca1-1739ce0580f1@googlegroups.com> <57bca956-2348-4825-8f5f-04fb91863696@googlegroups.com> <094f94ed-dbcc-4dba-bd9d-894a75f69037@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: Ada202X : Adding functors From: Martin Injection-Date: Wed, 14 Nov 2012 08:39:07 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2012-11-14T00:39:07-08:00 List-Id: On Wednesday, November 14, 2012 12:51:03 AM UTC, Adam Beneschan wrote: > On Tuesday, November 13, 2012 3:11:57 AM UTC-8, Martin wrote: >=20 >=20 >=20 > >=20 >=20 > > But Adam - that's cool cat is already out the bag! >=20 >=20 >=20 > Well, that's a compelling reason to add a major new language feature. >=20 >=20 >=20 > Not. >=20 >=20 >=20 > > E.g. >=20 > > =20 >=20 > > with Ada.Text_IO; use Ada.Text_IO; >=20 > > with Project; use Project; >=20 > > with Matrix_3x3s; use Matrix_3x3s; >=20 > > with Vector_3s; use Vector_3s; >=20 > > procedure Test is >=20 > > procedure Display (X : Real) is >=20 > > begin >=20 > > Put_Line (Real'Image (X)); >=20 > > end Display; >=20 > > V : Vector_3 :=3D Create (X =3D> 12.34, >=20 > > Y =3D> 123.4, >=20 > > Z =3D> 1234.0); >=20 > > M : Matrix_3x3 :=3D (Create (X =3D> V, >=20 > > Y =3D> V * 2.0, >=20 > > Z =3D> V * 4.0)); >=20 > > begin >=20 > > V (1) :=3D 1.0; >=20 > > Display (V (1)); >=20 > > Display (V (2)); >=20 > > Display (V (3)); >=20 > > M (1, 1) :=3D 20.0; >=20 > > Display (M (1, 1)); >=20 > > end Test; >=20 > >=20 >=20 > > V and M used as-if they were functions >=20 >=20 >=20 > Umm, no, since you can't have a function call (by itself) on the left sid= e of an assignment. They're being used as arrays, not as functions. And I= think that's probably one of the reasons Constant_Indexing and Variable_In= dexing were added; there wasn't any good way to declare an object that wasn= 't actually an array but that you wanted to be able to use like an array, w= here you could define an indexing operation that would produce a *variable*= that could be used on the left side of an assignment (or in other situatio= ns where a variable was required). Also, I think it was related to some ne= w features allowing iteration over a container. I'm really not clear on th= e details of why this feature was added--I'm mostly just guessing--but the = AI involved does mention a desire to avoid syntactic awkwardness and a lot = of extra text. And I don't see anything in your example (the one in your o= riginal post) where there's any awkwardness that needs to be avoided. The = workaround I posted involves just adding one more identifier, and in my opi= nion adding this would make things clearer to the reader, while the syntax = you're proposing is, I think, likely to make things more confusing. >=20 >=20 >=20 > There may be other, more complex cases, though, where this would be a use= ful feature. I haven't yet followed the link Georg posted, but I'm going t= o; maybe there are some examples there that would make it clearer why a fea= ture would be worthwhile in Ada. So far I haven't seen anything like that = in the examples here. >=20 >=20 >=20 > -- Adam It may have been the intent to add only 'array-like' accessors to container= s but they've opened up something more... Here's a functor-like program for= converting Centigrade to Fahrenheit: package C_To_F is pragma Pure (C_To_F); type Algorithm is tagged private with Constant_Indexing =3D> Constant_Reference; function Create (C : Long_Float) return Algorithm; type Constant_Reference_Type (Value : not null access constant Long_Floa= t) is private with Implicit_Dereference =3D> Value; function Constant_Reference (This : Algorithm; Dummy : Integer) return Constant_Reference_Type; X : constant Integer; private type Algorithm is tagged record F : Long_Float; end record; X : constant Integer :=3D 0; function Create (C : Long_Float) return Algorithm is (F =3D> (C * 9.0 / 5.0) + 32.0); type Constant_Reference_Type (Value : not null access constant Long_Floa= t) is null record; function Constant_Reference (This : Algorithm; Dummy : Integer) return Constant_Reference_Type is (Value =3D> This.F'Unrestricted_Access); end C_To_F; with Ada.Text_IO; use Ada.Text_IO; with C_To_F; use C_To_F; procedure Test is F1 : constant Algorithm :=3D C_To_F.Create (10.0); F2 : constant Algorithm :=3D C_To_F.Create (20.0); begin Put_Line ("F1 :=3D " & Long_Float'Image (F1(X))); Put_Line ("F2 :=3D " & Long_Float'Image (F2(X))); end Test; D:\Ada\demo\obj\test F1 :=3D 5.00000000000000E+01 F2 :=3D 6.80000000000000E+01 [2012-11-14 08:24:36] process terminated successfully (elapsed time: 00.20s= ) Or this which is a functor that double a value at creation time and then ap= plies a power to that value at some later time. package Double_Then_Power is pragma Pure (Double_Then_Power); type Algorithm is tagged private with Constant_Indexing =3D> Constant_Reference; function Create (To_Double : Long_Float) return Algorithm; type Constant_Reference_Type (Value : not null access constant Long_Floa= t) is private with Implicit_Dereference =3D> Value; function Constant_Reference (This : in out Algorithm; To_Power : Integer) return Constant_Reference_Type; private type Algorithm is tagged record Result : Long_Float; end record; function Create (To_Double : Long_Float) return Algorithm is (Result =3D> To_Double * 2.0); type Constant_Reference_Type (Value : not null access constant Long_Floa= t) is null record; end Double_Then_Power; package body Double_Then_Power is function Constant_Reference (This : in out Algorithm; To_Power : Integer) return Constant_Reference_Type is begin This.Result :=3D This.Result ** To_Power; return (Value =3D> This.Result'Unrestricted_Access); end Constant_Reference; end Double_Then_Power; with Ada.Text_IO; use Ada.Text_IO; with Double_Then_Power; use Double_Then_Power; procedure Test is F1 : Algorithm :=3D Double_Then_Power.Create (1.0); F2 : Algorithm :=3D Double_Then_Power.Create (2.0); F3 : Algorithm :=3D F1; -- Assigning one functor to another... begin Put_Line ("F1 :=3D " & Long_Float'Image (F1(2))); Put_Line ("F2 :=3D " & Long_Float'Image (F2(3))); Put_Line ("F3 :=3D " & Long_Float'Image (F3(1))); end Test; D:\Ada\demo2\obj\test F1 :=3D 4.00000000000000E+00 F2 :=3D 6.40000000000000E+01 F3 :=3D 2.00000000000000E+00 [2012-11-14 08:34:25] process terminated successfully (elapsed time: 00.20s= ) So, it actually looks like I can actually (nearly) do it all in Ada already= ! :-) Would be nice to have a (set of?) root interface(s) that all algorithms cou= ld derive from, then I could have containers of algorithms. -- Martin