comp.lang.ada
 help / color / mirror / Atom feed
* Ada202X : Adding functors
@ 2012-11-12 22:09 Martin
  2012-11-12 23:14 ` Jeffrey Carter
                   ` (3 more replies)
  0 siblings, 4 replies; 44+ messages in thread
From: Martin @ 2012-11-12 22:09 UTC (permalink / raw)


I'm increasingly using functors in my C++ life and they are very cool. I'd like to be able to use them in my Ada life too but the language doesn't support it - or can someone tell me I'm wrong?

I think it could be done by 'simply' allowing something like this:

package P is
   type T is tagged ...;
   function Create return T;
   procedure "()" (This : T; I : Integer);  -- The functor call
   function "()" (This : T) return Integer; -- Alternative functor that's a function
private
...
end P;

with P;
procedure Demo is
   My_T : P.T := P.Create
begin
   My_T (42);  -- call to procedure version
   if My_T () > 100 then ... end if;  -- call to function version
end Demo;

I guess one of the trickier bits of adding this would be the possible need to step away from the current Ada convention of not requiring empty parenthesis...but new language revisions always change the 'current' good style...

Any thoughts?

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 22:09 Ada202X : Adding functors Martin
@ 2012-11-12 23:14 ` Jeffrey Carter
  2012-11-12 23:19   ` Martin
  2012-11-12 23:44 ` Adam Beneschan
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 44+ messages in thread
From: Jeffrey Carter @ 2012-11-12 23:14 UTC (permalink / raw)


On 11/12/2012 03:09 PM, Martin wrote:
>
> I guess one of the trickier bits of adding this would be the possible need to
> step away from the current Ada convention of not requiring empty
> parenthesis...but new language revisions always change the 'current' good
> style...

Ada 80 required empty parentheses for subprogram calls with no explicit actual 
parameters. There were many objections to this, even though they disambiguated 
some calls that are ambiguous without them, and they were removed in Ada 83. I, 
for one, would not want to see them return.

I have to admit I do not see the advantage of this over existing subprograms.

-- 
Jeff Carter
"Strange women lying in ponds distributing swords
is no basis for a system of government."
Monty Python & the Holy Grail
66



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 23:14 ` Jeffrey Carter
@ 2012-11-12 23:19   ` Martin
  2012-11-13 10:45     ` Georg Bauhaus
  0 siblings, 1 reply; 44+ messages in thread
From: Martin @ 2012-11-12 23:19 UTC (permalink / raw)


I don't think it would need to extend to existing code or to explicit calls, only to functors - would that be more acceptable?

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 22:09 Ada202X : Adding functors Martin
  2012-11-12 23:14 ` Jeffrey Carter
@ 2012-11-12 23:44 ` Adam Beneschan
  2012-11-13  2:11   ` Jeffrey Carter
  2012-11-13 11:11   ` Martin
  2012-11-13  4:22 ` Shark8
  2012-11-15  0:20 ` sbelmont700
  3 siblings, 2 replies; 44+ messages in thread
From: Adam Beneschan @ 2012-11-12 23:44 UTC (permalink / raw)


On Monday, November 12, 2012 2:09:15 PM UTC-8, Martin wrote:
> I'm increasingly using functors in my C++ life and they are very cool. I'd like to be able to use them in my Ada life too but the language doesn't support it - or can someone tell me I'm wrong?
> 
> I think it could be done by 'simply' allowing something like this:
> 
> package P is 
>    type T is tagged ...;
> 
>    function Create return T;
>    procedure "()" (This : T; I : Integer);  -- The functor call
>    function "()" (This : T) return Integer; -- Alternative functor that's a function
> 
> private
> 
> ...
> 
> end P;
> 
> with P;
> procedure Demo is
>    My_T : P.T := P.Create
> begin
>    My_T (42);  -- call to procedure version
>    if My_T () > 100 then ... end if;  -- call to function version
> end Demo;
> 
> 
> 
> I guess one of the trickier bits of adding this would be the possible need to step away from the current Ada convention of not requiring empty parenthesis...but new language revisions always change the 'current' good style...
> 
> Any thoughts?

package P is 
   type T is tagged ...; 
   function Create return T; 
   procedure Call (This : T; I : Integer);  -- The functor call 
   function Call (This : T) return Integer; -- Alternative functor that's   
                                            -- function
private 
... 
end P; 

with P; 
procedure Demo is 
   My_T : P.T := P.Create ;
begin 
   My_T.Call (42);  -- call to procedure version 
   if My_T.Call > 100 then ... end if;  -- call to function version 
end Demo; 


This already works in Ada, and doesn't require any major language changes that would give the ARG headaches about empty parentheses, possible syntax conflicts with user-defined references and indexing, the interpretation of constructs involving function calls that return P.T followed by parentheses, etc., etc., etc.  I'll concede that doing it this way may be considered less "cool" than being able to avoid typing that extra identifier ("Call").  Being able to say "This is a variable, but OH LOOK I can use it like a function" certainly does seem cool, in a way.  I don't see any other advantage, though.

                         -- Adam



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 23:44 ` Adam Beneschan
@ 2012-11-13  2:11   ` Jeffrey Carter
  2012-11-13 11:11   ` Martin
  1 sibling, 0 replies; 44+ messages in thread
From: Jeffrey Carter @ 2012-11-13  2:11 UTC (permalink / raw)


On 11/12/2012 04:44 PM, Adam Beneschan wrote:
>
> Being able to say "This is a variable, but OH LOOK I can use it like a
> function" certainly does seem cool, in a way.

We have this in Ada; it's called an array.

-- 
Jeff Carter
"Strange women lying in ponds distributing swords
is no basis for a system of government."
Monty Python & the Holy Grail
66



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 22:09 Ada202X : Adding functors Martin
  2012-11-12 23:14 ` Jeffrey Carter
  2012-11-12 23:44 ` Adam Beneschan
@ 2012-11-13  4:22 ` Shark8
  2012-11-15  0:20 ` sbelmont700
  3 siblings, 0 replies; 44+ messages in thread
From: Shark8 @ 2012-11-13  4:22 UTC (permalink / raw)


On Monday, November 12, 2012 3:09:15 PM UTC-7, Martin wrote:
> I'm increasingly using functors in my C++ life and they are very cool. I'd like to be able to use them in my Ada life too but the language doesn't support it - or can someone tell me I'm wrong?
> 
> I think it could be done by 'simply' allowing something like this:
> 
> package P is
>    type T is tagged ...;
>    function Create return T;
>    procedure "()" (This : T; I : Integer);  -- The functor call
>    function "()" (This : T) return Integer; -- Alternative functor that's a function
> private
> ...
> end P;
> 
> with P;
> procedure Demo is
>    My_T : P.T := P.Create
> begin
>    My_T (42);  -- call to procedure version
>    if My_T () > 100 then ... end if;  -- call to function version
> end Demo;

Er, why?
Couldn't you use operator overloading, generic packages, etc to do it?

    Type NR is null record;
    Generic
	Type T;
	With Function  "+"( Left: in out T; Right: Integer ) Return NR;
	With Function  "+"( Item: T ) Return Integer;
    Package K is
    End K;
Then use K as a signature package for your actual usages. Also, you could eliminate NR and use a procedure instead, calling it 'Add' or something.



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 23:19   ` Martin
@ 2012-11-13 10:45     ` Georg Bauhaus
  2012-11-13 12:08       ` Yannick Duchêne (Hibou57)
  2012-11-13 12:35       ` Martin
  0 siblings, 2 replies; 44+ messages in thread
From: Georg Bauhaus @ 2012-11-13 10:45 UTC (permalink / raw)


On 13.11.12 00:19, Martin wrote:
> I don't think it would need to extend to existing code or to explicit calls, only to functors - would that be more acceptable?

But is adding syntactic implicitness of ?() enough?

Isn't there more about "functors"? And if so, wouldn't Ada
generics have to become "more recursive" so as to get all the
benefits of using "functors" in a generalized and checked fashion?

http://www.catonmat.net/blog/on-functors/

(Otherwise, overloading "()" just looks like catering to those who
write programs in a style that is between lazy (avoiding names) and
obfuscating.)




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 23:44 ` Adam Beneschan
  2012-11-13  2:11   ` Jeffrey Carter
@ 2012-11-13 11:11   ` Martin
  2012-11-14  0:51     ` Adam Beneschan
  1 sibling, 1 reply; 44+ messages in thread
From: Martin @ 2012-11-13 11:11 UTC (permalink / raw)


On Monday, November 12, 2012 11:44:39 PM UTC, Adam Beneschan wrote:
> On Monday, November 12, 2012 2:09:15 PM UTC-8, Martin wrote:
> 
> > I'm increasingly using functors in my C++ life and they are very cool. I'd like to be able to use them in my Ada life too but the language doesn't support it - or can someone tell me I'm wrong?
> 
> > 
> 
> > I think it could be done by 'simply' allowing something like this:
> 
> > 
> 
> > package P is 
> 
> >    type T is tagged ...;
> 
> > 
> 
> >    function Create return T;
> 
> >    procedure "()" (This : T; I : Integer);  -- The functor call
> 
> >    function "()" (This : T) return Integer; -- Alternative functor that's a function
> 
> > 
> 
> > private
> 
> > 
> 
> > ...
> 
> > 
> 
> > end P;
> 
> > 
> 
> > with P;
> 
> > procedure Demo is
> 
> >    My_T : P.T := P.Create
> 
> > begin
> 
> >    My_T (42);  -- call to procedure version
> 
> >    if My_T () > 100 then ... end if;  -- call to function version
> 
> > end Demo;
> 
> > 
> 
> > 
> 
> > 
> 
> > I guess one of the trickier bits of adding this would be the possible need to step away from the current Ada convention of not requiring empty parenthesis...but new language revisions always change the 'current' good style...
> 
> > 
> 
> > Any thoughts?
> 
> 
> 
> package P is 
> 
>    type T is tagged ...; 
> 
>    function Create return T; 
> 
>    procedure Call (This : T; I : Integer);  -- The functor call 
> 
>    function Call (This : T) return Integer; -- Alternative functor that's   
> 
>                                             -- function
> 
> private 
> 
> ... 
> 
> end P; 
> 
> 
> 
> with P; 
> 
> procedure Demo is 
> 
>    My_T : P.T := P.Create ;
> 
> begin 
> 
>    My_T.Call (42);  -- call to procedure version 
> 
>    if My_T.Call > 100 then ... end if;  -- call to function version 
> 
> end Demo; 
> 
> 
> 
> 
> 
> This already works in Ada, and doesn't require any major language changes that would give the ARG headaches about empty parentheses, possible syntax conflicts with user-defined references and indexing, the interpretation of constructs involving function calls that return P.T followed by parentheses, etc., etc., etc.  I'll concede that doing it this way may be considered less "cool" than being able to avoid typing that extra identifier ("Call").  Being able to say "This is a variable, but OH LOOK I can use it like a function" certainly does seem cool, in a way.  I don't see any other advantage, though.
> 
> 
> 
>                          -- Adam

But Adam - that's cool cat is already out the bag! E.g.

with Ada.Text_IO; use Ada.Text_IO;
with Project;     use Project;
with Matrix_3x3s; use Matrix_3x3s;
with Vector_3s;   use Vector_3s;
procedure Test is
   procedure Display (X : Real) is
   begin
      Put_Line (Real'Image (X));
   end Display;
   V : Vector_3 := Create (X => 12.34,
                           Y => 123.4,
                           Z => 1234.0);
   M : Matrix_3x3 := (Create (X => V,
                              Y => V * 2.0,
                              Z => V * 4.0));
begin
   V (1) := 1.0;
   Display (V (1));
   Display (V (2));
   Display (V (3));
   M (1, 1) := 20.0;
   Display (M (1, 1));
end Test;

V and M used as-if they were functions - in fact they use Constant_Indexing and Variable_Indexing:

...
package Vector_3s is
   pragma Pure (Vector_3s);
   subtype An_Axis is Integer range 1 .. 3;
   type Vector_3 is tagged private
     with Constant_Indexing => Vector_3s.Constant_Reference,
          Variable_Indexing => Vector_3s.Variable_Reference;
...
package Matrix_3x3s is
   pragma Pure (Matrix_3x3s);
   subtype An_Axis is Integer range 1 .. 3;
   type Matrix_3x3 is tagged private
     with Constant_Indexing => Matrix_3x3s.Constant_Reference,
          Variable_Indexing => Matrix_3x3s.Variable_Reference;
...

But it doesn't currently work without an index parameter!

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-13 10:45     ` Georg Bauhaus
@ 2012-11-13 12:08       ` Yannick Duchêne (Hibou57)
  2012-11-13 12:35       ` Martin
  1 sibling, 0 replies; 44+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2012-11-13 12:08 UTC (permalink / raw)


