comp.lang.ada
 help / color / mirror / Atom feed
* Access type to member procedure of instance (Object Oriented programming in Ada)
@ 2012-11-19  9:59 ake.ragnar.dahlgren
  2012-11-19 11:13 ` Georg Bauhaus
                   ` (7 more replies)
  0 siblings, 8 replies; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-11-19  9:59 UTC (permalink / raw)


Not sure if this has already been discussed but: Is it possible to define a pointer to a member procedure of an instance?

This problem has it's origin in the implementation of the MVC pattern for a GtkAda application. Consider the following:

package Some_Package is

   type Message_Type is tagged null record;
   
   procedure Print(Message : Message_Type);

end Some_Package;



package body Some_Package is

   procedure Print (Message : Message_Type) is
   begin
      null;
   end Print;

end Some_Package;


Then it is possible to create the following Main application that compiles just fine:

with Some_Package;

procedure Main is
   Message : Some_Package.Message_Type;
begin
   Message.Print;
end Main;

Is it possible to create a parameterless access type to the Message.Print procedure? The following application refuses to compile:

with Some_Package;

procedure Main is
   Message : Some_Package.Message_Type;
   
   Method_Ref : access procedure := Message.Print'Access;
begin
   Method_Ref;
end Main;

The error message is: no selector "Print" for type "Message_Type" defined at some_package.ads:3


It is possible to create a workaround:

with Some_Package;

procedure Main is
   Message : Some_Package.Message_Type;
   
   procedure Method_Ref is
   begin
      Message.Print;
   end Method_Ref;
   
begin
   Method_Ref;
end Main;

Is there a better way? Or is this the optimal way?

Regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
@ 2012-11-19 11:13 ` Georg Bauhaus
  2012-11-19 11:39 ` Brian Drummond
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 47+ messages in thread
From: Georg Bauhaus @ 2012-11-19 11:13 UTC (permalink / raw)


On 19.11.12 10:59, ake.ragnar.dahlgren@gmail.com wrote:
> Is there a better way? Or is this the optimal way?

It depends, and is easier to answer once the intent
is known. The idea is that using normal means, a pointer
cannot just point at any callable thing, and the indirect
call cannot be expected to work, without taking
the required parameters into account, somehow.

If this particular implementation of the MVC pattern
does not allow calling object oriented operations via objects
or pointers to these, maybe an example of how to do a similar
thing and guidance is found the source of (version 1 or version 3)
of the AUnit testing framework.




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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
  2012-11-19 11:13 ` Georg Bauhaus
@ 2012-11-19 11:39 ` Brian Drummond
  2012-11-20 11:43   ` Brian Drummond
  2012-11-19 13:03 ` sbelmont700
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 47+ messages in thread
From: Brian Drummond @ 2012-11-19 11:39 UTC (permalink / raw)


On Mon, 19 Nov 2012 01:59:42 -0800, ake.ragnar.dahlgren wrote:

> Not sure if this has already been discussed but: Is it possible to
> define a pointer to a member procedure of an instance?

Yes.

with Some_Package;

procedure Main is
   Message : Some_Package.Message_Type;

   Method_Ref : access procedure (Message : Some_Package.Message_Type) 
		:= Some_Package.Print'Access;
begin
   Method_Ref.all(Message);
end Main;

However this is not the same question as:

> Is it possible to create a parameterless access type to the
> Message.Print procedure? The following application refuses to compile:

Message.Print is not parameterless, it is identical to Print(Message) 
so ... no. 

(This is not specifically Ada, in any OO language I have ever seen, the 
receiver is always the first parameter. I don't know of any language that 
replicates every method for every instance of a class, but I suppose it's 
theoretically possible!. Unless "Message" is a singleton, it would be 
horribly inefficient)

You can certainly define a pointer to the member procedure, but it still 
expects a parameter, and you still have to supply that.

You can certainly wrap it in a parameterless procedure (binding Message 
to Print) and create a parameterless access to that... 
with Some_Package;

procedure Main is
   Message : Some_Package.Message_Type;

procedure PrintMessage is
begin
   Message.Print;
end PrintMessage;
   
   Method_Ref : access procedure := PrintMessage'Access;
begin
   Method_Ref.all;
end Main;

but I have a feeling you are trying to accomplish something else here and 
I can't see what. 

Hopefully someone else has a better idea...

- Brian



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
  2012-11-19 11:13 ` Georg Bauhaus
  2012-11-19 11:39 ` Brian Drummond
@ 2012-11-19 13:03 ` sbelmont700
  2012-11-19 16:18 ` Adam Beneschan
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 47+ messages in thread
From: sbelmont700 @ 2012-11-19 13:03 UTC (permalink / raw)


On Monday, November 19, 2012 4:59:42 AM UTC-5, ake.ragna...@gmail.com wrote:
> 
> Is it possible to create a parameterless access type to the Message.Print procedure?
> 

Unless there is more to the story you haven't provided, you probably ought to be taking an access value to a Message'Class object, and invoking Print on that.

-sb



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
                   ` (2 preceding siblings ...)
  2012-11-19 13:03 ` sbelmont700
@ 2012-11-19 16:18 ` Adam Beneschan
  2012-11-19 17:02   ` Peter C. Chapin
  2012-11-19 20:22 ` ake.ragnar.dahlgren
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 47+ messages in thread
From: Adam Beneschan @ 2012-11-19 16:18 UTC (permalink / raw)


On Monday, November 19, 2012 1:59:42 AM UTC-8, ake.ragna...@gmail.com wrote:
> Not sure if this has already been discussed but: Is it possible to define a pointer to a member procedure of an instance?

No, I don't think so.  I've been thinking about proposing an addition to Ada to do something like this, since I think this feature does exist in other languages (C# delegates, in particular; I don't know C++ well enough to know whether there's something similar there).  

Ada already has "access protected procedure", in which an access object has to have both a reference to the code being called and a reference to the (protected) object being operated on.  So at first glance it seems like adding a new kind of access type "access blahblah procedure" (perhaps "access tagged procedure", if we want to avoid defining a new reserved word), where the access object has both a reference to the subprogram code and a reference to the object being operated on, wouldn't be too difficult.  My thinking here is that if you say Obj.Op'access, and Obj has a class-wide type, then an indirect call through the access type would dispatch to the correct Op.  The tricky thing is figuring out whether it would play nice with other language features, such as pre-/post-conditions.  

Unlike the other posters here, I haven't studied your example to see whether it is really a good example of a case where a feature like this is needed, or whether there's a good enough workaround using existing Ada features to solve your particular problem.

                                -- Adam



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 16:18 ` Adam Beneschan
@ 2012-11-19 17:02   ` Peter C. Chapin
  2012-11-19 18:23     ` Adam Beneschan
  2012-11-20 10:59     ` Brian Drummond
  0 siblings, 2 replies; 47+ messages in thread
From: Peter C. Chapin @ 2012-11-19 17:02 UTC (permalink / raw)


On 11/19/2012 11:18 AM, Adam Beneschan wrote:

> No, I don't think so.  I've been thinking about proposing an addition
> to Ada to do something like this, since I think this feature does
> exist in other languages (C# delegates, in particular; I don't know
> C++ well enough to know whether there's something similar there).

FWIW C++ does have a "pointer to member" feature. It looks like this

class Example {
public:
   void f( int );
};

// Declare p to be "pointer to member function of Example...
// Initialize p to point at Example::f.
void (Example::*p)( int ) = &Example::f;

Example object;  // Create an object.
object.*p(42);   // Invoke member f indirectly on 'object'

Peter







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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 17:02   ` Peter C. Chapin
@ 2012-11-19 18:23     ` Adam Beneschan
  2012-11-19 20:57       ` Peter C. Chapin
  2012-11-19 21:26       ` Dmitry A. Kazakov
  2012-11-20 10:59     ` Brian Drummond
  1 sibling, 2 replies; 47+ messages in thread
From: Adam Beneschan @ 2012-11-19 18:23 UTC (permalink / raw)


On Monday, November 19, 2012 9:02:29 AM UTC-8, Peter C. Chapin wrote:
> On 11/19/2012 11:18 AM, Adam Beneschan wrote:
> 
> 
> FWIW C++ does have a "pointer to member" feature. It looks like this
> 
> class Example {
> 
> public:
> 
>    void f( int );
> 
> };
> 
> // Declare p to be "pointer to member function of Example...
> // Initialize p to point at Example::f.
> void (Example::*p)( int ) = &Example::f;
> 
> Example object;  // Create an object.
> object.*p(42);   // Invoke member f indirectly on 'object'

This doesn't look at all like what I'm talking about, since &Example::f still refers to a method defined for the class Example but without reference to a particular object.  Something equivalent would be if you could say &object.f (or maybe &object.*p) and store the result of that in a pointer that could be called later.

                             -- Adam



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
                   ` (3 preceding siblings ...)
  2012-11-19 16:18 ` Adam Beneschan
@ 2012-11-19 20:22 ` ake.ragnar.dahlgren
  2012-11-20 11:16   ` Brian Drummond
  2012-11-19 20:52 ` ake.ragnar.dahlgren
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-11-19 20:22 UTC (permalink / raw)


On Monday, November 19, 2012 10:59:42 AM UTC+1, ake.ragna...@gmail.com wrote:
> Not sure if this has already been discussed but: Is it possible to define a pointer to a member procedure of an instance?
> 
> 
> 
> This problem has it's origin in the implementation of the MVC pattern for a GtkAda application. Consider the following:
> 
> 
> 
> package Some_Package is
> 
> 
> 
>    type Message_Type is tagged null record;
> 
>    
> 
>    procedure Print(Message : Message_Type);
> 
> 
> 
> end Some_Package;
> 
> 
> 
> 
> 
> 
> 
> package body Some_Package is
> 
> 
> 
>    procedure Print (Message : Message_Type) is
> 
>    begin
> 
>       null;
> 
>    end Print;
> 
> 
> 
> end Some_Package;
> 
> 
> 
> 
> 
> Then it is possible to create the following Main application that compiles just fine:
> 
> 
> 
> with Some_Package;
> 
> 
> 
> procedure Main is
> 
>    Message : Some_Package.Message_Type;
> 
> begin
> 
>    Message.Print;
> 
> end Main;
> 
> 
> 
> Is it possible to create a parameterless access type to the Message.Print procedure? The following application refuses to compile:
> 
> 
> 
> with Some_Package;
> 
> 
> 
> procedure Main is
> 
>    Message : Some_Package.Message_Type;
> 
>    
> 
>    Method_Ref : access procedure := Message.Print'Access;
> 
> begin
> 
>    Method_Ref;
> 
> end Main;
> 
> 
> 
> The error message is: no selector "Print" for type "Message_Type" defined at some_package.ads:3
> 
> 
> 
> 
> 
> It is possible to create a workaround:
> 
> 
> 
> with Some_Package;
> 
> 
> 
> procedure Main is
> 
>    Message : Some_Package.Message_Type;
> 
>    
> 
>    procedure Method_Ref is
> 
>    begin
> 
>       Message.Print;
> 
>    end Method_Ref;
> 
>    
> 
> begin
> 
>    Method_Ref;
> 
> end Main;
> 
> 
> 
> Is there a better way? Or is this the optimal way?
> 
> 
> 
> Regards,
> 
> Åke Ragnar Dahlgren

Thanks everybody for posting. Adam you answered my question perfectly since my question was a pure Ada question whether or not it is possible to define pointers to member methods of class instances. And the answer is no. To add this as a feature to Ada might be useful. But of course this needs careful investigation.

I do not mean to make this a Gtkada issue but I have received requests for clarifying the origin of the question.

The Gtk application uses Glade and contains the following procedure call:

Gtkada.Builder.Register_Handler
   (Builder      => Builder,
    Handler_Name => "File_Quit",
    Handler      => On_Quit'Access);

where the On_Quit procedure is declared as follows:

procedure On_Quit (Object : access Gtkada.Builder.Gtkada_Builder_Record'Class) is
begin
  -- Code is omitted
end On_Quit;

When On_Quit is defined as above everything compiles just fine. The problem is if one would like the On_Quit method to be a member method of an instance. In this case there is a Controller instance whose method should be called. It is declared as:

procedure On_Quit (This   : Controller_Type;
                   Object : access Gtkada.Builder.Gtkada_Builder_Record'Class);

Using the Controller's On_Quit procedure one would like to write:

Gtkada.Builder.Register_Handler
   (Builder      => Builder,
    Handler_Name => "File_Quit",
    Handler      => Controller.On_Quit'Access);

This did not compile and thereof the question.

Additional information if needed: The spec. of the Register_Handler procedure in the Gtkada.Builder package is declared as:

procedure Register_Handler
  (Builder      : access Gtkada_Builder_Record'Class;
   Handler_Name : String;
   Handler      : Builder_Handler);

The Builder_Handler is a pointer to a method:

type Builder_Handler is access procedure
  (Builder : access Gtkada_Builder_Record'Class);

Best regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
                   ` (4 preceding siblings ...)
  2012-11-19 20:22 ` ake.ragnar.dahlgren
@ 2012-11-19 20:52 ` ake.ragnar.dahlgren
  2012-11-19 21:56   ` Dmitry A. Kazakov
  2012-11-19 22:13   ` sbelmont700
  2012-11-19 23:59 ` Randy Brukardt
  2012-11-22  9:47 ` ake.ragnar.dahlgren
  7 siblings, 2 replies; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-11-19 20:52 UTC (permalink / raw)