Le Tue, 13 Nov 2012 11:45:05 +0100, Georg Bauhaus  
<rm.dash-bauhaus@futureapps.de> a écrit:
> http://www.catonmat.net/blog/on-functors/
The paper says:
> It's interesting how the term "functor" meanscompletely different things  
> in various programming languages.

That's the point (and why I did not understand that thread).


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-13 10:45     ` Georg Bauhaus
  2012-11-13 12:08       ` Yannick Duchêne (Hibou57)
@ 2012-11-13 12:35       ` Martin
  1 sibling, 0 replies; 44+ messages in thread
From: Martin @ 2012-11-13 12:35 UTC (permalink / raw)


On Tuesday, November 13, 2012 10:45:05 AM UTC, Georg Bauhaus wrote:
> On 13.11.12 00:19, Martin wrote:
> 
> > I don't think it would need to extend to existing code or to explicit calls, only to functors - would that be more acceptable?
> 
> 
> 
> But is adding syntactic implicitness of ?() enough?
> 
> 
> 
> Isn't there more about "functors"? And if so, wouldn't Ada
> 
> generics have to become "more recursive" so as to get all the
> 
> benefits of using "functors" in a generalized and checked fashion?
> 
> 
> 
> http://www.catonmat.net/blog/on-functors/
> 
> 
> 
> (Otherwise, overloading "()" just looks like catering to those who
> 
> write programs in a style that is between lazy (avoiding names) and
> 
> obfuscating.)

I would have no problems with an attempt to make Ada Generics more 'recursive' as you put it...I'm finding a lot of milage in some of C++ templates.

One mod could be for generics to say that a generic type parameter could be specified in terms of an interface type but that actual parameter need not be derived from that same interface type - providing that it met the contract of the interface type(s), i.e. allow Duck-ish Typing for interface types.

It isn't Duck Typing, as the generic still has the contract...but I think it could open up Ada generics to some interesting (and still safe...I think! The compiler would still have to check the instantiation) directions...

I'm thinking out loud on this one... :-)

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-13 11:11   ` Martin
@ 2012-11-14  0:51     ` Adam Beneschan
  2012-11-14  8:39       ` Martin
  0 siblings, 1 reply; 44+ messages in thread
From: Adam Beneschan @ 2012-11-14  0:51 UTC (permalink / raw)


On Tuesday, November 13, 2012 3:11:57 AM UTC-8, Martin wrote:

> 
> But Adam - that's cool cat is already out the bag!

Well, that's a compelling reason to add a major new language feature.

Not.

> E.g.
>  
> with Ada.Text_IO; use Ada.Text_IO;
> with Project;     use Project;
> with Matrix_3x3s; use Matrix_3x3s;
> with Vector_3s;   use Vector_3s;
> procedure Test is
>    procedure Display (X : Real) is
>    begin
>       Put_Line (Real'Image (X));
>    end Display;
>    V : Vector_3 := Create (X => 12.34,
>                            Y => 123.4,
>                            Z => 1234.0);
>    M : Matrix_3x3 := (Create (X => V,
>                               Y => V * 2.0,
>                               Z => V * 4.0));
> begin
>    V (1) := 1.0;
>    Display (V (1));
>    Display (V (2));
>    Display (V (3));
>    M (1, 1) := 20.0;
>    Display (M (1, 1));
> end Test;
> 
> V and M used as-if they were functions

Umm, no, since you can't have a function call (by itself) on the left side 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_Indexing 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, where 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 situations where a variable was required).  Also, I think it was related to some new features allowing iteration over a container.  I'm really not clear on the 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 original post) where there's any awkwardness that needs to be avoided.  The workaround I posted involves just adding one more identifier, and in my opinion adding this would make things clearer to the reader, while the syntax you're proposing is, I think, likely to make things more confusing.