On Monday, November 19, 2012 10:59:42 AM UTC+1, ake.ragna...@gmail.com wrote:
> Not sure if this has already been discussed but: Is it possible to define a pointer to a member procedure of an instance?
> 
> 
> 
> This problem has it's origin in the implementation of the MVC pattern for a GtkAda application. Consider the following:
> 
> 
> 
> package Some_Package is
> 
> 
> 
>    type Message_Type is tagged null record;
> 
>    
> 
>    procedure Print(Message : Message_Type);
> 
> 
> 
> end Some_Package;
> 
> 
> 
> 
> 
> 
> 
> package body Some_Package is
> 
> 
> 
>    procedure Print (Message : Message_Type) is
> 
>    begin
> 
>       null;
> 
>    end Print;
> 
> 
> 
> end Some_Package;
> 
> 
> 
> 
> 
> Then it is possible to create the following Main application that compiles just fine:
> 
> 
> 
> with Some_Package;
> 
> 
> 
> procedure Main is
> 
>    Message : Some_Package.Message_Type;
> 
> begin
> 
>    Message.Print;
> 
> end Main;
> 
> 
> 
> Is it possible to create a parameterless access type to the Message.Print procedure? The following application refuses to compile:
> 
> 
> 
> with Some_Package;
> 
> 
> 
> procedure Main is
> 
>    Message : Some_Package.Message_Type;
> 
>    
> 
>    Method_Ref : access procedure := Message.Print'Access;
> 
> begin
> 
>    Method_Ref;
> 
> end Main;
> 
> 
> 
> The error message is: no selector "Print" for type "Message_Type" defined at some_package.ads:3
> 
> 
> 
> 
> 
> It is possible to create a workaround:
> 
> 
> 
> with Some_Package;
> 
> 
> 
> procedure Main is
> 
>    Message : Some_Package.Message_Type;
> 
>    
> 
>    procedure Method_Ref is
> 
>    begin
> 
>       Message.Print;
> 
>    end Method_Ref;
> 
>    
> 
> begin
> 
>    Method_Ref;
> 
> end Main;
> 
> 
> 
> Is there a better way? Or is this the optimal way?
> 
> 
> 
> Regards,
> 
> Åke Ragnar Dahlgren

Actually I've been thinking. The workaround worked for the contrived example above but not for my Gtkada application.

What inspired the Gtkada application I've been experimenting with is the explanation given by Ada in Denmark on their wiki:

http://wiki.ada-dk.org/building_gui_with_glade_3

What one can see there is that a Builder instance is created and when the application quits it is deallocated. This makes the code suitable for using Ada's object oriented features and to let the Builder instance be created in the Initialize procedure and let it be deallocated in the Finalize procedure.

Also it is possible to see that the callbacks are declared in the Simple_Callbacks package. Note that the methods are not instance member methods.

I hope I am wrong but it seems to me that since Ada lacks the ability to create pointers (maybe access types are the right words) to instance member methods, it is not possible to take advantage of Ada's OOP features when developing Glade3 applications.

Best regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 18:23     ` Adam Beneschan
@ 2012-11-19 20:57       ` Peter C. Chapin
  2012-11-19 21:26       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 47+ messages in thread
From: Peter C. Chapin @ 2012-11-19 20:57 UTC (permalink / raw)


On 11/19/2012 01:23 PM, Adam Beneschan wrote:

>> class Example {
>> public:
>>     void f( int );
>> };
>>
>> // Declare p to be "pointer to member function of Example...
>> // Initialize p to point at Example::f.
>> void (Example::*p)( int ) = &Example::f;
>>
>> Example object;  // Create an object.
>> object.*p(42);   // Invoke member f indirectly on 'object'
>

> This doesn't look at all like what I'm talking about, since &Example::f still refers to a method defined for the class Example but without reference to a particular object.  Something equivalent would be if you could say &object.f (or maybe &object.*p) and store the result of that in a pointer that could be called later.

It's not exactly the same for sure but there are similarities. Here you 
can create the pointer without reference to any particular object but 
you need an actual object in order to use it.

It seems like what you're talking about would be a kind of partial 
evaluation since you'd have a pointer to a subprogram that has one of 
its parameters already specified but the others not. I'm not saying 
that's a bad thing, I'm just trying to understand the ramifications.

Peter




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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 18:23     ` Adam Beneschan
  2012-11-19 20:57       ` Peter C. Chapin
@ 2012-11-19 21:26       ` Dmitry A. Kazakov
  2012-11-19 22:19         ` Adam Beneschan
  1 sibling, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-19 21:26 UTC (permalink / raw)


On Mon, 19 Nov 2012 10:23:13 -0800 (PST), Adam Beneschan wrote:

> This doesn't look at all like what I'm talking about, since &Example::f
> still refers to a method defined for the class Example but without
> reference to a particular object.  Something equivalent would be if you
> could say &object.f (or maybe &object.*p) and store the result of that in
> a pointer that could be called later.

What would you do for:

   type T is tagged ...
   procedure Foo (X, Y, Z : T) ;

Would the closure carry three objects with it?

If closures to be supported then they better be a bit more universal than
just one tagged object + one operation.

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



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 20:52 ` ake.ragnar.dahlgren
@ 2012-11-19 21:56   ` Dmitry A. Kazakov
  2012-11-22  9:49     ` ake.ragnar.dahlgren
  2012-11-19 22:13   ` sbelmont700
  1 sibling, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-19 21:56 UTC (permalink / raw)


On Mon, 19 Nov 2012 12:52:17 -0800 (PST), ake.ragnar.dahlgren@gmail.com
wrote:

> Also it is possible to see that the callbacks are declared in the
> Simple_Callbacks package. Note that the methods are not instance member
> methods.

GtkAda package Gtk.Handlers provides generic package User_Callback which
does all you need. It is the recommended way to pass additional parameters
to Gtk event handlers. GValue objects could be used to pass more than one
parameter etc.
 
> I hope I am wrong but it seems to me that since Ada lacks the ability to
> create pointers (maybe access types are the right words) to instance
> member methods, it is not possible to take advantage of Ada's OOP features
> when developing Glade3 applications.

I doubt that this would be useful with Gtk anyway. Closures would require
special treatment in order to marshal them to Gtk handlers. There is a
complex infrastructure in Gtk for dealing with closures. It is based on
plain pointers. If Ada provided fat pointers (access types) for
object+primitive operation closures these would be incompatible with Gtk
closures anyway. And you would get accessibility checks failed most of the
time. Closures themselves is a huge problem when refer to dynamic objects.
You should not pass any objects this way which are not reference-counted by
the means of gobject. If you do Ada objects you should really be sure that
the object is not destructed before handler is called.

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



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 20:52 ` ake.ragnar.dahlgren
  2012-11-19 21:56   ` Dmitry A. Kazakov
@ 2012-11-19 22:13   ` sbelmont700
  1 sibling, 0 replies; 47+ messages in thread
From: sbelmont700 @ 2012-11-19 22:13 UTC (permalink / raw)


On Monday, November 19, 2012 3:52:17 PM UTC-5, ake.ragna...@gmail.com wrote:
> I hope I am wrong but it seems to me that since Ada lacks the ability to create pointers (maybe access types are the right words) to instance member methods, it is not possible to take advantage of Ada's OOP features when developing Glade3 applications.
> 

The first problem is that "pointers to instance member methods" is a contridiction in terms; methods are *part* of an object, not some independent 'thing' that can ever exist or be executed otherwise.  Given an object, you access it's subprograms, not the other way around.  It's even stated in the LRM: "Note that using an access-to-class-wide tagged type with a dispatching operation is a potentially more structured alternative to using an access-to-subprogram type."  IMHO, the offending programs should be redesigned, not kludges added to the language.

The second problem is that GTK is a C-based, procedural API.  It was kind-of/sort-of "OOP-ized" for Gtk-Ada, but there are many parts that are still very procedural and reek of C.  The fact that you are registering callback procedures (instead of objects) is a dead giveaway that you are not dealing strictly with OOP.

-sb



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 21:26       ` Dmitry A. Kazakov
@ 2012-11-19 22:19         ` Adam Beneschan
  2012-11-20 10:12           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Adam Beneschan @ 2012-11-19 22:19 UTC (permalink / raw)


On Monday, November 19, 2012 1:26:58 PM UTC-8, Dmitry A. Kazakov wrote:
> On Mon, 19 Nov 2012 10:23:13 -0800 (PST), Adam Beneschan wrote:
> 
> 
> 
> > This doesn't look at all like what I'm talking about, since &Example::f
> > still refers to a method defined for the class Example but without
> > reference to a particular object.  Something equivalent would be if you
> > could say &object.f (or maybe &object.*p) and store the result of that in
> > a pointer that could be called later.
> 
> What would you do for:
> 
>    type T is tagged ...
> 
>    procedure Foo (X, Y, Z : T) ;
> 
> Would the closure carry three objects with it?

What I'm proposing is a way that one could say something like

   Object.Operation'access

In Ada, with regard to your procedure Foo, you can say

   X.Foo (Y, Z)

That's just the way the language is.  The Object.Operation notation doesn't treat the three parameters as having equivalent importance.  If you don't like this when using Foo, then don't use that feature, and you probably wouldn't want to use something like X.Foo'access.  And it probably shouldn't be used on a procedure like that.  But it might help with the case that I think is a lot more common, where a procedure or function *is* considered to operate primarily on one tagged object more than others.


> If closures to be supported then they better be a bit more universal than 
> just one tagged object + one operation.

Why?  Is there a rule that says that if a proposed change doesn't fix the entire world, then we shouldn't propose something that improves part of the world?  I was trying to suggest something that **might** be worthwhile by making certain things easier---I don't know for sure that it's worthwhile, but the fact that someone decided to add this to C# and that someone here asked about it makes me think it **could** be worthwhile---but in any case, I was **not** attempting to try to elevate Ada to Programming Language Nirvana Perfection.  So suppose it would help in a lot of cases but not help in all cases.  So what?

                                -- Adam



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
                   ` (5 preceding siblings ...)
  2012-11-19 20:52 ` ake.ragnar.dahlgren
@ 2012-11-19 23:59 ` Randy Brukardt
  2012-11-20  0:05   ` Randy Brukardt
                     ` (2 more replies)
  2012-11-22  9:47 ` ake.ragnar.dahlgren
  7 siblings, 3 replies; 47+ messages in thread
From: Randy Brukardt @ 2012-11-19 23:59 UTC (permalink / raw)


<ake.ragnar.dahlgren@gmail.com> wrote in message 
news:9b0bcb37-8ae3-440f-af4f-a796702e4250@googlegroups.com...
>Not sure if this has already been discussed but: Is it possible to define a 
>pointer to
> a member procedure of an instance?
>
>This problem has it's origin in the implementation of the MVC pattern for a 
>GtkAda application.
>Consider the following:
>
>package Some_Package is
>
>   type Message_Type is tagged null record;
>
>   procedure Print(Message : Message_Type);
>
>end Some_Package;
>
>package body Some_Package is
>
>   procedure Print (Message : Message_Type) is
>   begin
>      null;
>   end Print;
>
>end Some_Package;
>
>Then it is possible to create the following Main application that compiles 
>just fine:
>
>with Some_Package;
>procedure Main is
>   Message : Some_Package.Message_Type;
>begin
>   Message.Print;
>end Main;
>
>Is it possible to create a parameterless access type to the Message.Print 
>procedure?
>The following application refuses to compile:
>
>with Some_Package;
>procedure Main is
>   Message : Some_Package.Message_Type;
>
>   Method_Ref : access procedure := Message.Print'Access;
>begin
>   Method_Ref;
>end Main;
>
>The error message is: no selector "Print" for type "Message_Type" defined 
>at some_package.ads:3

I think this should work; if it doesn't, the error has something to do with 
conventions. So there is probably a compiler bug here.

The "name" (Ada synax terminology) "Message.Print" represents a 
parameterless procedure, and can be used in the same way as other 
parameterless procedures. In particular, it can be renamed as a 
parameterless procedure:

    procedure P renames Message.Print;

I'm not certain what the convention of this procedure is (it might be 
defined to be "intrinsic" somewhere, in which case you couldn't take 'Access 
to it, I can't find such a rule on a quick check of the RM). But it surely 
exists and should not report that "selector "Print" doesn't exist.

In any case, our intent is that one could use this just like any other 
procedure with the same profile. You can rename it, pass it as a formal 
subprogram, call it of course, etc. So I would expect 'Access to work as 
well, unless the RM explicitly says it does not.

                                                 Randy.

P.S. I don't know what everyone else is talking about here; it's *obvious* 
;-) that this should work in Ada and all other programming languages with 
similar constructs. (Please make careful note of the smiley here.)






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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 23:59 ` Randy Brukardt
@ 2012-11-20  0:05   ` Randy Brukardt
  2012-11-20  1:00     ` Adam Beneschan
  2012-11-20  0:52   ` Adam Beneschan
  2012-11-20 11:28   ` Brian Drummond
  2 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2012-11-20  0:05 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> wrote in message 
news:k8eh4g$bs8$1@munin.nbi.dk...
...
> In any case, our intent is that one could use this just like any other 
> procedure with the same profile. You can rename it, pass it as a formal 
> subprogram, call it of course, etc. So I would expect 'Access to work as 
> well, unless the RM explicitly says it does not.

I should point out that I don't think that the code you wrote actually would 
solve the problem you were trying to solve. That's because you usually need 
to make dispatching calls, and such a call would be bound to a subprogram 
when you wrote the name "Message.Print" and not when you actually made the 
call.

But I think the code you wrote is legal and you just have a compiler bug 
that is giving you the error that you reported. (Either that, or there is a 
different problem that should be reported.)

                                              Randy.





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 23:59 ` Randy Brukardt
  2012-11-20  0:05   ` Randy Brukardt
@ 2012-11-20  0:52   ` Adam Beneschan
  2012-11-20 21:34     ` Randy Brukardt
  2012-11-20 11:28   ` Brian Drummond
  2 siblings, 1 reply; 47+ messages in thread
From: Adam Beneschan @ 2012-11-20  0:52 UTC (permalink / raw)


On Monday, November 19, 2012 3:59:14 PM UTC-8, Randy Brukardt wrote:

> >with Some_Package;
> 
> >procedure Main is
> >   Message : Some_Package.Message_Type;
> >begin
> >   Message.Print;
> >end Main;
> 
> >
> 
> >Is it possible to create a parameterless access type to the Message.Print 
> 
> >procedure?
> 
> >The following application refuses to compile:
> 
> >with Some_Package;
> >procedure Main is
> >   Message : Some_Package.Message_Type;
> >   Method_Ref : access procedure := Message.Print'Access;
> >begin
> >   Method_Ref;
> >end Main;
> 
> >The error message is: no selector "Print" for type "Message_Type" defined 
> >at some_package.ads:3

> I think this should work; if it doesn't, the error has something to do with 
> conventions. So there is probably a compiler bug here....

> I'm not certain what the convention of this procedure is (it might be 
> defined to be "intrinsic" somewhere, in which case you couldn't take 'Access 
> to it, I can't find such a rule on a quick check of the RM). 

6.3.1(4): The Intrinsic calling convention represents subprograms that are “built in” to the compiler. The default calling convention is Intrinsic for the following: ...

6.3.1(10.1/2) any prefixed view of a subprogram (see 4.1.3).

The AARM gives the reason immediately following:
 
Reason: The profile of a prefixed view is different than the “real” profile of the subprogram (it doesn't have the first parameter), so we don't want to be able to take 'Access of it, as that would require generating a wrapper of some sort. 

> But it surely 
> exists and should not report that "selector "Print" doesn't exist.

Yep, the error message appears to be wrong, but I can sort of understand it.  If the compiler knows that a prefixed view wouldn't be allowed here (as a prefix to 'Access), then since it has to do name resolution (in case Print is overloaded), it might be using a different search routine than it would use if it were processing a procedure call.  Or something like that.  


> In any case, our intent is that one could use this just like any other  
> procedure with the same profile. You can rename it, pass it as a formal 
> subprogram, call it of course, etc. So I would expect 'Access to work as 
> well, unless the RM explicitly says it does not.

I think the necessity of generating a wrapper, possibly a separate wrapper for every appearance of this kind of 'Access, is why the language designers decided not to allow it.  See AI95-252.  It's also why I was suggesting adding a new kind of access type, rather than changing the language to simply allow 'Access.

                            -- Adam



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20  0:05   ` Randy Brukardt
@ 2012-11-20  1:00     ` Adam Beneschan
  2012-11-20 21:38       ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Adam Beneschan @ 2012-11-20  1:00 UTC (permalink / raw)


On Monday, November 19, 2012 4:05:16 PM UTC-8, Randy Brukardt wrote:
> "Randy Brukardt" wrote in message 

> I should point out that I don't think that the code you wrote actually would 
> solve the problem you were trying to solve. That's because you usually need 
> to make dispatching calls, and such a call would be bound to a subprogram 
> when you wrote the name "Message.Print" and not when you actually made the 
> call.

If Message had type Message_Type'Class, I'd assume that at some point, Message.Print'Access would need to determine which Print subprogram would be called, and figure out the address of it.  I don't think it matters whether it's done when the 'Access value is computed or when the call is made, since the tag of an object can't be changed during the object's lifetime.  I could be wrong, though; maybe I've missed a case where it matters.  (But I'm not concerned about the possibility of an object's tag being changed through extralegal means like Unchecked_Conversion.)

                           -- Adam



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 22:19         ` Adam Beneschan
@ 2012-11-20 10:12           ` Dmitry A. Kazakov
  2012-11-20 21:51             ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-20 10:12 UTC (permalink / raw)


On Mon, 19 Nov 2012 14:19:46 -0800 (PST), Adam Beneschan wrote:

> On Monday, November 19, 2012 1:26:58 PM UTC-8, Dmitry A. Kazakov wrote:
>> On Mon, 19 Nov 2012 10:23:13 -0800 (PST), Adam Beneschan wrote:
>> 
>>> This doesn't look at all like what I'm talking about, since &Example::f
>>> still refers to a method defined for the class Example but without
>>> reference to a particular object.  Something equivalent would be if you
>>> could say &object.f (or maybe &object.*p) and store the result of that in
>>> a pointer that could be called later.
>> 
>> What would you do for:
>> 
>>    type T is tagged ...
>> 
>>    procedure Foo (X, Y, Z : T) ;
>> 
>> Would the closure carry three objects with it?
> 
> What I'm proposing is a way that one could say something like
> 
>    Object.Operation'access
> 
> In Ada, with regard to your procedure Foo, you can say
> 
>    X.Foo (Y, Z)
> 
> That's just the way the language is.

Two wrongs does not make one right.

>> If closures to be supported then they better be a bit more universal than 
>> just one tagged object + one operation.
> 
> Why?  Is there a rule that says that if a proposed change doesn't fix the
> entire world, then we shouldn't propose something that improves part of
> the world?

No idea. It is a great mystery to me what makes into the language and what
does not. Considering this one:

1. Why closures at all?

2. Why some arguments are more important than others, unless the programmer
specifies so?

3. Why closures must support only tagged types?

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



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 17:02   ` Peter C. Chapin
  2012-11-19 18:23     ` Adam Beneschan
@ 2012-11-20 10:59     ` Brian Drummond
  1 sibling, 0 replies; 47+ messages in thread
From: Brian Drummond @ 2012-11-20 10:59 UTC (permalink / raw)


On Mon, 19 Nov 2012 12:02:27 -0500, Peter C. Chapin wrote:

> FWIW C++ does have a "pointer to member" feature. It looks like this
> 
> class Example {
> public:
>    void f( int );
> };
> 
> // Declare p to be "pointer to member function of Example...
> // Initialize p to point at Example::f.
> void (Example::*p)( int ) = &Example::f;
> 
> Example object;  // Create an object.
> object.*p(42);   // Invoke member f indirectly on 'object'

This is practically identical to the Ada version in the "yes" part of my 
answer. It works by explicitly supplying "object" as the first parameter.

Unfortunately I don't think it's what the OP was really asking for...

- Brian



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 20:22 ` ake.ragnar.dahlgren
@ 2012-11-20 11:16   ` Brian Drummond
  0 siblings, 0 replies; 47+ messages in thread
From: Brian Drummond @ 2012-11-20 11:16 UTC (permalink / raw)


On Mon, 19 Nov 2012 12:22:21 -0800, ake.ragnar.dahlgren wrote:

> On Monday, November 19, 2012 10:59:42 AM UTC+1, ake.ragna...@gmail.com
> wrote:

>> This problem has it's origin in the implementation of the MVC pattern
>> for a GtkAda application. Consider the following:
...
> Additional information if needed: The spec. of the Register_Handler
> procedure in the Gtkada.Builder package is declared as:
> 
> procedure Register_Handler
>   (Builder      : access Gtkada_Builder_Record'Class;
>    Handler_Name : String;
>    Handler      : Builder_Handler);

Okay, this is looking familiar...

A previous post of mine linked at the bottom of the ada.dk tutorial 
contains the comment :

-- Having only Gtkada_Builder_Record'Class and GObject_Record'Class
-- seems restrictive. I failed to find any way to register and use 
-- the following:
--    procedure Destroy(Object : access Gtk_Widget_Record'Class);
-- eventually resorting to Gtk.Builder.Get_Widget in the procedure body.
-- I must be missing something here...

To expand on that; clearly everything is a subclass of GObject_Record, 
and therefore the intent must be that anything more complex like your 
On_Quit example be registered as an Object_Handler not a Builder_Handler.

--   type Builder_Handler is access procedure
--     (Builder : access Gtkada_Builder_Record'Class);
--   type Object_Handler is access procedure
--     (User_Data : access GObject_Record'Class);

The remaining question would be ... how?

It might be worth putting your On_Quit handler into the tutorial example, 
and asking "How do I register this as an Object_Handler?" on the GtkAda 
mailing list.

- Brian






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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 23:59 ` Randy Brukardt
  2012-11-20  0:05   ` Randy Brukardt
  2012-11-20  0:52   ` Adam Beneschan
@ 2012-11-20 11:28   ` Brian Drummond
  2012-11-20 14:27     ` Georg Bauhaus
  2012-11-20 15:52     ` Adam Beneschan
  2 siblings, 2 replies; 47+ messages in thread
From: Brian Drummond @ 2012-11-20 11:28 UTC (permalink / raw)


On Mon, 19 Nov 2012 17:59:06 -0600, Randy Brukardt wrote:

> The "name" (Ada synax terminology) "Message.Print" represents a
> parameterless procedure, and can be used in the same way as other
> parameterless procedures. In particular, it can be renamed as a
> parameterless procedure:
> 
>     procedure P renames Message.Print;
...
procedure Main is
   Message : Some_Package.Message_Type;

   procedure P renames Message.Print;
begin
   Message.Print;
   P;
end Main;
...
./main
Hello
Hello

Damn that's nice!
Where's the upvote button on this thing?

-Brian



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 11:39 ` Brian Drummond
@ 2012-11-20 11:43   ` Brian Drummond
  2012-11-20 21:57     ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Brian Drummond @ 2012-11-20 11:43 UTC (permalink / raw)


On Mon, 19 Nov 2012 11:39:03 +0000, Brian Drummond wrote:

> On Mon, 19 Nov 2012 01:59:42 -0800, ake.ragnar.dahlgren wrote:
> 
>> Not sure if this has already been discussed but: Is it possible to
>> define a pointer to a member procedure of an instance?
> 
> Yes.

>> Is it possible to create a parameterless access type to the
>> Message.Print procedure? The following application refuses to compile:
> 
> Message.Print is not parameterless, it is identical to Print(Message)
> so ... no.

Okay. I am astonished!
But I am more than happy to withdraw the above "no".

- Brian

--------------------------------------------------------
with Some_Package;

procedure Main is
   Message : Some_Package.Message_Type;

   procedure P renames Message.Print;

   Method_Ref : access procedure := P'access;

begin
   Message.Print;
   P;
   Method_Ref.all;
end Main;
--------------------------------------------------------

./main
Hello
Hello
Hello

And just for completeness...
--------------------------------------------------------
package Some_Package is

   type Message_Type is tagged null record;
   
   procedure Print(Message : Message_Type);

end Some_Package;
--------------------------------------------------------
with Ada.Text_IO;

package body Some_Package is

   procedure Print (Message : Message_Type) is begin
      Ada.Text_IO.Put_Line("Hello");
   end Print;

end Some_Package;
--------------------------------------------------------




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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20 11:28   ` Brian Drummond
@ 2012-11-20 14:27     ` Georg Bauhaus
  2012-11-20 15:52     ` Adam Beneschan
  1 sibling, 0 replies; 47+ messages in thread
From: Georg Bauhaus @ 2012-11-20 14:27 UTC (permalink / raw)


On 20.11.12 12:28, Brian Drummond wrote:

> procedure Main is
>    Message : Some_Package.Message_Type;
> 
>    procedure P renames Message.Print;
> begin
>    Message.Print;
>    P;
> end Main;
> ...
> ./main
> Hello
> Hello
> 
> Damn that's nice!
> Where's the upvote button on this thing?

IMHO, the Ada Wikibook is in need of a chapter on the value of names,
and opportunities for (re)naming. (X renames Some_Ptr.all also has
some fans, I think.)

The Ada reddit allows upvoting, once there is a link to, or reddit
post about, the desired topic.




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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20 11:28   ` Brian Drummond
  2012-11-20 14:27     ` Georg Bauhaus
@ 2012-11-20 15:52     ` Adam Beneschan
  1 sibling, 0 replies; 47+ messages in thread
From: Adam Beneschan @ 2012-11-20 15:52 UTC (permalink / raw)


On Tuesday, November 20, 2012 3:28:07 AM UTC-8, Brian Drummond wrote:
> On Mon, 19 Nov 2012 17:59:06 -0600, Randy Brukardt wrote:
> 
> > The "name" (Ada synax terminology) "Message.Print" represents a
> > parameterless procedure, and can be used in the same way as other
> > parameterless procedures. In particular, it can be renamed as a
> > parameterless procedure:
> 
> >     procedure P renames Message.Print;
> 
> ...
> 
> procedure Main is
>    Message : Some_Package.Message_Type; 
>    procedure P renames Message.Print;
> begin
>    Message.Print;
>    P;
> end Main;
> 
> ...
> ./main
> Hello
> Hello
> 
> Damn that's nice!
> 
> Where's the upvote button on this thing?

Fortunately, we don't have one.

By the way, you cannot rename Message.Print with a "renaming-as-body".

                               -- Adam



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20  0:52   ` Adam Beneschan
@ 2012-11-20 21:34     ` Randy Brukardt
  0 siblings, 0 replies; 47+ messages in thread
From: Randy Brukardt @ 2012-11-20 21:34 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1374 bytes --]

"Adam Beneschan" <adam@irvine.com> wrote in message 
news:adc832ae-94f1-43eb-b119-be9767888a19@googlegroups.com...
...
>> I'm not certain what the convention of this procedure is (it might be
>> defined to be "intrinsic" somewhere, in which case you couldn't take 
>> 'Access
>> to it, I can't find such a rule on a quick check of the RM).
>
>6.3.1(4): The Intrinsic calling convention represents subprograms that are 
>�built in�
>to the compiler. The default calling convention is Intrinsic for the 
>following: ...
>
>6.3.1(10.1/2) any prefixed view of a subprogram (see 4.1.3).

Thanks. I looked for that, but couldn't find it.

...
>> But it surely
>> exists and should not report that "selector "Print" doesn't exist.
>
>Yep, the error message appears to be wrong, but I can sort of understand 
>it.  If the
>compiler knows that a prefixed view wouldn't be allowed here (as a prefix 
>to 'Access),
>then since it has to do name resolution (in case Print is overloaded), it 
>might be using a
>different search routine than it would use if it were processing a 
>procedure call.  Or
>something like that.

I can "understand" how the message came about, but that's unlikely to help 
the poor programmer who can't figure out the problem. Or even the harried 
language-lawyer who is certain that the prefix is legal... :-)

                                 Randy.





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20  1:00     ` Adam Beneschan
@ 2012-11-20 21:38       ` Randy Brukardt
  2012-11-20 23:43         ` Adam Beneschan
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2012-11-20 21:38 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:114a6fcf-32c3-408f-961f-2e3bf3c5af04@googlegroups.com...
On Monday, November 19, 2012 4:05:16 PM UTC-8, Randy Brukardt wrote:
>> "Randy Brukardt" wrote in message

>> I should point out that I don't think that the code you wrote actually 
>> would
>> solve the problem you were trying to solve. That's because you usually 
>> need
>> to make dispatching calls, and such a call would be bound to a subprogram
>> when you wrote the name "Message.Print" and not when you actually made 
>> the
>> call.

>If Message had type Message_Type'Class, I'd assume that at some point,
>Message.Print'Access would need to determine which Print subprogram would 
>be
>called, and figure out the address of it.  I don't think it matters whether 
>it's done when the
>'Access value is computed or when the call is made, since the tag of an 
>object can't be
>changed during the object's lifetime.  I could be wrong, though; maybe I've 
>missed a case
>where it matters.  (But I'm not concerned about the possibility of an 
>object's tag being
>changed through extralegal means like Unchecked_Conversion.)

I don't think this is quite true; if the object is a parameter (for 
instance), it can have different tags for different calls. But I don't see 
that happening for something like Param.Print'Access -- access values are 
never dispatching.

Anyway, since something like Param.Print'Access is illegal in any case, we 
don't have to decide what this means or how code would be generated for it.

                                                   Randy.


                           -- Adam 





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20 10:12           ` Dmitry A. Kazakov
@ 2012-11-20 21:51             ` Randy Brukardt
  2012-11-21  8:24               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2012-11-20 21:51 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:1ilx4ms9xk5h8.pz5jsnqrogye.dlg@40tude.net...
...
>No idea. It is a great mystery to me what makes into the language and what
>does not. Considering this one:

Obviously, you can read the AIs and the meeting minutes to find out why 
things were done the way they are. That's one reason that the associated AIs 
are linked in the AARM for every changed paragraph.

> 1. Why closures at all?

I assume we're talking about Ada's "prefixed views" (closures are something 
else to me). A combination of popular demand and the fact that Ada 83 
already had them for tasks.

> 2. Why some arguments are more important than others, unless the 
> programmer
> specifies so?

No good reason, IMHO, other than that that was the way it worked for tasks 
in Ada 83.

> 3. Why closures must support only tagged types?

We tried to allow prefixed views for all types, but we ran into problems 
because Ada always allows an implicit conversion at a dot, and we didn't 
want these to be different. In the end, we decided on restricting it to just 
tagged types because the rules worked well with them. Almost all new types 
ought to be tagged (and controlled) anyway [yes, I realize that some 
language rules don't allow that in some cases - grumble].

One advantage of restricting prefixed views to tagged types is that it 
leaves the door open for future extensions to other kinds of types. If we 
allowed it on other kinds of types and got it wrong, we'd be stuck with it 
forever (compatibility concerns would not allow us to change the meaning in 
the future). And we certainly were not sure how the rules should work for 
untagged types. So this is a case where doing nothing was better than doing 
something we were not sure about.

                                                  Randy.





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20 11:43   ` Brian Drummond
@ 2012-11-20 21:57     ` Randy Brukardt
  0 siblings, 0 replies; 47+ messages in thread
From: Randy Brukardt @ 2012-11-20 21:57 UTC (permalink / raw)


"Brian Drummond" <brian@shapes.demon.co.uk> wrote in message 
news:k8fqd7$1hv$4@dont-email.me...
> On Mon, 19 Nov 2012 11:39:03 +0000, Brian Drummond wrote:
>> On Mon, 19 Nov 2012 01:59:42 -0800, ake.ragnar.dahlgren wrote:
...
>>> Is it possible to create a parameterless access type to the
>>> Message.Print procedure? The following application refuses to compile:
>>
>> Message.Print is not parameterless, it is identical to Print(Message)
>> so ... no.
>
> Okay. I am astonished!
> But I am more than happy to withdraw the above "no".

I'm astonished, too. Unfortunately, I think this is depending on a compiler 
bug. (One that I'd encourage them to keep :-).

Ada says that the properties of a renaming are the same as the renamed 
entity. Since the renamed entity in this case has convention Intrinsic, the 
renaming also should have convention Intrinsic (and thus the 'Access still 
should be illegal).

Probably what's happening here is that the compiler is generating a wrapper 
to implement this rename, and it is allowing 'Access to be taken of this 
wrapper, because there is no implementation reason not to. But I don't think 
it should be allowed in language terms.

                                    Randy.





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20 21:38       ` Randy Brukardt
@ 2012-11-20 23:43         ` Adam Beneschan
  2012-11-21 22:12           ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Adam Beneschan @ 2012-11-20 23:43 UTC (permalink / raw)


On Tuesday, November 20, 2012 1:38:38 PM UTC-8, Randy Brukardt wrote:
> "Adam Beneschan" wrote in message 
> 
> >If Message had type Message_Type'Class, I'd assume that at some point,
> >Message.Print'Access would need to determine which Print subprogram would 
> >be
> >called, and figure out the address of it.  I don't think it matters whether 
> >it's done when the
> >'Access value is computed or when the call is made, since the tag of an 
> >object can't be
> >changed during the object's lifetime.  I could be wrong, though; maybe I've 
> >missed a case
> >where it matters.  (But I'm not concerned about the possibility of an 
> >object's tag being
> >changed through extralegal means like Unchecked_Conversion.)
> 
> I don't think this is quite true; if the object is a parameter (for 
> instance), it can have different tags for different calls. But I don't see 
> that happening for something like Param.Print'Access -- access values are 
> never dispatching.
> 
> Anyway, since something like Param.Print'Access is illegal in any case, we 
> don't have to decide what this means or how code would be generated for it.

I probably confused things.  Yes, Param.Print'Access is illegal, but I was thinking in terms of "what if" we added a language feature to make it legal--probably by adding a new kind of access type that contained references both to the prefix object and, somehow, to the subprogram.  In that case, I'd want it to be dispatching, if Param's type were classwide.

This would mean that if Param's type were classwide, the actual subprogram referred to by the access value would be determined at runtime, not at compile time.  And I don't think it would matter *when* the subprogram address to which the program will dispatch were actually determined, i.e. when the statement containing the 'Access were executed, or when the access value was dereferenced in order to call the subprogram, since the object's tag shouldn't change in between those times.

But I guess I didn't make it clear that all this was ***if*** we decided to add a new capability to the language and if we did it the way I envision.  Sorry about that.  Hope this helps clear things up.

                                -- Adam




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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20 21:51             ` Randy Brukardt
@ 2012-11-21  8:24               ` Dmitry A. Kazakov
  2012-11-21 22:19                 ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-21  8:24 UTC (permalink / raw)


On Tue, 20 Nov 2012 15:51:41 -0600, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:1ilx4ms9xk5h8.pz5jsnqrogye.dlg@40tude.net...
> ...
>>No idea. It is a great mystery to me what makes into the language and what
>>does not. Considering this one:
> 
> Obviously, you can read the AIs and the meeting minutes to find out why 
> things were done the way they are.

These do not explain the decisions made. It is people who support some AIs
and do not support others.

>> 1. Why closures at all?
> 
> I assume we're talking about Ada's "prefixed views" (closures are something 
> else to me).

I meant member pointers here, which are a form of a closure. I don't see
strong case for these. The standard OO model that passes a proper object[s]
and then calls to an operation of a statically known name, maybe,
dispatching is the way to do things. Functional programming mess, please.

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



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-20 23:43         ` Adam Beneschan
@ 2012-11-21 22:12           ` Randy Brukardt
  2012-11-22  1:59             ` Adam Beneschan
  0 siblings, 1 reply; 47+ messages in thread
From: Randy Brukardt @ 2012-11-21 22:12 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:87af1bfd-41d2-45c7-953a-c1954d4f5ceb@googlegroups.com...
>On Tuesday, November 20, 2012 1:38:38 PM UTC-8, Randy Brukardt wrote:
>> "Adam Beneschan" wrote in message
>>
>> >If Message had type Message_Type'Class, I'd assume that at some point,
>> >Message.Print'Access would need to determine which Print subprogram 
>> >would
>> >be
>> >called, and figure out the address of it.  I don't think it matters 
>> >whether
>> >it's done when the
>> >'Access value is computed or when the call is made, since the tag of an
>> >object can't be
>> >changed during the object's lifetime.  I could be wrong, though; maybe 
>> >I've
>> >missed a case
>> >where it matters.  (But I'm not concerned about the possibility of an
>> >object's tag being
>> >changed through extralegal means like Unchecked_Conversion.)
>>
>> I don't think this is quite true; if the object is a parameter (for
>> instance), it can have different tags for different calls. But I don't 
>> see
>> that happening for something like Param.Print'Access -- access values are
>> never dispatching.
>>
>> Anyway, since something like Param.Print'Access is illegal in any case, 
>> we
>> don't have to decide what this means or how code would be generated for 
>> it.
>
>I probably confused things.  Yes, Param.Print'Access is illegal, but I was
>thinking in terms of "what if" we added a language feature to make it 
>legal--probably
>by adding a new kind of access type that contained references both to the 
>prefix
>object and, somehow, to the subprogram.  In that case, I'd want it to be
>dispatching, if Param's type were classwide.

*IF* we made it legal, we'd simply change the convention to Ada. There is no 
reason for the complication of a new kind of access type, because creating a 
wrapper is simple. Moreover, both Ada 2005 and Ada 2012 require creating 
wrappers in certain circumstances, so it's not like this is something a 
compiler never has done before. (And there are at least 4 other places where 
Janus/Ada uses wrappers, it's just not a big deal. And one of them is for 
'Access when the  subprogram was declared inside a generic while the access 
type was not.)

Note that GNAT is apparently using a wrapper to implement the renames of a 
prefixed view (and mistakenly allowing 'Access to be taken of the result). 
Doing exactly that for 'Access is not likely to be a big deal.

Whether or not that wrapper ought to dispatch is a separate issue and 
probably doesn't really make any difference to how the 'Access is supported.

                                                        Randy.





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-21  8:24               ` Dmitry A. Kazakov
@ 2012-11-21 22:19                 ` Randy Brukardt
  0 siblings, 0 replies; 47+ messages in thread
From: Randy Brukardt @ 2012-11-21 22:19 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:4ayu88ck8dkd.1qcy3gnnf7ove.dlg@40tude.net...
> On Tue, 20 Nov 2012 15:51:41 -0600, Randy Brukardt wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:1ilx4ms9xk5h8.pz5jsnqrogye.dlg@40tude.net...
>> ...
>>>No idea. It is a great mystery to me what makes into the language and 
>>>what
>>>does not. Considering this one:
>>
>> Obviously, you can read the AIs and the meeting minutes to find out why
>> things were done the way they are.
>
> These do not explain the decisions made. It is people who support some AIs
> and do not support others.

If that's true, then I'm doing a bad job taking notes. I try to record 
everything interesting that people say on a topic, and it is usually the 
case that people are asked to explain their positions on a topic. Obviously, 
not everyone who votes explains their opinion, but since close votes are 
considered failures, almost all of the reasoning should be explained.

There are some discussions that don't last long enough for reasons to be 
recorded, but those are almost always rote issues that were previously 
discussed (either at a meeting or via e-mail).

>>> 1. Why closures at all?
>>
>> I assume we're talking about Ada's "prefixed views" (closures are 
>> something
>> else to me).
>
> I meant member pointers here, which are a form of a closure. I don't see
> strong case for these. The standard OO model that passes a proper 
> object[s]
> and then calls to an operation of a statically known name, maybe,
> dispatching is the way to do things. Functional programming mess, please.

Unfortunately, I have no more idea what you mean by "member pointers" than 
you did by "closures". Ada doesn't have "members" or "pointers", and while 
the latter is rather pedantic, the former isn't (Ada has components and 
primitive operations and neither can really have pointers to them). So I'll 
let this pass with no comment...

                                        Randy.





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-21 22:12           ` Randy Brukardt
@ 2012-11-22  1:59             ` Adam Beneschan
  2012-11-29  2:43               ` Randy Brukardt
  0 siblings, 1 reply; 47+ messages in thread
From: Adam Beneschan @ 2012-11-22  1:59 UTC (permalink / raw)


On Wednesday, November 21, 2012 2:12:23 PM UTC-8, Randy Brukardt wrote:
> "Adam Beneschan" wrote in message 

> *IF* we made it legal, we'd simply change the convention to Ada. There is no 
> reason for the complication of a new kind of access type, because creating a 
> wrapper is simple. Moreover, both Ada 2005 and Ada 2012 require creating 
> wrappers in certain circumstances, so it's not like this is something a 
> compiler never has done before. 

Our compiler creates wrappers too.  I think that for a nested type extension, it has to create a wrapper for each inherited operation.  But that's only done once per operation per type.  I'm not thrilled with the idea of possibly generating a wrapper every time an 'Access occurs, which is what I think would be needed.  On the other hand, maybe in practice it wouldn't be a problem.  Maybe there wouldn't be that many occurrences of Obj.Operation'Access.  Anyway, it sounds like a space/time tradeoff.

It occurs to me that if you're right, we didn't need "access protected procedure/function" either, since that could also be implemented with wrappers, I think (there's a difference in that a dereference that calls a protected subprogram is a protected action, but I think the logic needed to make it a protected action could probably be stuck inside the wrapper.)

Anyway, it's all academic unless we actually decide it's worthwhile to make this change, and I'm not sure it is.  This was all pretty much musing about how it *might* work.

                              -- Adam



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
                   ` (6 preceding siblings ...)
  2012-11-19 23:59 ` Randy Brukardt
@ 2012-11-22  9:47 ` ake.ragnar.dahlgren
  2012-11-22 10:25   ` Dmitry A. Kazakov
  2012-11-22 12:13   ` Brian Drummond
  7 siblings, 2 replies; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-11-22  9:47 UTC (permalink / raw)


On Monday, November 19, 2012 10:59:42 AM UTC+1, ake.ragna...@gmail.com wrote:
> Not sure if this has already been discussed but: Is it possible to define a pointer to a member procedure of an instance? This problem has it's origin in the implementation of the MVC pattern for a GtkAda application. Consider the following: package Some_Package is type Message_Type is tagged null record; procedure Print(Message : Message_Type); end Some_Package; package body Some_Package is procedure Print (Message : Message_Type) is begin null; end Print; end Some_Package; Then it is possible to create the following Main application that compiles just fine: with Some_Package; procedure Main is Message : Some_Package.Message_Type; begin Message.Print; end Main; Is it possible to create a parameterless access type to the Message.Print procedure? The following application refuses to compile: with Some_Package; procedure Main is Message : Some_Package.Message_Type; Method_Ref : access procedure := Message.Print'Access; begin Method_Ref; end Main; The error message is: no selector "Print" for type "Message_Type" defined at some_package.ads:3 It is possible to create a workaround: with Some_Package; procedure Main is Message : Some_Package.Message_Type; procedure Method_Ref is begin Message.Print; end Method_Ref; begin Method_Ref; end Main; Is there a better way? Or is this the optimal way? Regards, Åke Ragnar Dahlgren

I want to thank everybody for replying. I had no idea about the "renames" feature as Randy pointed out. Brian expressed it very well: I am astonished!

As for the Gtkada application I have given up on implementing the MVC pattern using tagged types. Instead I choose the same approach as was done in the Ada in Denmark wiki.

Best regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-19 21:56   ` Dmitry A. Kazakov
@ 2012-11-22  9:49     ` ake.ragnar.dahlgren
  0 siblings, 0 replies; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-11-22  9:49 UTC (permalink / raw)
  Cc: mailbox

On Monday, November 19, 2012 10:56:10 PM UTC+1, Dmitry A. Kazakov wrote:
> On Mon, 19 Nov 2012 12:52:17 -0800 (PST), ake.ragnar.dahlgren@gmail.com wrote: > Also it is possible to see that the callbacks are declared in the > Simple_Callbacks package. Note that the methods are not instance member > methods. GtkAda package Gtk.Handlers provides generic package User_Callback which does all you need. It is the recommended way to pass additional parameters to Gtk event handlers. GValue objects could be used to pass more than one parameter etc. > I hope I am wrong but it seems to me that since Ada lacks the ability to > create pointers (maybe access types are the right words) to instance > member methods, it is not possible to take advantage of Ada's OOP features > when developing Glade3 applications. I doubt that this would be useful with Gtk anyway. Closures would require special treatment in order to marshal them to Gtk handlers. There is a complex infrastructure in Gtk for dealing with closures. It is based on plain pointers. If Ada provided fat pointers (access types) for object+primitive operation closures these would be incompatible with Gtk closures anyway. And you would get accessibility checks failed most of the time. Closures themselves is a huge problem when refer to dynamic objects. You should not pass any objects this way which are not reference-counted by the means of gobject. If you do Ada objects you should really be sure that the object is not destructed before handler is called. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de

I could not follow all the details of your explanation of closures. But I thank you. And you thank you for the guidelines on using Gtkada.

Best regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-22  9:47 ` ake.ragnar.dahlgren
@ 2012-11-22 10:25   ` Dmitry A. Kazakov
  2012-12-02 20:42     ` ake.ragnar.dahlgren
  2012-11-22 12:13   ` Brian Drummond
  1 sibling, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2012-11-22 10:25 UTC (permalink / raw)


On Thu, 22 Nov 2012 01:47:39 -0800 (PST), ake.ragnar.dahlgren@gmail.com
wrote:

> As for the Gtkada application I have given up on implementing the MVC
> pattern using tagged types.

Could you provide more details?

Gtk (and so GtkAda) deploys MVC. E.g. Gtk combo boxes, tree views, column
renderers are all using the MVC pattern.

> Instead I choose the same approach as was done
> in the Ada in Denmark wiki.

It is unclear what are the differences, but MVC is a real help when dealing
with Gtk and GUI in general. GtkAda should not pose any difficulties for
MVC. (You don't need pointers to members for MVC, plain pointers to objects
are sufficient)

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



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-22  9:47 ` ake.ragnar.dahlgren
  2012-11-22 10:25   ` Dmitry A. Kazakov
@ 2012-11-22 12:13   ` Brian Drummond
  2012-12-03 16:17     ` ake.ragnar.dahlgren
  1 sibling, 1 reply; 47+ messages in thread
From: Brian Drummond @ 2012-11-22 12:13 UTC (permalink / raw)


On Thu, 22 Nov 2012 01:47:39 -0800, ake.ragnar.dahlgren wrote:

> I want to thank everybody for replying. I had no idea about the
> "renames" feature as Randy pointed out. Brian expressed it very well: I
> am astonished!

But heed Randy's warning : 

(I may have been confused among the discussion and speculation, but my 
understanding is this: corrections welcome!)

the Renames is legal and intended to work as demonstrated:

taking its access is ILLEGAL and only works because of an apparent bug in 
Gnat (which I for one am NOT jumping to report!). And therefore using it 
is a BAD IDEA because it may well go away in the future (as well as not 
being portable)

It might be useful to see the reports from other compilers on the 
example...

> As for the Gtkada application I have given up on implementing the MVC
> pattern using tagged types. Instead I choose the same approach as was
> done in the Ada in Denmark wiki.

I believe that uses "tagged types" internally, but it is certainly 
easier...

See also "Gate3" available at
http://sourceforge.net/projects/lorenz/
which will auto-generate the Ada framework shown on that Ada.dk page,
from your Glade UI XML file.

- Brian





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-22  1:59             ` Adam Beneschan
@ 2012-11-29  2:43               ` Randy Brukardt
  0 siblings, 0 replies; 47+ messages in thread
From: Randy Brukardt @ 2012-11-29  2:43 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:7f09e5c5-f118-4431-a3c2-4abd2145dc14@googlegroups.com...
On Wednesday, November 21, 2012 2:12:23 PM UTC-8, Randy Brukardt wrote:
...
>It occurs to me that if you're right, we didn't need "access protected 
>procedure/function" either,
>since that could also be implemented with wrappers, I think (there's a 
>difference in that a
>dereference that calls a protected subprogram is a protected action, but I 
>think the logic
>needed to make it a protected action could probably be stuck inside the 
>wrapper.)

Right, there is no implementation need for access-to-protected. But there is 
a difference here: the semantics of a protected call is a bit different than 
the semantics of an unprotected call, and there are cases where you need to 
make that visible. So there is a semantic reason beyond the implementation 
reason for having them separate.