There may be other, more complex cases, though, where this would be a useful feature.  I haven't yet followed the link Georg posted, but I'm going to; maybe there are some examples there that would make it clearer why a feature would be worthwhile in Ada.  So far I haven't seen anything like that in the examples here.

                              -- Adam



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14  0:51     ` Adam Beneschan
@ 2012-11-14  8:39       ` Martin
  2012-11-14 16:54         ` Adam Beneschan
  0 siblings, 1 reply; 44+ messages in thread
From: Martin @ 2012-11-14  8:39 UTC (permalink / raw)


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:
> 
> 
> 
> > 
> 
> > But Adam - that's cool cat is already out the bag!
> 
> 
> 
> Well, that's a compelling reason to add a major new language feature.
> 
> 
> 
> Not.
> 
> 
> 
> > E.g.
> 
> >  
> 
> > with Ada.Text_IO; use Ada.Text_IO;
> 
> > with Project;     use Project;
> 
> > with Matrix_3x3s; use Matrix_3x3s;
> 
> > with Vector_3s;   use Vector_3s;
> 
> > procedure Test is
> 
> >    procedure Display (X : Real) is
> 
> >    begin
> 
> >       Put_Line (Real'Image (X));
> 
> >    end Display;
> 
> >    V : Vector_3 := Create (X => 12.34,
> 
> >                            Y => 123.4,
> 
> >                            Z => 1234.0);
> 
> >    M : Matrix_3x3 := (Create (X => V,
> 
> >                               Y => V * 2.0,
> 
> >                               Z => V * 4.0));
> 
> > begin
> 
> >    V (1) := 1.0;
> 
> >    Display (V (1));
> 
> >    Display (V (2));
> 
> >    Display (V (3));
> 
> >    M (1, 1) := 20.0;
> 
> >    Display (M (1, 1));
> 
> > end Test;
> 
> > 
> 
> > V and M used as-if they were functions
> 
> 
> 
> Umm, no, since you can't have a function call (by itself) on the left side 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_Indexing 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, where 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 situations where a variable was required).  Also, I think it was related to some new features allowing iteration over a container.  I'm really not clear on the 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 original post) where there's any awkwardness that needs to be avoided.  The workaround I posted involves just adding one more identifier, and in my opinion adding this would make things clearer to the reader, while the syntax you're proposing is, I think, likely to make things more confusing.
> 
> 
> 
> There may be other, more complex cases, though, where this would be a useful feature.  I haven't yet followed the link Georg posted, but I'm going to; maybe there are some examples there that would make it clearer why a feature would be worthwhile in Ada.  So far I haven't seen anything like that in the examples here.
> 
> 
> 
>                               -- Adam

It may have been the intent to add only 'array-like' accessors to containers 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 => Constant_Reference;
   function Create (C : Long_Float) return Algorithm;
   type Constant_Reference_Type (Value : not null access constant Long_Float) is
      private with Implicit_Dereference => 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 := 0;
   function Create (C : Long_Float) return Algorithm is
     (F => (C * 9.0 / 5.0) + 32.0);
   type Constant_Reference_Type (Value : not null access constant Long_Float) is
     null record;
   function Constant_Reference (This : Algorithm; Dummy : Integer)
                                return Constant_Reference_Type is
      (Value => 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 := C_To_F.Create (10.0);
   F2 : constant Algorithm := C_To_F.Create (20.0);
begin
   Put_Line ("F1 := " & Long_Float'Image (F1(X)));
   Put_Line ("F2 := " & Long_Float'Image (F2(X)));
end Test;

D:\Ada\demo\obj\test
F1 :=  5.00000000000000E+01
F2 :=  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 applies 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 => Constant_Reference;
   function Create (To_Double : Long_Float) return Algorithm;
   type Constant_Reference_Type (Value : not null access constant Long_Float) is
      private with Implicit_Dereference => 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 => To_Double * 2.0);
   type Constant_Reference_Type (Value : not null access constant Long_Float) 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 := This.Result ** To_Power;
      return (Value => 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 := Double_Then_Power.Create (1.0);
   F2 : Algorithm := Double_Then_Power.Create (2.0);
   F3 : Algorithm := F1;  -- Assigning one functor to another...
begin
   Put_Line ("F1 := " & Long_Float'Image (F1(2)));
   Put_Line ("F2 := " & Long_Float'Image (F2(3)));
   Put_Line ("F3 := " & Long_Float'Image (F3(1)));
end Test;

D:\Ada\demo2\obj\test
F1 :=  4.00000000000000E+00
F2 :=  6.40000000000000E+01
F3 :=  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 could derive from, then I could have containers of algorithms.

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14  8:39       ` Martin
@ 2012-11-14 16:54         ` Adam Beneschan
  2012-11-14 18:54           ` Martin
  2012-11-14 20:37           ` Dmitry A. Kazakov
  0 siblings, 2 replies; 44+ messages in thread
From: Adam Beneschan @ 2012-11-14 16:54 UTC (permalink / raw)


On Wednesday, November 14, 2012 12:39:07 AM UTC-8, Martin wrote:
> 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:

> It may have been the intent to add only 'array-like' accessors to containers but they've opened up something more...

A new way to write obfuscated code?  Why do you think this would convince me or anything else to support a language change?  You're declaring a tagged type, using aspects that are intended for implicit array referencing or user-defined access dereferencing, applying a parameter list to an object of the tagged type, and expecting readers to figure out what you mean.  And you *still* haven't given any argument for why this would be better than just adding a normal subprogram name (which I've called Perform in the snippet below) and writing something like:

   F1 : Algorithm := Double_Then_Power.Create (1.0);
   F2 : Algorithm := Double_Then_Power.Create (2.0);
   F3 : Algorithm := F1;  -- Assigning one functor to another...
begin
   Put_Line ("F1 := " & Long_Float'Image (F1.Perform(2)));
   Put_Line ("F2 := " & Long_Float'Image (F2.Perform(3)));
   Put_Line ("F3 := " & Long_Float'Image (F3.Perform(1)));

You can already do this in Ada 2005; no need to use the new accessor features, which are confusing because you're trying to use them in a way they're not intended to be used.

You haven't given a good argument for why we need to change the language so that programmers can write the above without the .Perform.  So far, your only arguments seem to be (1) you can do it in C++ and it's "very cool", and (2) programmers can already abuse features of the language to make it look the way you want, so we should enshrine it.  Sorry, but it would take a lot more than that to convince me that we would need a language change. 

                                -- Adam



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 16:54         ` Adam Beneschan
@ 2012-11-14 18:54           ` Martin
  2012-11-14 20:37           ` Dmitry A. Kazakov
  1 sibling, 0 replies; 44+ messages in thread
From: Martin @ 2012-11-14 18:54 UTC (permalink / raw)