In any case, it's certainly true that Ada 83 and Ada 95 tried to avoid 
requiring wrappers in any circumstances (and that may be why we have 
access-to-protected -- I don't remember any discussions on that), but Ada 
2005 and especially Ada 2012 have given up on that and definitely require 
them in a lot of cases. So much of the reason for convention Intrinsic and 
the like is really OBE.

But do note that there are some cases where even a wrapper can't bail you 
out. The reason you can't in general take 'Access of a subprogram in a 
generic body is because a shared implementation can't make that work, even 
if wrappers are used. (To take one example.) So we can't just get rid of 
most of those rules without some thought. And then it's questionable whether 
it would be worth the effort.

                                Randy.





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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-22 10:25   ` Dmitry A. Kazakov
@ 2012-12-02 20:42     ` ake.ragnar.dahlgren
  2012-12-03 11:21       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-12-02 20:42 UTC (permalink / raw)
  Cc: mailbox

On Thursday, November 22, 2012 11:24:27 AM UTC+1, Dmitry A. Kazakov wrote:
> On Thu, 22 Nov 2012 01:47:39 -0800 (PST), ake.ragnar.dahlgren@gmail.com
> 
> wrote:
> 
> 
> 
> > As for the Gtkada application I have given up on implementing the MVC
> 
> > pattern using tagged types.
> 
> 
> 
> Could you provide more details?
> 
> 
> 
> Gtk (and so GtkAda) deploys MVC. E.g. Gtk combo boxes, tree views, column
> 
> renderers are all using the MVC pattern.
> 
> 
> 
> > Instead I choose the same approach as was done
> 
> > in the Ada in Denmark wiki.
> 
> 
> 
> It is unclear what are the differences, but MVC is a real help when dealing
> 
> with Gtk and GUI in general. GtkAda should not pose any difficulties for
> 
> MVC. (You don't need pointers to members for MVC, plain pointers to objects
> 
> are sufficient)
> 
> 
> 
> -- 
> 
> Regards,
> 
> Dmitry A. Kazakov
> 
> http://www.dmitry-kazakov.de

I gladly provide more details by giving an example of Ada code. The with statements have been omitted and the GUI described by the main_window.glade file is assumed to contain a Label called Main_Label and the window has a destroy signal called Main_Window_Quit:

procedure Main is
begin
   Application.Main;
end Main;


package Application is

   pragma Elaborate_Body;

   procedure Main;

end Application;



package body Application is

   Main_Window_Controller : Controllers.Main_Window.Controller_Ref_Type;
   Main_Window : Views.Main_Window.Main_Window_Ref_Type;

   procedure On_Main_Window_Quit(Object : access Gtkada.Builder.Gtkada_Builder_Record'Class)
                                 renames Main_Window_Controller.On_Quit;

   procedure Main is
   begin

      Main_Window_Controller := new Controllers.Main_Window.Controller_Type;
      Main_Window := Views.Main_Window.Create_Main_Window(Main_Window_Controller,
                                                          On_Main_Window_Quit'Access);
      Main_Window.Show;

      Gtk.Main.Main;
      -- Enter the main gtk loop.
   end Main;

begin
   Gtk.Main.Init;
end Application;


package Controllers.Main_Window is

   type Controller_Type is tagged private;
   type Controller_Ref_Type is access all Controller_Type;

   procedure On_Quit (This : Controller_Type;
                      Object : access Gtkada.Builder.Gtkada_Builder_Record'Class);

private

   type Controller_Type is new Ada.Finalization.Controlled with null record;

end Controllers.Main_Window;



package body Controllers.Main_Window is

   procedure On_Quit
     (This : Controller_Type;
      Object : access Gtkada.Builder.Gtkada_Builder_Record'Class)
   is
   begin
      GNAT.IO.Put_Line("Will exit the application!");
      Gtk.Main.Main_Quit;
   end On_Quit;

end Controllers.Main_Window;



package Views.Main_Window is

   type Main_Window_Type(<>) is tagged private;
   type Main_Window_Ref_Type is access Main_Window_Type;

   procedure Show(Main_Window : Main_Window_Type);

   function Create_Main_Window(Controller : Controllers.Main_Window.Controller_Ref_Type;
                               On_Quit : Gtkada.Builder.Builder_Handler)
                               return Main_Window_Ref_Type;

private
   type Main_Window_Type(Controller_Ref : Controllers.Main_Window.Controller_Ref_Type) is new Ada.Finalization.Controlled with record
      Builder    : Gtkada.Builder.Gtkada_Builder;
   end record;

   Label : Gtk.Label.Gtk_Label;
   -- Extracted widget from the xml file

   overriding procedure Initialize (Main_Window : in out Main_Window_Type);
   overriding procedure Finalize   (Object : in out Main_Window_Type);

end Views.Main_Window;



package body Views.Main_Window is

   procedure Show(Main_Window : Main_Window_Type) is
   begin
      --  Find our main window, then display it and all of its children.
      Gtk.Widget.Show_All (Main_Window.Builder.Get_Widget ("Main_Window"));
   end Show;

   overriding procedure Initialize (Main_Window : in out Main_Window_Type) is
      Error   : Glib.Error.GError;      
   begin
      --     Step 1: create a Builder and add the XML data,
      Gtkada.Builder.Gtk_New (Main_Window.Builder);
      Error := Main_Window.Builder.Add_From_File ("main_window.glade");
      if Error /= null then
         Ada.Text_IO.Put_Line ("Error : " & Glib.Error.Get_Message (Error));
         Glib.Error.Error_Free (Error);
         raise Constraint_Error;
      end if;

      -- Step 2: Extract all widgets the application wishes to update
      declare
         Widget : Gtk.Widget.Gtk_Widget;
         use type Gtk.Window.Gtk_Window;
      begin
         Widget := Main_Window.Builder.Get_Widget("Main_Label");
         if Widget /= null then
            Label := Gtk.Label.Gtk_Label(Widget);
            if Label /= null then
               Label.Set_Text("Managed to set text successfully!");
            else
               Ada.Text_IO.Put_Line("Could not convert widget to Label");
            end if;
         else
            Ada.Text_IO.Put_Line("Widget not found!");
         end if;
      end;
   end Initialize;

   function Create_Main_Window(Controller : Controllers.Main_Window.Controller_Ref_Type;
                               On_Quit : Gtkada.Builder.Builder_Handler) return Main_Window_Ref_Type
   is
      Main_Window : Main_Window_Ref_Type := new Main_Window_Type(Controller);
   begin
      Gtkada.Builder.Register_Handler
        (Builder      => Main_Window.Builder,
         Handler_Name => "Main_Window_Quit",
         Handler      =>  On_Quit);

      -- Step 3: Call Do_Connect once to connect all registered handlers
      Main_Window.Builder.Do_Connect;

      return Main_Window;
   end Create_Main_Window;

   overriding procedure Finalize   (Object : in out Main_Window_Type) is
   begin
      Object.Builder.Unref;
   end Finalize;

end Views.Main_Window;


What I am trying to achieve is something like can be read in the Application.Main procedure. And to be able to do that I've used the forbidden renames feature of the GNAT compiler (as Brian and Randy has pointed out):
   procedure On_Main_Window_Quit(Object : access Gtkada.Builder.Gtkada_Builder_Record'Class)
                                 renames Main_Window_Controller.On_Quit;

I hope it has been interesting reading these thoughts on Gtkada development.

Best regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-12-02 20:42     ` ake.ragnar.dahlgren
@ 2012-12-03 11:21       ` Dmitry A. Kazakov
  2012-12-03 20:21         ` ake.ragnar.dahlgren
  0 siblings, 1 reply; 47+ messages in thread
From: Dmitry A. Kazakov @ 2012-12-03 11:21 UTC (permalink / raw)


On Sun, 2 Dec 2012 12:42:27 -0800 (PST), ake.ragnar.dahlgren@gmail.com
wrote:

> I gladly provide more details by giving an example of Ada code. The with
> statements have been omitted and the GUI described by the
> main_window.glade file is assumed to contain a Label called Main_Label and
> the window has a destroy signal called Main_Window_Quit:

1. I cannot comment on Glade, I don't use it.

2. What is the problem?

Why handling Quit signal requires MVC, especially, because there is no such
signal, AFAIK?

3. Is it about exiting GTK main loop? That does not need MVC at all.

In order to quit Gtk.Main.Main you have to call Gtk.Main.Quit. This is made
from a handler of the "destroy" event of Gtk_Object_Record, which is called
when a Gtk object is about to be destroyed. The object here is the main
window. That is it.

In order to initiate destruction of the main window otherwise than by means
of the window manager, the window manager does that when you press the
button [x] on window title, you should call the Destroy operation of
Gtk_Object_Record. The main window is Gtk_Window_Record, a descendant of.

Here is a minimal working sample of such application with a button to close
it:

----------------- simple.adb -----------------------------
with Gtk.Object;  use Gtk.Object;
with Gtk.Button;  use Gtk.Button;
with Gtk.Window;  use Gtk.Window;
with Gtk.Widget;  use Gtk.Widget;
with Gtk.Table;   use Gtk.Table;

with Gtk.Handlers;
with Gtk.Main;

procedure Simple is

   package No_Data_Handlers is -- Event handlers with no user parameters
      new Gtk.Handlers.Callback (Gtk_Widget_Record);
   package Killer_Handlers is -- Handlers that take Gtk_Object
      new Gtk.Handlers.User_Callback (Gtk_Widget_Record, Gtk_Object);

   procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
   begin
     Gtk.Main.Main_Quit; -- Exit the message loop, we are done
   end Destroy;

   procedure Clicked
             (  Widget : access Gtk_Widget_Record'Class;
                Object : Gtk_Object
             )  is
   begin
      Destroy (Object); -- Kill the object passed
   end Clicked;

   Window : Gtk_Window;
   Grid   : Gtk_Table;
   Button : Gtk_Button;

begin
   Gtk.Main.Init;
   Gtk.Window.Gtk_New (Window);
   Gtk_New (Grid, 1, 1, False);
   Add (Window, Grid);
   Gtk_New (Button, "Clicked to kill");
   Attach (Grid, Button, 0, 1, 0, 1);
   No_Data_Handlers.Connect
   (  Window,
      "destroy",
      Destroy'Access
   );
   Killer_Handlers.Connect
   (  Button,
      "clicked",
      Clicked'Access,
      Gtk_Object_Record'Class (Window.all)'Access
   );
   Show_All (Grid);
   Show (Window);

   Gtk.Main.Main;
end Simple;
-----------------------------------------------------------
As you see it is almost trivial.

4. Regarding MVC. When deploying it, the first questions to answer are:

4.1. What is the model?
4.2. What is the view?
4.3. What is the controller?

http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

An example of using MVC in Gtk is combo box:

The model is Gtk_List_Store_Record, contains a row per box entry. A
designated column of the row determines the entry's contents.

The view is Gtk_Combo_Box_Record widget itself

The controller is anything else, which modifies the model, e.g. adds new
rows to the model. Typically an event callback responding to user actions.

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



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-11-22 12:13   ` Brian Drummond
@ 2012-12-03 16:17     ` ake.ragnar.dahlgren
  2012-12-03 21:56       ` Brian Drummond
  0 siblings, 1 reply; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-12-03 16:17 UTC (permalink / raw)


On Thursday, November 22, 2012 1:13:27 PM UTC+1, Brian Drummond wrote:
> On Thu, 22 Nov 2012 01:47:39 -0800, ake.ragnar.dahlgren wrote: > I want to thank everybody for replying. I had no idea about the > "renames" feature as Randy pointed out. Brian expressed it very well: I > am astonished! But heed Randy's warning : (I may have been confused among the discussion and speculation, but my understanding is this: corrections welcome!) the Renames is legal and intended to work as demonstrated: taking its access is ILLEGAL and only works because of an apparent bug in Gnat (which I for one am NOT jumping to report!). And therefore using it is a BAD IDEA because it may well go away in the future (as well as not being portable) It might be useful to see the reports from other compilers on the example... > As for the Gtkada application I have given up on implementing the MVC > pattern using tagged types. Instead I choose the same approach as was > done in the Ada in Denmark wiki. I believe that uses "tagged types" internally, but it is certainly easier... See also "Gate3" available at http://sourceforge.net/projects/lorenz/ which will auto-generate the Ada framework shown on that Ada.dk page, from your Glade UI XML file. - Brian

Thank you for your suggestion to use Gate3. I will check it out.

Yesterday I posted Ada code which uses Access on a renamed procedure. It's not clear to me but is it really illegal as you write? I hope you are not sure since you wrote corrections are welcome.

Best regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-12-03 11:21       ` Dmitry A. Kazakov
@ 2012-12-03 20:21         ` ake.ragnar.dahlgren
  2012-12-03 22:15           ` Dmitry A. Kazakov
  2012-12-25 21:51           ` Gustaf Thorslund
  0 siblings, 2 replies; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-12-03 20:21 UTC (permalink / raw)
  Cc: mailbox

On Monday, December 3, 2012 12:21:00 PM UTC+1, Dmitry A. Kazakov wrote:
> On Sun, 2 Dec 2012 12:42:27 -0800 (PST), ake.ragnar.dahlgren@gmail.com
> 
> wrote:
> 
> 
> 
> > I gladly provide more details by giving an example of Ada code. The with
> 
> > statements have been omitted and the GUI described by the
> 
> > main_window.glade file is assumed to contain a Label called Main_Label and
> 
> > the window has a destroy signal called Main_Window_Quit:
> 
> 
> 
> 1. I cannot comment on Glade, I don't use it.
> 
> 
> 
> 2. What is the problem?
> 
> 
> 
> Why handling Quit signal requires MVC, especially, because there is no such
> 
> signal, AFAIK?
> 
> 
> 
> 3. Is it about exiting GTK main loop? That does not need MVC at all.
> 
> 
> 
> In order to quit Gtk.Main.Main you have to call Gtk.Main.Quit. This is made
> 
> from a handler of the "destroy" event of Gtk_Object_Record, which is called
> 
> when a Gtk object is about to be destroyed. The object here is the main
> 
> window. That is it.
> 
> 
> 
> In order to initiate destruction of the main window otherwise than by means
> 
> of the window manager, the window manager does that when you press the
> 
> button [x] on window title, you should call the Destroy operation of
> 
> Gtk_Object_Record. The main window is Gtk_Window_Record, a descendant of.
> 
> 
> 
> Here is a minimal working sample of such application with a button to close
> 
> it:
> 
> 
> 
> ----------------- simple.adb -----------------------------
> 
> with Gtk.Object;  use Gtk.Object;
> 
> with Gtk.Button;  use Gtk.Button;
> 
> with Gtk.Window;  use Gtk.Window;
> 
> with Gtk.Widget;  use Gtk.Widget;
> 
> with Gtk.Table;   use Gtk.Table;
> 
> 
> 
> with Gtk.Handlers;
> 
> with Gtk.Main;
> 
> 
> 
> procedure Simple is
> 
> 
> 
>    package No_Data_Handlers is -- Event handlers with no user parameters
> 
>       new Gtk.Handlers.Callback (Gtk_Widget_Record);
> 
>    package Killer_Handlers is -- Handlers that take Gtk_Object
> 
>       new Gtk.Handlers.User_Callback (Gtk_Widget_Record, Gtk_Object);
> 
> 
> 
>    procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
> 
>    begin
> 
>      Gtk.Main.Main_Quit; -- Exit the message loop, we are done
> 
>    end Destroy;
> 
> 
> 
>    procedure Clicked
> 
>              (  Widget : access Gtk_Widget_Record'Class;
> 
>                 Object : Gtk_Object
> 
>              )  is
> 
>    begin
> 
>       Destroy (Object); -- Kill the object passed
> 
>    end Clicked;
> 
> 
> 
>    Window : Gtk_Window;
> 
>    Grid   : Gtk_Table;
> 
>    Button : Gtk_Button;
> 
> 
> 
> begin
> 
>    Gtk.Main.Init;
> 
>    Gtk.Window.Gtk_New (Window);
> 
>    Gtk_New (Grid, 1, 1, False);
> 
>    Add (Window, Grid);
> 
>    Gtk_New (Button, "Clicked to kill");
> 
>    Attach (Grid, Button, 0, 1, 0, 1);
> 
>    No_Data_Handlers.Connect
> 
>    (  Window,
> 
>       "destroy",
> 
>       Destroy'Access
> 
>    );
> 
>    Killer_Handlers.Connect
> 
>    (  Button,
> 
>       "clicked",
> 
>       Clicked'Access,
> 
>       Gtk_Object_Record'Class (Window.all)'Access
> 
>    );
> 
>    Show_All (Grid);
> 
>    Show (Window);
> 
> 
> 
>    Gtk.Main.Main;
> 
> end Simple;
> 
> -----------------------------------------------------------
> 
> As you see it is almost trivial.
> 
> 
> 
> 4. Regarding MVC. When deploying it, the first questions to answer are:
> 
> 
> 
> 4.1. What is the model?
> 
> 4.2. What is the view?
> 
> 4.3. What is the controller?
> 
> 
> 
> http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
> 
> 
> 
> An example of using MVC in Gtk is combo box:
> 
> 
> 
> The model is Gtk_List_Store_Record, contains a row per box entry. A
> 
> designated column of the row determines the entry's contents.
> 
> 
> 
> The view is Gtk_Combo_Box_Record widget itself
> 
> 
> 
> The controller is anything else, which modifies the model, e.g. adds new
> 
> rows to the model. Typically an event callback responding to user actions.
> 
> 
> 
> -- 
> 
> Regards,
> 
> Dmitry A. Kazakov
> 
> http://www.dmitry-kazakov.de

I agree with you that the example is almost trivial and that it is a good demonstratiion on how to use Gtkada. However, I am currently toying with the idea of making Gtkada applications using Glade-3 which is very similiar but a little bit different.

> 2. What is the problem?
> 
> 
> 
> Why handling Quit signal requires MVC, especially, because there is no such
> 
> signal, AFAIK?

There are two problems that together would require one to structure the code as I have done.

1) Automated tests (AUnit). The code should be testable. Perhaps one would like to have a test that verifies that Gtk.Main.Main_Quit is called when the "destroy" event of Gtk_Object_Record is triggered from the main window and so on. To make the code testable one needs to separate the GUI code from the logic somehow.
2) Perhaps one would like two have two views who are "connected" to the same controller instance (code reusability). If one updates a field on the controller instance then that change should be reflected in the two views. Something like the following:

package body Application is

   Main_Window_Controller : Controllers.Main_Window.Controller_Ref_Type;

   Main_Window_1 : Views.Main_Window.Main_Window_Ref_Type;
   Main_Window_2 : Views.Main_Window.Main_Window_Ref_Type;

   procedure On_Main_Window_Quit(Object : access Gtkada.Builder.Gtkada_Builder_Record'Class)
                                 renames Main_Window_Controller.On_Quit;

   procedure Main is
   begin

      Main_Window_Controller := new Controllers.Main_Window.Controller_Type;

      Main_Window_1 := Views.Main_Window.Create_Main_Window(Main_Window_Controller,                                                          On_Main_Window_Quit'Access);
      Main_Window_2 := Views.Main_Window.Create_Main_Window(Main_Window_Controller,                                                          On_Main_Window_Quit'Access);


      Main_Window_1.Show;
      Main_Window_2.Show;

      Gtk.Main.Main;
      -- Enter the main gtk loop.
   end Main;

begin
   Gtk.Main.Init;
end Application;

Not that I have in mind an actual real world application that would require two identical windows, but of theoretical interest. It is possible in other languages, and I'm thinking why not Ada?

Best regards,
Åke Ragnar Dahlgren



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-12-03 16:17     ` ake.ragnar.dahlgren
@ 2012-12-03 21:56       ` Brian Drummond
  0 siblings, 0 replies; 47+ messages in thread
From: Brian Drummond @ 2012-12-03 21:56 UTC (permalink / raw)


On Mon, 03 Dec 2012 08:17:26 -0800, ake.ragnar.dahlgren wrote:

> On Thursday, November 22, 2012 1:13:27 PM UTC+1, Brian Drummond wrote:
>> On Thu, 22 Nov 2012 01:47:39 -0800, ake.ragnar.dahlgren wrote: > I want
>> to thank everybody for replying. I had no idea about the > "renames"
>> feature as Randy pointed out. Brian expressed it very well: I > am
>> astonished! But heed Randy's warning : (I may have been confused among
>> the discussion and speculation, but my understanding is this:
>> corrections welcome!) the Renames is legal and intended to work as
>> demonstrated: taking its access is ILLEGAL...
>> Brian
> 
> Thank you for your suggestion to use Gate3. I will check it out.
> 
> Yesterday I posted Ada code which uses Access on a renamed procedure.
> It's not clear to me but is it really illegal as you write? I hope you
> are not sure since you wrote corrections are welcome.

I was expecting corrections on the legality of the rename in the first 
place; Randy and Adam have me convinced that taking its access is a Gnat 
fluke...

I *think* the answer is to register On_Quit as an Object_Handler rather 
than a Builder_Handler, as I suggested on Nov.20, to overcome the 
restrictions on argument type for a Builder Handler (which if I 
understand, is why you need the Rename contortion to make the first 
argument disappear)

Unfortunately, the correct way to use Object_Handler does not seem to 
have documentation/example code to help people like me get started ... 
yet. In my original example (linked from the ada.dk tutorial), the 
restriction on parameter formats for handlers was questioned in the 
comments, but I don't know the answers yet.

But I am convinced there *will be* a better way than the rename trick 
(and legal!) when we find it...

- Brian



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-12-03 20:21         ` ake.ragnar.dahlgren
@ 2012-12-03 22:15           ` Dmitry A. Kazakov
  2012-12-25 21:51           ` Gustaf Thorslund
  1 sibling, 0 replies; 47+ messages in thread
From: Dmitry A. Kazakov @ 2012-12-03 22:15 UTC (permalink / raw)


On Mon, 3 Dec 2012 12:21:45 -0800 (PST), ake.ragnar.dahlgren@gmail.com
wrote:

> However, I am currently toying with
> the idea of making Gtkada applications using Glade-3 which is very
> similiar but a little bit different.

My condolences...
 
>> 2. What is the problem?
>> 
>> Why handling Quit signal requires MVC, especially, because there is no such
>> 
>> signal, AFAIK?
> 
> There are two problems that together would require one to structure the
> code as I have done.
> 
> 1) Automated tests (AUnit). The code should be testable.

GUI is non-testable, too many states, some states are ill-defined, some are
real time dependent.

> Perhaps one would
> like to have a test that verifies that Gtk.Main.Main_Quit is called when
> the "destroy" event of Gtk_Object_Record is triggered from the main window
> and so on. To make the code testable one needs to separate the GUI code
> from the logic somehow.

That would be a GTK test = not a test of your code.

> 2) Perhaps one would like two have two views who are "connected" to the
> same controller instance (code reusability).

It is no problem at all. In the sample I provided the event handler takes
the window to destroy as a parameter.

> Not that I have in mind an actual real world application that would
> require two identical windows, but of theoretical interest. It is possible
> in other languages, and I'm thinking why not Ada?

It is already the way you wanted.

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



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-12-03 20:21         ` ake.ragnar.dahlgren
  2012-12-03 22:15           ` Dmitry A. Kazakov
@ 2012-12-25 21:51           ` Gustaf Thorslund
  2012-12-26 18:11             ` ake.ragnar.dahlgren
  1 sibling, 1 reply; 47+ messages in thread
From: Gustaf Thorslund @ 2012-12-25 21:51 UTC (permalink / raw)


ake.ragnar.dahlgren@gmail.com writes:

> Not that I have in mind an actual real world application that would
> require two identical windows, but of theoretical interest. 

I often find myself looking at same file in two buffers/windows in
emacs. Useful if you want to look at different parts of a file at the
same time. I suppose if you would have some 3D drawing application it
could be useful to look at different views at the same time too.

Hope I've not destroyed the fun of solving a theoretical problem by
bringing up two practical applications ;-)

/Gustaf



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

* Re: Access type to member procedure of instance (Object Oriented programming in Ada)
  2012-12-25 21:51           ` Gustaf Thorslund
@ 2012-12-26 18:11             ` ake.ragnar.dahlgren
  0 siblings, 0 replies; 47+ messages in thread
From: ake.ragnar.dahlgren @ 2012-12-26 18:11 UTC (permalink / raw)


On Tuesday, December 25, 2012 10:51:39 PM UTC+1, Gustaf Thorslund wrote:
> ake.ragnar.dahlgren@gmail.com writes:
> 
> 
> 
> > Not that I have in mind an actual real world application that would
> 
> > require two identical windows, but of theoretical interest. 
> 
> 
> 
> I often find myself looking at same file in two buffers/windows in
> 
> emacs. Useful if you want to look at different parts of a file at the
> 
> same time. I suppose if you would have some 3D drawing application it
> 
> could be useful to look at different views at the same time too.
> 
> 
> 
> Hope I've not destroyed the fun of solving a theoretical problem by
> 
> bringing up two practical applications ;-)
> 
> 
> 
> /Gustaf

Thanks for giving practical applications.

I will write more on this thread as soon as I have some time on my hands.

Best Regards,
Åke Ragnar Dahlgren



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

end of thread, other threads:[~2012-12-26 18:11 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-19  9:59 Access type to member procedure of instance (Object Oriented programming in Ada) ake.ragnar.dahlgren
2012-11-19 11:13 ` Georg Bauhaus
2012-11-19 11:39 ` Brian Drummond
2012-11-20 11:43   ` Brian Drummond
2012-11-20 21:57     ` Randy Brukardt
2012-11-19 13:03 ` sbelmont700
2012-11-19 16:18 ` Adam Beneschan
2012-11-19 17:02   ` Peter C. Chapin
2012-11-19 18:23     ` Adam Beneschan
2012-11-19 20:57       ` Peter C. Chapin
2012-11-19 21:26       ` Dmitry A. Kazakov
2012-11-19 22:19         ` Adam Beneschan
2012-11-20 10:12           ` Dmitry A. Kazakov
2012-11-20 21:51             ` Randy Brukardt
2012-11-21  8:24               ` Dmitry A. Kazakov
2012-11-21 22:19                 ` Randy Brukardt
2012-11-20 10:59     ` Brian Drummond
2012-11-19 20:22 ` ake.ragnar.dahlgren
2012-11-20 11:16   ` Brian Drummond
2012-11-19 20:52 ` ake.ragnar.dahlgren
2012-11-19 21:56   ` Dmitry A. Kazakov
2012-11-22  9:49     ` ake.ragnar.dahlgren
2012-11-19 22:13   ` sbelmont700
2012-11-19 23:59 ` Randy Brukardt
2012-11-20  0:05   ` Randy Brukardt
2012-11-20  1:00     ` Adam Beneschan
2012-11-20 21:38       ` Randy Brukardt
2012-11-20 23:43         ` Adam Beneschan
2012-11-21 22:12           ` Randy Brukardt
2012-11-22  1:59             ` Adam Beneschan
2012-11-29  2:43               ` Randy Brukardt
2012-11-20  0:52   ` Adam Beneschan
2012-11-20 21:34     ` Randy Brukardt
2012-11-20 11:28   ` Brian Drummond
2012-11-20 14:27     ` Georg Bauhaus
2012-11-20 15:52     ` Adam Beneschan
2012-11-22  9:47 ` ake.ragnar.dahlgren
2012-11-22 10:25   ` Dmitry A. Kazakov
2012-12-02 20:42     ` ake.ragnar.dahlgren
2012-12-03 11:21       ` Dmitry A. Kazakov
2012-12-03 20:21         ` ake.ragnar.dahlgren
2012-12-03 22:15           ` Dmitry A. Kazakov
2012-12-25 21:51           ` Gustaf Thorslund
2012-12-26 18:11             ` ake.ragnar.dahlgren
2012-11-22 12:13   ` Brian Drummond
2012-12-03 16:17     ` ake.ragnar.dahlgren
2012-12-03 21:56       ` Brian Drummond

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