On Wednesday, November 14, 2012 4:54:10 PM UTC, Adam Beneschan wrote:
> On Wednesday, November 14, 2012 12:39:07 AM UTC-8, Martin wrote:
> 
> > 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:
> 
> 
> 
> > It may have been the intent to add only 'array-like' accessors to containers but they've opened up something more...
> 
> 
> 
> A new way to write obfuscated code?  Why do you think this would convince me or anything else to support a language change?  You're declaring a tagged type, using aspects that are intended for implicit array referencing or user-defined access dereferencing, applying a parameter list to an object of the tagged type, and expecting readers to figure out what you mean.  And you *still* haven't given any argument for why this would be better than just adding a normal subprogram name (which I've called Perform in the snippet below) and writing something like:
> 
> 
> 
>    F1 : Algorithm := Double_Then_Power.Create (1.0);
> 
>    F2 : Algorithm := Double_Then_Power.Create (2.0);
> 
>    F3 : Algorithm := F1;  -- Assigning one functor to another...
> 
> begin
> 
>    Put_Line ("F1 := " & Long_Float'Image (F1.Perform(2)));
> 
>    Put_Line ("F2 := " & Long_Float'Image (F2.Perform(3)));
> 
>    Put_Line ("F3 := " & Long_Float'Image (F3.Perform(1)));
> 
> 
> 
> You can already do this in Ada 2005; no need to use the new accessor features, which are confusing because you're trying to use them in a way they're not intended to be used.
> 
> 
> 
> You haven't given a good argument for why we need to change the language so that programmers can write the above without the .Perform.  So far, your only arguments seem to be (1) you can do it in C++ and it's "very cool", and (2) programmers can already abuse features of the language to make it look the way you want, so we should enshrine it.  Sorry, but it would take a lot more than that to convince me that we would need a language change. 
> 
> 
> 
>                                 -- Adam

Sorry, too busy to write anything else...had to go and work!!

Yes, you're right, I have used in ways that perhaps the ARG didn't intend - I feel quite chuffed I managed to make it do that! It's not quite in the same league as discovering C++ templates supported meta-programming though! :-)

And, yes, this is a very straw-ish strawman.

The reasons could be the same as those given for C++. In C++, functors offer an opportunity for the compiler to perform better optimisation than it can with a function pointer, which is roughly the alternative. I don't know if that would be true for Ada compilers but if I don't ask by throwing out this idea then I'll never know. In C++, the other main advantage is that templates neither know nor care if they thing they are working with is a function or a functor they both look the same. Ada isn't going to get that advantage - but it's a huge win in the C++ world.

I note people are offering alternatives like using "+" but that's as much an abuse as anything I've done in the above - perhaps people are used to seeing that already.

Yes, it is in part just down to 'coolness' but why shouldn't Ada be cool? A little bit of cool might bring Ada-based companies more business...

And any new language syntax is always obfuscatory - I HATED Ada95 when it came out...I simply couldn't believe what I was seeing was better than my lovely Ada83 code...but I got used to it and now I look at Ada95 code and think it looks awful compared to how I write Ada2012!

I suspect adding this may only make sense in the context of perhaps expanding the generics model not sure…as I mentioned in another post, if the typing was a little bit Duck-ish wrt generic type parameters.

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 16:54         ` Adam Beneschan
  2012-11-14 18:54           ` Martin
@ 2012-11-14 20:37           ` Dmitry A. Kazakov
  2012-11-14 20:57             ` Shark8
                               ` (2 more replies)
  1 sibling, 3 replies; 44+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-14 20:37 UTC (permalink / raw)


On Wed, 14 Nov 2012 08:54:09 -0800 (PST), Adam Beneschan wrote:

> A new way to write obfuscated code?

I don't understand the point. If there is any obfuscation then on the Ada's
side which does not support straightforward declaration of user-defined
arrays/indexing operation.

> You can already do this in Ada 2005; no need to use the new accessor
> features, which are confusing because you're trying to use them in a way
> they're not intended to be used.

Which is?

> You haven't given a good argument for why we need to change the language
> so that programmers can write the above without the .Perform.

Because arrays do not have Perform operation, they do ()-operation.

Indexing is a well established abstraction, which barely needs any
arguments, since most higher level languages have arrays starting with
FORTRAN.

If any argumentation is needed, then on the side of those, who is arguing
that arrays must be only language-defined. Why?

> and (2) programmers can already abuse features of the language to make it
> look the way you want, so we should enshrine it.

Maybe ARG should not introduce features abused so easily? Unfortunately
many of Ada 2005/2012 changes make the language less safe and more
difficult to understand.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 20:37           ` Dmitry A. Kazakov
@ 2012-11-14 20:57             ` Shark8
  2012-11-14 21:31             ` Martin
  2012-11-14 21:45             ` Simon Wright
  2 siblings, 0 replies; 44+ messages in thread
From: Shark8 @ 2012-11-14 20:57 UTC (permalink / raw)
  Cc: mailbox

On Wednesday, November 14, 2012 1:37:55 PM UTC-7, Dmitry A. Kazakov wrote:
> 
> Indexing is a well established abstraction, which barely needs any
> arguments, since most higher level languages have arrays starting with
> FORTRAN.

I tend to start my arrays with 1, enumerations, or 0.

;)



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 20:37           ` Dmitry A. Kazakov
  2012-11-14 20:57             ` Shark8
@ 2012-11-14 21:31             ` Martin
  2012-11-14 22:42               ` Adam Beneschan
  2012-11-15  9:27               ` Dmitry A. Kazakov
  2012-11-14 21:45             ` Simon Wright
  2 siblings, 2 replies; 44+ messages in thread
From: Martin @ 2012-11-14 21:31 UTC (permalink / raw)
  Cc: mailbox

On Wednesday, November 14, 2012 8:37:55 PM UTC, Dmitry A. Kazakov wrote:
> Because arrays do not have Perform operation, they do ()-operation.


Yes, there was a decision at some early point in Ada's life to move away from "[]" for array accessing to "()" - which seems to be a move to deliberately make it look like a function call.

Also, there are enumerate values which again are 'functions'...only not really...now that's obfuscation! :-)
-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 20:37           ` Dmitry A. Kazakov
  2012-11-14 20:57             ` Shark8
  2012-11-14 21:31             ` Martin
@ 2012-11-14 21:45             ` Simon Wright
  2012-11-14 22:22               ` Martin
  2012-11-14 22:27               ` Martin
  2 siblings, 2 replies; 44+ messages in thread
From: Simon Wright @ 2012-11-14 21:45 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Wed, 14 Nov 2012 08:54:09 -0800 (PST), Adam Beneschan wrote:
>
>> A new way to write obfuscated code?
>
> I don't understand the point. If there is any obfuscation then on the
> Ada's side which does not support straightforward declaration of
> user-defined arrays/indexing operation.

This is Martin's code:

   procedure Test is
      F1 : constant Algorithm := C_To_F.Create (10.0);
      F2 : constant Algorithm := C_To_F.Create (20.0);
   begin
      Put_Line ("F1 := " & Long_Float'Image (F1(X)));
      Put_Line ("F2 := " & Long_Float'Image (F2(X)));
   end Test;

F1(X) is a user-defined array indexing which returns the Fahrenheit
equivalent of the 10.0 Celsius that F1 was created with *no matter what
index you supply* because the only purpose of making it look like an
array indexing was to avoid making it look like what it is - a
subprogram call.

There may be some point in this in C++, if the templating mechanism only
cares about the syntactic feature of ()-represents-invocation. I'm not
sure I want to know.



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 21:45             ` Simon Wright
@ 2012-11-14 22:22               ` Martin
  2012-11-14 22:27               ` Martin
  1 sibling, 0 replies; 44+ messages in thread
From: Martin @ 2012-11-14 22:22 UTC (permalink / raw)


On Wednesday, November 14, 2012 9:45:26 PM UTC, Simon Wright wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
> 
> 
> > On Wed, 14 Nov 2012 08:54:09 -0800 (PST), Adam Beneschan wrote:
> 
> >
> 
> >> A new way to write obfuscated code?
> 
> >
> 
> > I don't understand the point. If there is any obfuscation then on the
> 
> > Ada's side which does not support straightforward declaration of
> 
> > user-defined arrays/indexing operation.
> 
> 
> 
> This is Martin's code:
> 
> 
> 
>    procedure Test is
> 
>       F1 : constant Algorithm := C_To_F.Create (10.0);
> 
>       F2 : constant Algorithm := C_To_F.Create (20.0);
> 
>    begin
> 
>       Put_Line ("F1 := " & Long_Float'Image (F1(X)));
> 
>       Put_Line ("F2 := " & Long_Float'Image (F2(X)));
> 
>    end Test;
> 
> 
> 
> F1(X) is a user-defined array indexing which returns the Fahrenheit
> 
> equivalent of the 10.0 Celsius that F1 was created with *no matter what
> 
> index you supply* because the only purpose of making it look like an
> 
> array indexing was to avoid making it look like what it is - a
> 
> subprogram call.
> 
> 
> 
> There may be some point in this in C++, if the templating mechanism only
> 
> cares about the syntactic feature of ()-represents-invocation. I'm not
> 
> sure I want to know.

Simon, remember that 'X' is there to make this work at all with Ada2012...hence my asking 'what about Ada202X'. And, yes, it may only be of real worth if Ada generic change too (see my other thought on that...I thinking about calling that proposal 'Swan typing'...a bit like Duck typing but stronger and more elegant ;-)

I'm actually amazed I'm managed to implement any sort of functors at all in Ada2012 :-)
-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 21:45             ` Simon Wright
  2012-11-14 22:22               ` Martin
@ 2012-11-14 22:27               ` Martin
  1 sibling, 0 replies; 44+ messages in thread
From: Martin @ 2012-11-14 22:27 UTC (permalink / raw)


On Wednesday, November 14, 2012 9:45:26 PM UTC, Simon Wright wrote:
> There may be some point in this in C++, if the templating mechanism only
> cares about the syntactic feature of ()-represents-invocation. I'm not
> sure I want to know.

This bit isn't quite right...the point about C++ templates (with their Duck typing) is that they _don't_ want to know that it's a function call...in fact, it might be a function call or a functor. And using functors give the C++ compiler chances to optimise that aren't available otherwise.

NB: Functors can also hold state unlike the functions that can't (other than static state - and then you have other problems).

Ada already has this 'don't know from looking' feature wrt to arrays (which look like function calls) and enumerates (pretending to be functions).

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 21:31             ` Martin
@ 2012-11-14 22:42               ` Adam Beneschan
  2012-11-15  9:27               ` Dmitry A. Kazakov
  1 sibling, 0 replies; 44+ messages in thread
From: Adam Beneschan @ 2012-11-14 22:42 UTC (permalink / raw)


On Wednesday, November 14, 2012 1:31:53 PM UTC-8, Martin wrote:
> On Wednesday, November 14, 2012 8:37:55 PM UTC, Dmitry A. Kazakov wrote:
> 
> > Because arrays do not have Perform operation, they do ()-operation.
> 
> 
> 
> 
> 
> Yes, there was a decision at some early point in Ada's life to move away from "[]" for array accessing to "()" - which seems to be a move to deliberately make it look like a function call.

No, I think the decision was based more on a Steelman requirement that programs can be written using a very limited character set, and [] weren't in that set.  Neither were some characters we're used to using, like double quote marks.  They got around that by defining alternate syntax for string literals.  But it shouldn't surprise anyone that they solved the array problem by using () for both indexes and subprogram calls, since there was a long history of using () in other languages for array indexes and often for both array indexes and function parameter lists (BASIC and Fortran, for example).  I've seen the idea promoted before that the syntax is the same because someone wanted some kind of equivalence between array indexing and calling a function, but I think it's nonsense (especially since you can say A(I) := B for an array indexing operation but not a function, so the two aren't really equivalent).

                             -- Adam



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-12 22:09 Ada202X : Adding functors Martin
                   ` (2 preceding siblings ...)
  2012-11-13  4:22 ` Shark8
@ 2012-11-15  0:20 ` sbelmont700
  2012-11-15  7:12   ` Martin
  2012-11-15 10:11   ` Dmitry A. Kazakov
  3 siblings, 2 replies; 44+ messages in thread
From: sbelmont700 @ 2012-11-15  0:20 UTC (permalink / raw)


On Monday, November 12, 2012 5:09:15 PM UTC-5, Martin wrote:
> I'm increasingly using functors in my C++ life and they are very cool. I'd like to be able to use them in my Ada life too but the language doesn't support it - or can someone tell me I'm wrong?
> 


IMHO, lambda closures are better in every way than a 'functor', and I for one would welcome their addition to Ada.  That is, assuming the mind-bending travesty of a syntax that Cx11 chose could be avoided.

-sb



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15  0:20 ` sbelmont700
@ 2012-11-15  7:12   ` Martin
  2012-11-15 12:21     ` Georg Bauhaus
  2012-11-15 12:31     ` Georg Bauhaus
  2012-11-15 10:11   ` Dmitry A. Kazakov
  1 sibling, 2 replies; 44+ messages in thread
From: Martin @ 2012-11-15  7:12 UTC (permalink / raw)


Yup...I think I listed lambdas in another post...possibly even my 'No 1'! No chance of me using them in my C++ work, our compilers aren't up to C++11. 



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-14 21:31             ` Martin
  2012-11-14 22:42               ` Adam Beneschan
@ 2012-11-15  9:27               ` Dmitry A. Kazakov
  1 sibling, 0 replies; 44+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-15  9:27 UTC (permalink / raw)


On Wed, 14 Nov 2012 13:31:53 -0800 (PST), Martin wrote:

> On Wednesday, November 14, 2012 8:37:55 PM UTC, Dmitry A. Kazakov wrote:
>> Because arrays do not have Perform operation, they do ()-operation.
> 
> Yes, there was a decision at some early point in Ada's life to move away
> from "[]" for array accessing to "()" - which seems to be a move to
> deliberately make it look like a function call.

Function call and array indexing are strictly same thing called mapping. So
the decision was right. 

> Also, there are enumerate values which again are 'functions'...only not
> really...now that's obfuscation! :-)

Similarly, evaluation of a name into an object is a concept independent on
how the object's value is evaluated, when or if.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15  0:20 ` sbelmont700
  2012-11-15  7:12   ` Martin
@ 2012-11-15 10:11   ` Dmitry A. Kazakov
  2012-11-15 15:52     ` Peter C. Chapin
  2012-11-15 21:34     ` sbelmont700
  1 sibling, 2 replies; 44+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-15 10:11 UTC (permalink / raw)


On Wed, 14 Nov 2012 16:20:44 -0800 (PST), sbelmont700@gmail.com wrote:

> On Monday, November 12, 2012 5:09:15 PM UTC-5, Martin wrote:
>> I'm increasingly using functors in my C++ life and they are very cool. I'd
>> like to be able to use them in my Ada life too but the language doesn't
>> support it - or can someone tell me I'm wrong?
> 
> IMHO, lambda closures are better in every way than a 'functor', and I for
> one would welcome their addition to Ada.

I doubt that could be made compatible with static typing. Comparing 
advantages of both static typing is a clear winner.

But it is of course an interesting question how much functions could be 
made first class citizens without loosing safety (and proper typing).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15  7:12   ` Martin
@ 2012-11-15 12:21     ` Georg Bauhaus
  2012-11-15 12:31     ` Georg Bauhaus
  1 sibling, 0 replies; 44+ messages in thread
From: Georg Bauhaus @ 2012-11-15 12:21 UTC (permalink / raw)


On 15.11.12 08:12, Martin wrote:
> Yup...I think I listed lambdas in another post...possibly even my 'No 1'! No chance of me using them in my C++ work, our compilers aren't up to C++11.
>

Does the capturing mechanism allow returning lambda-expressions
outliving their declarative region, i.e. can they be returned?

I noticed this when boldly trying to make sense of the draft standard:

// 22 [Note: If an entity is implicitly or explicitly captured by
//  reference, invoking the function call operator of the
//  corresponding lambda-Expression after the lifetime of the entity
//  has ended is likely to result in undefined behavior. �endnote]




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15  7:12   ` Martin
  2012-11-15 12:21     ` Georg Bauhaus
@ 2012-11-15 12:31     ` Georg Bauhaus
  2012-11-15 12:46       ` Martin
  2012-11-16  6:15       ` Randy Brukardt
  1 sibling, 2 replies; 44+ messages in thread
From: Georg Bauhaus @ 2012-11-15 12:31 UTC (permalink / raw)


On 15.11.12 08:12, Martin wrote:
> Yup...I think I listed lambdas in another post...possibly even my 'No 1'! No chance of me using them in my C++ work, our compilers aren't up to C++11.
>

If lambda-expressions should help with not naming small
expressions that don't deserve a name (that'll be fun!),
and if lambda-expressions need not be passed upwards,
then maybe more along the lines of if-expressions, and
expression functions,

with Ada.Containers.Vectors;

procedure Foo is
    
    package Nats is new Ada.Containers.Vectors
      (Index_Type => Positive,
       Element_Type => Natural);

    V : Nats.Vector;
    Sum : Natural := 0;

begin  -- not Ada

    V.Iterate (Process => (with (Position : Cursor) do
                             Sum := Sum + Element (Position)));

    declare
       Copy2 : Nats.Vector;
    begin
       for E of V loop
          Copy2.Append
            (New_Item =>
               (with (X : Natural => E) return Natural is
                  2 * X));
       end loop;
    end;

end Foo;




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 12:31     ` Georg Bauhaus
@ 2012-11-15 12:46       ` Martin
  2012-11-16  6:15       ` Randy Brukardt
  1 sibling, 0 replies; 44+ messages in thread
From: Martin @ 2012-11-15 12:46 UTC (permalink / raw)


On Thursday, November 15, 2012 12:31:42 PM UTC, Georg Bauhaus wrote:
> On 15.11.12 08:12, Martin wrote:
> 
> > Yup...I think I listed lambdas in another post...possibly even my 'No 1'! No chance of me using them in my C++ work, our compilers aren't up to C++11.
> 
> >
> 
> 
> 
> If lambda-expressions should help with not naming small
> 
> expressions that don't deserve a name (that'll be fun!),
> 
> and if lambda-expressions need not be passed upwards,
> 
> then maybe more along the lines of if-expressions, and
> 
> expression functions,
> 
> 
> 
> with Ada.Containers.Vectors;
> 
> 
> 
> procedure Foo is
> 
>     
> 
>     package Nats is new Ada.Containers.Vectors
> 
>       (Index_Type => Positive,
> 
>        Element_Type => Natural);
> 
> 
> 
>     V : Nats.Vector;
> 
>     Sum : Natural := 0;
> 
> 
> 
> begin  -- not Ada
> 
> 
> 
>     V.Iterate (Process => (with (Position : Cursor) do
> 
>                              Sum := Sum + Element (Position)));
> 
> 
> 
>     declare
> 
>        Copy2 : Nats.Vector;
> 
>     begin
> 
>        for E of V loop
> 
>           Copy2.Append
> 
>             (New_Item =>
> 
>                (with (X : Natural => E) return Natural is
> 
>                   2 * X));
> 
>        end loop;
> 
>     end;
> 
> 
> 
> end Foo;

+1



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 10:11   ` Dmitry A. Kazakov
@ 2012-11-15 15:52     ` Peter C. Chapin
  2012-11-15 17:04       ` Dmitry A. Kazakov
  2012-11-15 21:34     ` sbelmont700
  1 sibling, 1 reply; 44+ messages in thread
From: Peter C. Chapin @ 2012-11-15 15:52 UTC (permalink / raw)


On 11/15/2012 05:11 AM, Dmitry A. Kazakov wrote:

>> IMHO, lambda closures are better in every way than a 'functor', and I for
>> one would welcome their addition to Ada.
>
> I doubt that could be made compatible with static typing. Comparing
> advantages of both static typing is a clear winner.
>
> But it is of course an interesting question how much functions could be
> made first class citizens without loosing safety (and proper typing).

Could you elaborate on what you mean here? There are statically typed 
functional languages where functions are first class and that also have 
a reasonable notion of type safety.

Peter





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 15:52     ` Peter C. Chapin
@ 2012-11-15 17:04       ` Dmitry A. Kazakov
  2012-11-15 19:57         ` Georg Bauhaus
  2012-11-16  0:01         ` Peter C. Chapin
  0 siblings, 2 replies; 44+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-15 17:04 UTC (permalink / raw)


On Thu, 15 Nov 2012 10:52:02 -0500, Peter C. Chapin wrote:

> On 11/15/2012 05:11 AM, Dmitry A. Kazakov wrote:
> 
>>> IMHO, lambda closures are better in every way than a 'functor', and I for
>>> one would welcome their addition to Ada.
>>
>> I doubt that could be made compatible with static typing. Comparing
>> advantages of both static typing is a clear winner.
>>
>> But it is of course an interesting question how much functions could be
>> made first class citizens without loosing safety (and proper typing).
> 
> Could you elaborate on what you mean here? There are statically typed 
> functional languages where functions are first class and that also have 
> a reasonable notion of type safety.

I think they are actually weakly typed. Nobody would admit that easily, I
would not wonder if Forth people claimed it statically typed as well. (:-))

Anyway, the issue is that functions are intimately related to the types of
their arguments and results as primitive operations. Non-first class
functions are singletons which ensures 1-1 mapping between the operation
and the argument/result type. First-class functions would break that
correspondence. They could be seen as "free functions" regarding their
arguments/result, of course. But, again, there are good reasons why all
operations should be primitive and none free. Yes, Ada violates that rule
and this is a problem already.

It is also unclear what happens with the operations defined on functional
objects. What will be the types of function functions (functionals)? It is
an infinite recursion of higher-order functions to stop somewhere.

Maybe somebody could sort that out, maybe not. In any case there are enough
troubles without that. And I personally find functional decomposition bad.
Georg already posted a quite disgusting example of how it could look like.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 17:04       ` Dmitry A. Kazakov
@ 2012-11-15 19:57         ` Georg Bauhaus
  2012-11-15 20:39           ` Dmitry A. Kazakov
  2012-11-16  0:01         ` Peter C. Chapin
  1 sibling, 1 reply; 44+ messages in thread
From: Georg Bauhaus @ 2012-11-15 19:57 UTC (permalink / raw)


On 15.11.12 18:04, Dmitry A. Kazakov wrote:
> And I personally find functional decomposition bad.


But "anonymous" programming is very, very popular, always.  In
part this is a natural consequence of the benefits that some
programmers associate with anonymity:

When programmers have an easier time not needing to name what
they know (thus hide their "cultural capital"), they think it is
good for them. Their knowledge, their "intellectual property" is
well protected in nested, unnamed expressions. Second, when the
language lets them type less, this creates a win-win situation
for some, as follows:


(1) for programmers who can get away with writing less(*).
(2) for companies that cater to those programmers by supporting
    more anonymity in the language.
(3) for consultants who specialize in getting to know the lambdas'
    meanings

I hope that project managers will not be fooled, but in vain,
I suppose. The DRY principle often misunderstood, so much that
it has become an argument in a rhetorical arsenal of those
who prefer the writer over the reader.

__
(*) Getting away may literally mean to change companies
    and have others take care of their anonymous functions.



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 19:57         ` Georg Bauhaus
@ 2012-11-15 20:39           ` Dmitry A. Kazakov
  2012-11-16  0:15             ` Peter C. Chapin
  0 siblings, 1 reply; 44+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-15 20:39 UTC (permalink / raw)


On Thu, 15 Nov 2012 20:57:35 +0100, Georg Bauhaus wrote:

> On 15.11.12 18:04, Dmitry A. Kazakov wrote:
>> And I personally find functional decomposition bad.
> 
> But "anonymous" programming is very, very popular, always.

I don't think it is about anonymity. It is rather about implied contracts,
inference from given implementation, structural equivalence which makes
functional decomposition questionable.

It boils down to weak typing because a closure is not considered
implementation of some stated, well-thought, designed type property. It is
written ad hoc. I also don't like declarative recursion where imperative
iteration is evidently cleaner. If you want to do something to each element
of container, the language should provide a way to write a plain loop
rather than a closure kludges.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 10:11   ` Dmitry A. Kazakov
  2012-11-15 15:52     ` Peter C. Chapin
@ 2012-11-15 21:34     ` sbelmont700
  1 sibling, 0 replies; 44+ messages in thread
From: sbelmont700 @ 2012-11-15 21:34 UTC (permalink / raw)
  Cc: mailbox

On Thursday, November 15, 2012 5:11:05 AM UTC-5, Dmitry A. Kazakov wrote:
> 
> I doubt that could be made compatible with static typing. Comparing 
> 
> advantages of both static typing is a clear winner.
> 
> 

I always envisioned a sort of access-to-subprogram parameter-type typing, though there are probably all sorts of esoteric problems and better ways.  Otherwise it just seems like auto-generating the code a human normally has to write.

package K is

   type Fancy_Lambda is lambda procedure (arg1 : T1; arg2 : T2);

   procedure P (x : Fancy_Lambda) is
     foo : T1;
     bar : T2;
   begin
     x(arg1 => foo, arg2 => bar);
   end P;

end K;

procedure main is

  baz : Integer;

begin

  -- frakakta C++ syntax...
  K.P(x => [baz] (arg1 : T1; arg2 : T2) {baz := baz + 1});

end main;



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 17:04       ` Dmitry A. Kazakov
  2012-11-15 19:57         ` Georg Bauhaus
@ 2012-11-16  0:01         ` Peter C. Chapin
  2012-11-16  6:09           ` Randy Brukardt
  2012-11-16  8:59           ` Dmitry A. Kazakov
  1 sibling, 2 replies; 44+ messages in thread
From: Peter C. Chapin @ 2012-11-16  0:01 UTC (permalink / raw)


On 11/15/2012 12:04 PM, Dmitry A. Kazakov wrote:

>> Could you elaborate on what you mean here? There are statically typed
>> functional languages where functions are first class and that also have
>> a reasonable notion of type safety.
>
> I think they are actually weakly typed.

In the functional language that I use the most (Scala) lambda terms are 
statically typed and fully checked at compile time, just like any other 
expression.

> Anyway, the issue is that functions are intimately related to the types of
> their arguments and results as primitive operations. Non-first class
> functions are singletons which ensures 1-1 mapping between the operation
> and the argument/result type. First-class functions would break that
> correspondence.

I guess I'm not understanding what you mean here.

> It is also unclear what happens with the operations defined on functional
> objects. What will be the types of function functions (functionals)? It is
> an infinite recursion of higher-order functions to stop somewhere.

If you have higher order functions then you will have a way to write 
function types. For example, in Scala:

def filter(someList: List[Int], predicate: Int => Boolean) = ...

This defines a function 'filter' that takes a list of integers and a 
function from Int to Boolean. The notation 'Int => Boolean' is a 
function type. And yes, you can write types like

	(Int => Boolean) => String

for functions taking a (function from Int to Boolean) and returning 
String. It's no big deal. After all you can use access to access types 
in Ada. You can use records containing records. If you want names for 
the intermediate types, create names for them:

	type PredicateType = Int => Boolean
	type PredicateProcessor = PredicateType => String

Peter




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 20:39           ` Dmitry A. Kazakov
@ 2012-11-16  0:15             ` Peter C. Chapin
  2012-11-16 10:12               ` Georg Bauhaus
  0 siblings, 1 reply; 44+ messages in thread
From: Peter C. Chapin @ 2012-11-16  0:15 UTC (permalink / raw)


On 11/15/2012 03:39 PM, Dmitry A. Kazakov wrote:

> It boils down to weak typing because a closure is not considered
> implementation of some stated, well-thought, designed type property. It is
> written ad hoc.

The design is in the higher order function you are using. My example of 
'filter' again:

def filter(someList: List[Int], predicate: Int => Boolean) = ...

I'll send that function a closure

val resultList = filter(myList, item => item % 2 == 0)

Here 'item => item % 2 == 0' is a function taking the parameter 'item' 
and returning true if it is evenly divisible by two. The compiler knows 
the type of 'item' is Int because it is used in a context where an 
expression of type Int => Boolean is expected. The author of 'filter' 
conducted the well-thought design here. The compiler verifies that 'item 
% 2 == 0' is type correct and evaluates to the required type (Boolean in 
this case).

In this case filter would select items from myList that are even and 
return them in a new list. This could be done with a loop, of course, 
but that would require mutable state and would arguably be less clear. 
Of course that's a matter of taste.

Peter

P.S. Scala actually allows you to write closures with a special 
abbreviation in some cases. The expression above would really be

val resultList = filter(myList, _ % 2 == 0)




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16  0:01         ` Peter C. Chapin
@ 2012-11-16  6:09           ` Randy Brukardt
  2012-11-16 12:35             ` Peter C. Chapin
  2012-11-16  8:59           ` Dmitry A. Kazakov
  1 sibling, 1 reply; 44+ messages in thread
From: Randy Brukardt @ 2012-11-16  6:09 UTC (permalink / raw)



"Peter C. Chapin" <pcc482719@gmail.com> wrote in message 
news:WdGdnd-Z6-nFHzjN4p2dnAA@giganews.com...
> On 11/15/2012 12:04 PM, Dmitry A. Kazakov wrote:
>
>>> Could you elaborate on what you mean here? There are statically typed
>>> functional languages where functions are first class and that also have
>>> a reasonable notion of type safety.
>>
>> I think they are actually weakly typed.
>
> In the functional language that I use the most (Scala) lambda terms are 
> statically typed and fully checked at compile time, just like any other 
> expression.

There's more to a function contract than just the type-and-result-profile! 
To truly statically check such things, you also have to match the 
precondition, the postcondition, the exception contract, the global in/out 
usage, and so on. (Matching doesn't necessarily mean exact equivalence, of 
course, which makes it even harder.)

For Ada 2012, we simply punted on these issues. But that makes 
access-to-subprogram (or any sort of lambda, which would be semantically 
similar to access-to-subprogram) fragile: you can get Assertion_Error from 
any access-to-subprogram value, and there isn't much you can do about it.

One hopes that Ada 2020 will do better in this area, but I'm dubious that it 
can be done well for access-to-subprogram (and lambdas, and formal 
subprograms, all semantically similar). Complete reliance on dynamic 
contracts can be useful, but it certainly isn't my idea of strong types 
(that is, enforced at compile-time).

                                              Randy.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-15 12:31     ` Georg Bauhaus
  2012-11-15 12:46       ` Martin
@ 2012-11-16  6:15       ` Randy Brukardt
  1 sibling, 0 replies; 44+ messages in thread
From: Randy Brukardt @ 2012-11-16  6:15 UTC (permalink / raw)


"Georg Bauhaus" <rm.dash-bauhaus@futureapps.de> wrote in message 
news:50a4e088$0$9518$9b4e6d93@newsspool1.arcor-online.net...
...
> If lambda-expressions should help with not naming small
> expressions that don't deserve a name (that'll be fun!),
> and if lambda-expressions need not be passed upwards,
> then maybe more along the lines of if-expressions, and
> expression functions,

We talked about that during Ada 2012 as an alternative to the (heavier) 
iterator and reference "syntax sugar". But it doesn't really solve the 
problem (separating code from it's "natural" location and having 
user-defined and language-defined containers "look" different than the 
built-in containers).

I'm somewhat dubious that lambdas would really be the solution to anything 
(other than making entries in the obfuscated Ada contest easier :-). But I'm 
willing to be convinced...

                                                       Randy.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16  0:01         ` Peter C. Chapin
  2012-11-16  6:09           ` Randy Brukardt
@ 2012-11-16  8:59           ` Dmitry A. Kazakov
  2012-11-16 12:20             ` Peter C. Chapin
  1 sibling, 1 reply; 44+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-16  8:59 UTC (permalink / raw)


On Thu, 15 Nov 2012 19:01:28 -0500, Peter C. Chapin wrote:

> On 11/15/2012 12:04 PM, Dmitry A. Kazakov wrote:
> 
>> Anyway, the issue is that functions are intimately related to the types of
>> their arguments and results as primitive operations. Non-first class
>> functions are singletons which ensures 1-1 mapping between the operation
>> and the argument/result type. First-class functions would break that
>> correspondence.
> 
> I guess I'm not understanding what you mean here.

   type T is tagged ...
   procedure Operation (X : T);

There is only one instance of Operation for T. This is easy when Operation
is not an object. Once you make it an object, there could possibly be more
than one instance of.

   X : T'Class;
begin
   X.Operation;  -- Which one instance is called here?

Dispatching tables shall be checked statically, they shall have only one
operation in a slot etc.

>> It is also unclear what happens with the operations defined on functional
>> objects. What will be the types of function functions (functionals)? It is
>> an infinite recursion of higher-order functions to stop somewhere.
> 
> If you have higher order functions then you will have a way to write 
> function types. For example, in Scala:
> 
> def filter(someList: List[Int], predicate: Int => Boolean) = ...
> 
> This defines a function 'filter' that takes a list of integers and a 
> function from Int to Boolean. The notation 'Int => Boolean' is a 
> function type. And yes, you can write types like
> 
> 	(Int => Boolean) => String
> 
> for functions taking a (function from Int to Boolean) and returning 
> String. It's no big deal.

Can I inherit it? Override it? Which are the classes of types

   (Int => Boolean) => String

operates on?

> After all you can use access to access types 
> in Ada.

Yes. It puzzled me for years why we still cannot do it without access:

   type Integer_To_Boolean is function (X : Integer) return Boolean;

But this is not same as functions being first-class with all bells and
whistles.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16  0:15             ` Peter C. Chapin
@ 2012-11-16 10:12               ` Georg Bauhaus
  0 siblings, 0 replies; 44+ messages in thread
From: Georg Bauhaus @ 2012-11-16 10:12 UTC (permalink / raw)


On 16.11.12 01:15, Peter C. Chapin wrote:
> val resultList = filter(myList, _ % 2 == 0)

Incidentally, I have just again had to turn a short expression
like this into a regular function, since keeping it as an
expression would have made the program unreadable.

I think that "growing up" to become a function is the fate of many
expressions playing the role of a function.

In the language I need to use, filtering looks like

   my @resultList = grep { _ % 2 == 0 } @$myList;

Actually, I also need to sort records in $myList in reverse order by
a field named "id". Language support is structurally similar to
filtering. Special sort variables $a and $b provided by the language:

   my @resultList = sort { $b->{"id"} <=> $a->{"id"} } @$myList;

Again, an unnamed expression, $b->{"id"} <=> $a->{"id"}.

It turned out at some point that the components of $myList needed a
more complex comparison, since "id" would not establish the desired
order. Therefore, the statement now is,

   my @resultList = sort $by_latest @$myList;

where $by_latest is a code reference, a "function pointer".  But! As
almost always, the function would not need to carry its environment
around.

So the situation made me end up with the Perl equivalent of a plain
old Ada generic or function pointer, roughly,

   generic
      type T(<>) is private;
      with Comp (a, b: T) return int;
      -- ...
   function sort (items : in out List) return List;

This is not the first time that an expression had to become a function.
To me, this development seems to be the more frequent case.

Maybe unnamed expressions work much better in the role of a gimmick,
for example, when introducing "generic functions" by demonstration.




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16  8:59           ` Dmitry A. Kazakov
@ 2012-11-16 12:20             ` Peter C. Chapin
  2012-11-16 17:44               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 44+ messages in thread
From: Peter C. Chapin @ 2012-11-16 12:20 UTC (permalink / raw)


On 11/16/2012 03:59 AM, Dmitry A. Kazakov wrote:

>     type T is tagged ...
>     procedure Operation (X : T);
>
> There is only one instance of Operation for T. This is easy when Operation
> is not an object. Once you make it an object, there could possibly be more
> than one instance of.
>
>     X : T'Class;
> begin
>     X.Operation;  -- Which one instance is called here?

Isn't this an issue even without first class functions? It sounds like 
you are talking about dynamic dispatch... an OOP issue, not a functional 
issue. I guess I'm still not following you.

>> def filter(someList: List[Int], predicate: Int => Boolean) = ...
>>
>> This defines a function 'filter' that takes a list of integers and a
>> function from Int to Boolean. The notation 'Int => Boolean' is a
>> function type. And yes, you can write types like
>>
>> 	(Int => Boolean) => String
>>
>> for functions taking a (function from Int to Boolean) and returning
>> String. It's no big deal.
>
> Can I inherit it?

Yes.

class MyClass extends (Int => Boolean) => String {
   // ...
}

> Override it?

Not sure what you mean by this. You can override what it does when 
applied to an argument.

> Which are the classes of types
>
>     (Int => Boolean) => String
>
> operates on?

Scala treats function types as classes with a special 'apply' method. 
While that might seem like a circular definition it isn't because 
methods and functions are regarded differently in that language. In 
particular the type (Int => Boolean) => String is syntactic sugar for

	Function1[Function1[Int, Boolean], String]

where the [] syntax is used for generic type parameters. Anyway Scala 
has unusually tight integration between its functional and object 
oriented features (which is why I was surprised to learn that it didn't 
support contravariant refinement of parameter types). It's one of the 
hallmarks of that particular language.

Peter




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16  6:09           ` Randy Brukardt
@ 2012-11-16 12:35             ` Peter C. Chapin
  2012-11-16 18:10               ` Martin
  0 siblings, 1 reply; 44+ messages in thread
From: Peter C. Chapin @ 2012-11-16 12:35 UTC (permalink / raw)


On 11/16/2012 01:09 AM, Randy Brukardt wrote:

> There's more to a function contract than just the type-and-result-profile!
> To truly statically check such things, you also have to match the
> precondition, the postcondition, the exception contract, the global in/out
> usage, and so on. (Matching doesn't necessarily mean exact equivalence, of
> course, which makes it even harder.)

I should probably first make it clear that I'm not necessarily 
advocating for the addition of lambda expressions to Ada. My posts in 
this thread are only to say that lambda expressions are not necessarily 
any more weakly typed than any other kind of expression (as Dmitry asserts).

Anyway, it is certainly true that the contract extends beyond the 
type-and-result-profile. In that respect a function type is a richer 
entity than, say, type Integer... of course. Yet one could imagine a 
hypothetical language in which some of this additional richness was 
packed into the function type either with appropriate syntax or some 
sort of extra-linguistic annotations. In that case, parameters of higher 
order subprograms could declare this additional information, making it 
available for static analysis.

The full contract of a function includes its semantics as well. It would 
be interesting to speculate on what it would take to describe the 
semantics of a function with some suitable formal notation and decorate 
declarations with that information for purposes of static analysis. For 
example:

procedure Process_With(X : Integer,
                        F : Some_Function_Type with Semantics => (
   -- Semantics of required function written in Z (for example)
   )) is
begin
   -- etc...
end Process_With;

This is the other extreme on a scale starting with just the 
type-and-result profile of F embedded in its type. We can arbitrarily 
draw a line on the scale and say everything to the left of that line is 
"weak" and everything to the right is "strong" but the line is still 
arbitrary.

Peter




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16 12:20             ` Peter C. Chapin
@ 2012-11-16 17:44               ` Dmitry A. Kazakov
  2012-11-18 15:58                 ` Peter C. Chapin
  0 siblings, 1 reply; 44+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-16 17:44 UTC (permalink / raw)


On Fri, 16 Nov 2012 07:20:58 -0500, Peter C. Chapin wrote:

> On 11/16/2012 03:59 AM, Dmitry A. Kazakov wrote:
> 
>>     type T is tagged ...
>>     procedure Operation (X : T);
>>
>> There is only one instance of Operation for T. This is easy when Operation
>> is not an object. Once you make it an object, there could possibly be more
>> than one instance of.
>>
>>     X : T'Class;
>> begin
>>     X.Operation;  -- Which one instance is called here?
> 
> Isn't this an issue even without first class functions? It sounds like 
> you are talking about dynamic dispatch... an OOP issue, not a functional 
> issue. I guess I'm still not following you.

It is about how many instances of primitive

   procedure (X : T)

are allowed to exist. It is different from dispatch which selects instances
of different functional types. E.g.

   procedure (X : T)
   procedure (X : S)

S /= T

>>> def filter(someList: List[Int], predicate: Int => Boolean) = ...
>>>
>>> This defines a function 'filter' that takes a list of integers and a
>>> function from Int to Boolean. The notation 'Int => Boolean' is a
>>> function type. And yes, you can write types like
>>>
>>> 	(Int => Boolean) => String
>>>
>>> for functions taking a (function from Int to Boolean) and returning
>>> String. It's no big deal.
>>
>> Can I inherit it?
> 
> Yes.
> 
> class MyClass extends (Int => Boolean) => String {
>    // ...
> }

And the semantics of? Considering this:

   type T is tagged ...
   procedure Operation (X : T);

   procedure Operation_1 (X : T) is new Operation (X : T) with ...;

would mean what?

>> Override it?
> 
> Not sure what you mean by this.

1. When you inherit from Operation you inherit higher-order functions
defined on Operation (not on T). May I override them?

2. Let I inherited from Operation and overrode Operation in T. What
happens?

3. The class of operations derived from:

   procedure (X : T)
   
is

   procedure (X : T)'Class

What is the semantics of? In which relation is it with

  procedure (X : T'Class)
  procedure (X : T'Class)'Class

>> Which are the classes of types
>>
>>     (Int => Boolean) => String
>>
>> operates on?
> 
> Scala treats function types as classes with a special 'apply' method. 

This is equivalent to Ada's access to subprogram. But I suggest that
"apply" cannot be overridden just like Ada's all cannot. Which flattens the
type structure. The recursion is killed because "apply" or "all" are not
really first-class.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16 12:35             ` Peter C. Chapin
@ 2012-11-16 18:10               ` Martin
  0 siblings, 0 replies; 44+ messages in thread
From: Martin @ 2012-11-16 18:10 UTC (permalink / raw)


On Friday, November 16, 2012 12:35:52 PM UTC, Peter C. Chapin wrote:
> On 11/16/2012 01:09 AM, Randy Brukardt wrote:
> 
> 
> 
> > There's more to a function contract than just the type-and-result-profile!
> 
> > To truly statically check such things, you also have to match the
> 
> > precondition, the postcondition, the exception contract, the global in/out
> 
> > usage, and so on. (Matching doesn't necessarily mean exact equivalence, of
> 
> > course, which makes it even harder.)
> 
> 
> 
> I should probably first make it clear that I'm not necessarily 
> 
> advocating for the addition of lambda expressions to Ada. My posts in 
> 
> this thread are only to say that lambda expressions are not necessarily 
> 
> any more weakly typed than any other kind of expression (as Dmitry asserts).
> 
> 
> 
> Anyway, it is certainly true that the contract extends beyond the 
> 
> type-and-result-profile. In that respect a function type is a richer 
> 
> entity than, say, type Integer... of course. Yet one could imagine a 
> 
> hypothetical language in which some of this additional richness was 
> 
> packed into the function type either with appropriate syntax or some 
> 
> sort of extra-linguistic annotations. In that case, parameters of higher 
> 
> order subprograms could declare this additional information, making it 
> 
> available for static analysis.
> 
> 
> 
> The full contract of a function includes its semantics as well. It would 
> 
> be interesting to speculate on what it would take to describe the 
> 
> semantics of a function with some suitable formal notation and decorate 
> 
> declarations with that information for purposes of static analysis. For 
> 
> example:
> 
> 
> 
> procedure Process_With(X : Integer,
> 
>                         F : Some_Function_Type with Semantics => (
> 
>    -- Semantics of required function written in Z (for example)
> 
>    )) is
> 
> begin
> 
>    -- etc...
> 
> end Process_With;

Couldn't we just re-use what Ada already provides? Isn't it pre/post conditions?

procedure Process_With (X : Integer;
                                      F : Some_Function_Type
                                         with Pre => X > 10 and Post <= Some_Function_Type'Return > 100) is
begin
...
end Process_With;

-- Martin



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: Ada202X : Adding functors
  2012-11-16 17:44               ` Dmitry A. Kazakov
@ 2012-11-18 15:58                 ` Peter C. Chapin
  0 siblings, 0 replies; 44+ messages in thread
From: Peter C. Chapin @ 2012-11-18 15:58 UTC (permalink / raw)


On 11/16/2012 12:44 PM, Dmitry A. Kazakov wrote:

>> class MyClass extends (Int => Boolean) => String {
>>     // ...
>> }
>
> And the semantics of?

In Scala, anyway, there is a "magic" method apply that is used to define 
what happens when an object is applied to arguments. Since function 
types are abstract in Scala the compiler will require the programmer to 
override apply() to define what MyClass objects do when they are used as 
functions.

 > Considering this:
>
>     type T is tagged ...
>     procedure Operation (X : T);
>
>     procedure Operation_1 (X : T) is new Operation (X : T) with ...;
>
> would mean what?

I'm not sure. Are you trying to define a new type similar to

	type My_Integer is new Integer;

Or are you talking about dynamically creating function objects? On the 
other hand based on your comments it sounds like you might be talking 
about adding "methods" to existing "classes" (using non-Ada 
terminology). Or maybe you are speculating about the behavior of 
function types if they were also tagged types themselves. I can't tell 
from your presentation what you are talking about.

Anyway, it could well be the case that adding first class functions to 
Ada would be a bad idea due to unfavorable interactions with existing 
features. Perhaps this is what your examples are illustrating. But... 
that doesn't mean that first class functions are "weakly typed" in 
general. I believe that was your original assertion and that's what I'm 
taking exception to.

It might be interesting to note that, again in Scala at least, methods 
and functions are treated differently and methods are not really first 
class (although functions are). The compiler will implicitly wrap a 
method in a closure so it can be treated like a function but doing so 
needs a specific object to resolve the method's internal 'this' 
reference. If one wanted to get serious about adding first class 
functions to Ada perhaps a similar path could be followed to make it 
work sensibly.

Peter




^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2012-11-21  8:41 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-12 22:09 Ada202X : Adding functors Martin
2012-11-12 23:14 ` Jeffrey Carter
2012-11-12 23:19   ` Martin
2012-11-13 10:45     ` Georg Bauhaus
2012-11-13 12:08       ` Yannick Duchêne (Hibou57)
2012-11-13 12:35       ` Martin
2012-11-12 23:44 ` Adam Beneschan
2012-11-13  2:11   ` Jeffrey Carter
2012-11-13 11:11   ` Martin
2012-11-14  0:51     ` Adam Beneschan
2012-11-14  8:39       ` Martin
2012-11-14 16:54         ` Adam Beneschan
2012-11-14 18:54           ` Martin
2012-11-14 20:37           ` Dmitry A. Kazakov
2012-11-14 20:57             ` Shark8
2012-11-14 21:31             ` Martin
2012-11-14 22:42               ` Adam Beneschan
2012-11-15  9:27               ` Dmitry A. Kazakov
2012-11-14 21:45             ` Simon Wright
2012-11-14 22:22               ` Martin
2012-11-14 22:27               ` Martin
2012-11-13  4:22 ` Shark8
2012-11-15  0:20 ` sbelmont700
2012-11-15  7:12   ` Martin
2012-11-15 12:21     ` Georg Bauhaus
2012-11-15 12:31     ` Georg Bauhaus
2012-11-15 12:46       ` Martin
2012-11-16  6:15       ` Randy Brukardt
2012-11-15 10:11   ` Dmitry A. Kazakov
2012-11-15 15:52     ` Peter C. Chapin
2012-11-15 17:04       ` Dmitry A. Kazakov
2012-11-15 19:57         ` Georg Bauhaus
2012-11-15 20:39           ` Dmitry A. Kazakov
2012-11-16  0:15             ` Peter C. Chapin
2012-11-16 10:12               ` Georg Bauhaus
2012-11-16  0:01         ` Peter C. Chapin
2012-11-16  6:09           ` Randy Brukardt
2012-11-16 12:35             ` Peter C. Chapin
2012-11-16 18:10               ` Martin
2012-11-16  8:59           ` Dmitry A. Kazakov
2012-11-16 12:20             ` Peter C. Chapin
2012-11-16 17:44               ` Dmitry A. Kazakov
2012-11-18 15:58                 ` Peter C. Chapin
2012-11-15 21:34     ` sbelmont700

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox