comp.lang.ada
 help / color / mirror / Atom feed
* GtkAda : Trying to derive a widget
@ 2021-04-08 19:27 DrPi
  2021-04-08 22:27 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 9+ messages in thread
From: DrPi @ 2021-04-08 19:27 UTC (permalink / raw)


Hi,

I'm trying to create a GtkAda widget derived from a standard widget.

-- debug_panel.ads
with Gtk.Scrolled_Window; use Gtk.Scrolled_Window;
with Gtk.Text_View;       use Gtk.Text_View;

package Debug_Panel is

    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with private;
    type Debug_Panel is access all Debug_Panel_Record'Class;


    procedure Gtk_New (Panel : in out Debug_Panel);
    procedure Initialize (Panel : not null access Debug_Panel_Record'Class);

private

    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with record
       Text       : Gtk_Text_View;
    end record;

end Debug_Panel;


-- debug_panel.adb
package body Debug_Panel is

    procedure Gtk_New (Panel : in out Debug_Panel) is
    begin
       Panel := new Debug_Panel_Record;
       Initialize (Panel);
    end Gtk_New;

    procedure Initialize (Panel : not null access 
Debug_Panel_Record'Class) is
    begin
       Gtk.Scrolled_Window.Initialize (Panel);
       -- Init other widgets
    end Initialize;

end Debug_Panel;


When compiling, I get the following error :
debug_panel.adb:6:07: ambiguous expression (cannot resolve "Initialize")
debug_panel.adb:6:07: possible interpretation at debug_panel.ads:15
debug_panel.adb:6:07: possible interpretation at gtk-scrolled_window.ads:92

The solution might be obvious but I don't understand why this error is 
raised by the compiler.

Any help much appreciated.

Nicolas

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

* Re: GtkAda : Trying to derive a widget
  2021-04-08 19:27 GtkAda : Trying to derive a widget DrPi
@ 2021-04-08 22:27 ` Dmitry A. Kazakov
  2021-04-09  5:28   ` DrPi
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2021-04-08 22:27 UTC (permalink / raw)


On 2021-04-08 21:27, DrPi wrote:

> I'm trying to create a GtkAda widget derived from a standard widget.
> 
> -- debug_panel.ads
> with Gtk.Scrolled_Window; use Gtk.Scrolled_Window;
> with Gtk.Text_View;       use Gtk.Text_View;
> 
> package Debug_Panel is
> 
>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with private;
>    type Debug_Panel is access all Debug_Panel_Record'Class;
> 
> 
>    procedure Gtk_New (Panel : in out Debug_Panel);
>    procedure Initialize (Panel : not null access Debug_Panel_Record'Class);
> 
> private
> 
>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with record
>       Text       : Gtk_Text_View;
>    end record;
> 
> end Debug_Panel;
> 
> 
> -- debug_panel.adb
> package body Debug_Panel is
> 
>    procedure Gtk_New (Panel : in out Debug_Panel) is
>    begin
>       Panel := new Debug_Panel_Record;
>       Initialize (Panel);

    Debug_Panel.Initialize (Panel);

Another way would be to remove "use Gtk.Scrolled_Window" and declare as

    type Debug_Panel_Record is
       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with private;

Without "use" Initialize is unambiguous.

P.S. When you create new widget it is better to use a more general 
ancestor hiding insufficient details, e.g.

    type Debug_Panel_Record is
       new Gtk.Widget.Gtk_Widget_Record with private;
    ...
private
    type Debug_Panel_Record is
       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with
    record
       ...
    end record;

This makes the code less fragile if you later decide to choose another 
container widget for the base.

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

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

* Re: GtkAda : Trying to derive a widget
  2021-04-08 22:27 ` Dmitry A. Kazakov
@ 2021-04-09  5:28   ` DrPi
  2021-04-09  6:12     ` J-P. Rosen
  2021-04-09  6:18     ` Dmitry A. Kazakov
  0 siblings, 2 replies; 9+ messages in thread
From: DrPi @ 2021-04-09  5:28 UTC (permalink / raw)


Le 09/04/2021 à 00:27, Dmitry A. Kazakov a écrit :
> On 2021-04-08 21:27, DrPi wrote:
> 
>> I'm trying to create a GtkAda widget derived from a standard widget.
>>
>> -- debug_panel.ads
>> with Gtk.Scrolled_Window; use Gtk.Scrolled_Window;
>> with Gtk.Text_View;       use Gtk.Text_View;
>>
>> package Debug_Panel is
>>
>>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with 
>> private;
>>    type Debug_Panel is access all Debug_Panel_Record'Class;
>>
>>
>>    procedure Gtk_New (Panel : in out Debug_Panel);
>>    procedure Initialize (Panel : not null access 
>> Debug_Panel_Record'Class);
>>
>> private
>>
>>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with record
>>       Text       : Gtk_Text_View;
>>    end record;
>>
>> end Debug_Panel;
>>
>>
>> -- debug_panel.adb
>> package body Debug_Panel is
>>
>>    procedure Gtk_New (Panel : in out Debug_Panel) is
>>    begin
>>       Panel := new Debug_Panel_Record;
>>       Initialize (Panel);
> 
>    Debug_Panel.Initialize (Panel);
I did try this notation and got this error :
debug_panel.adb:6:07: invalid prefix in selected component "Debug_Panel"
debug_panel.adb:6:18: prefixed call is only allowed for objects of a 
tagged type

I've just realized this is because the package and the access type have 
the same name.

> 
> Another way would be to remove "use Gtk.Scrolled_Window" and declare as
> 
>    type Debug_Panel_Record is
>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with private;
> 
> Without "use" Initialize is unambiguous.
> 
That makes sense.
However, I don't understand why there is ambiguity when using "use".
Debug_Panel (the type) is of type Debug_Panel_Record, so Initialize 
should resolve to the one using this type. Well, I guess I'm wrong.

> P.S. When you create new widget it is better to use a more general 
> ancestor hiding insufficient details, e.g.
> 
>    type Debug_Panel_Record is
>       new Gtk.Widget.Gtk_Widget_Record with private;
>    ...
> private
>    type Debug_Panel_Record is
>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with
>    record
>       ...
>    end record;

I'm surprized this is possible to write such a thing in Ada.
What does the compiler do with this ?

> 
> This makes the code less fragile if you later decide to choose another 
> container widget for the base.
> 

Thanks for your help

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

* Re: GtkAda : Trying to derive a widget
  2021-04-09  5:28   ` DrPi
@ 2021-04-09  6:12     ` J-P. Rosen
  2021-04-09 11:32       ` DrPi
  2021-04-09  6:18     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 9+ messages in thread
From: J-P. Rosen @ 2021-04-09  6:12 UTC (permalink / raw)


Le 09/04/2021 à 07:28, DrPi a écrit :
>> Without "use" Initialize is unambiguous.
>>
> That makes sense.
> However, I don't understand why there is ambiguity when using "use".
> Debug_Panel (the type) is of type Debug_Panel_Record, so Initialize 
> should resolve to the one using this type. Well, I guess I'm wrong.
No, the type is "access Debug_Panel_Record'Class", and the other 
initialize is for "access Gtk_Scrolled_Window_Record'Class", which 
covers the other one.

Remember that a class wide type ('Class) is a different type that covers 
all descendants.

>> P.S. When you create new widget it is better to use a more general 
>> ancestor hiding insufficient details, e.g.
>>
>>    type Debug_Panel_Record is
>>       new Gtk.Widget.Gtk_Widget_Record with private;
>>    ...
>> private
>>    type Debug_Panel_Record is
>>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with
>>    record
>>       ...
>>    end record;
> 
> I'm surprized this is possible to write such a thing in Ada.
> What does the compiler do with this ?
> There is no problem, since 
Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record is a descendant of 
Gtk.Widget.Gtk_Widget_Record. There is no lie: a Debug_Panel_Record IS A 
Gtk_Widget_Record. The private view has more information: it actually IS 
A Gtk_Scrolled_Window_Record, but the extra properties are not 
accessible outside from the package body.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

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

* Re: GtkAda : Trying to derive a widget
  2021-04-09  5:28   ` DrPi
  2021-04-09  6:12     ` J-P. Rosen
@ 2021-04-09  6:18     ` Dmitry A. Kazakov
  2021-04-09 11:42       ` DrPi
  1 sibling, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2021-04-09  6:18 UTC (permalink / raw)


On 2021-04-09 07:28, DrPi wrote:
> Le 09/04/2021 à 00:27, Dmitry A. Kazakov a écrit :
>> On 2021-04-08 21:27, DrPi wrote:
>>
>>> I'm trying to create a GtkAda widget derived from a standard widget.
>>>
>>> -- debug_panel.ads
>>> with Gtk.Scrolled_Window; use Gtk.Scrolled_Window;
>>> with Gtk.Text_View;       use Gtk.Text_View;
>>>
>>> package Debug_Panel is
>>>
>>>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with 
>>> private;
>>>    type Debug_Panel is access all Debug_Panel_Record'Class;
>>>
>>>
>>>    procedure Gtk_New (Panel : in out Debug_Panel);
>>>    procedure Initialize (Panel : not null access 
>>> Debug_Panel_Record'Class);
>>>
>>> private
>>>
>>>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with record
>>>       Text       : Gtk_Text_View;
>>>    end record;
>>>
>>> end Debug_Panel;
>>>
>>>
>>> -- debug_panel.adb
>>> package body Debug_Panel is
>>>
>>>    procedure Gtk_New (Panel : in out Debug_Panel) is
>>>    begin
>>>       Panel := new Debug_Panel_Record;
>>>       Initialize (Panel);
>>
>>    Debug_Panel.Initialize (Panel);
> I did try this notation and got this error :
> debug_panel.adb:6:07: invalid prefix in selected component "Debug_Panel"
> debug_panel.adb:6:18: prefixed call is only allowed for objects of a 
> tagged type
> 
> I've just realized this is because the package and the access type have 
> the same name.

You can disambiguate it so:

    Standard.Debug_Panel.Initialize (Panel)

    Standard.Debug_Panel - The package name
    Standard.Debug_Panel.Debug_Panel - The type name

>> Another way would be to remove "use Gtk.Scrolled_Window" and declare as
>>
>>    type Debug_Panel_Record is
>>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with private;
>>
>> Without "use" Initialize is unambiguous.
>>
> That makes sense.
> However, I don't understand why there is ambiguity when using "use".
> Debug_Panel (the type) is of type Debug_Panel_Record, so Initialize 
> should resolve to the one using this type. Well, I guess I'm wrong.

Debug_Panel belongs to both Debug_Panel_Record'Class and 
Gtk_Scrolled_Window_Record'Class (and many other classes), so the ambiguity.

>> P.S. When you create new widget it is better to use a more general 
>> ancestor hiding insufficient details, e.g.
>>
>>    type Debug_Panel_Record is
>>       new Gtk.Widget.Gtk_Widget_Record with private;
>>    ...
>> private
>>    type Debug_Panel_Record is
>>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with
>>    record
>>       ...
>>    end record;
> 
> I'm surprized this is possible to write such a thing in Ada.
> What does the compiler do with this ?

The public view is Gtk_Widget_Record [with no record members], the full 
view is Gtk_Scrolled_Window_Record [with record members you specified].

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

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

* Re: GtkAda : Trying to derive a widget
  2021-04-09  6:12     ` J-P. Rosen
@ 2021-04-09 11:32       ` DrPi
  0 siblings, 0 replies; 9+ messages in thread
From: DrPi @ 2021-04-09 11:32 UTC (permalink / raw)


Le 09/04/2021 à 08:12, J-P. Rosen a écrit :
> Le 09/04/2021 à 07:28, DrPi a écrit :
>>> Without "use" Initialize is unambiguous.
>>>
>> That makes sense.
>> However, I don't understand why there is ambiguity when using "use".
>> Debug_Panel (the type) is of type Debug_Panel_Record, so Initialize 
>> should resolve to the one using this type. Well, I guess I'm wrong.
> No, the type is "access Debug_Panel_Record'Class", and the other 
> initialize is for "access Gtk_Scrolled_Window_Record'Class", which 
> covers the other one.
> 
What I mean is that one "Initialize" procedure has a parameter of type 
"access Debug_Panel_Record'Class" and the other of type "access 
Gtk_Scrolled_Window_Record'Class".
The call to "Initialize" is made with a "Debug_Panel" type which is an 
access to "Debug_Panel_Record'Class" not " an access to 
"Gtk_Scrolled_Window_Record'Class".
So, why is there an ambiguity here ?


> Remember that a class wide type ('Class) is a different type that covers 
> all descendants.
> 
>>> P.S. When you create new widget it is better to use a more general 
>>> ancestor hiding insufficient details, e.g.
>>>
>>>    type Debug_Panel_Record is
>>>       new Gtk.Widget.Gtk_Widget_Record with private;
>>>    ...
>>> private
>>>    type Debug_Panel_Record is
>>>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with
>>>    record
>>>       ...
>>>    end record;
>>
>> I'm surprized this is possible to write such a thing in Ada.
>> What does the compiler do with this ?
>> There is no problem, since 
> Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record is a descendant of 
> Gtk.Widget.Gtk_Widget_Record. There is no lie: a Debug_Panel_Record IS A 
> Gtk_Widget_Record. The private view has more information: it actually IS 
> A Gtk_Scrolled_Window_Record, but the extra properties are not 
> accessible outside from the package body.
> 
Ok. That's interesting.
One more thing learned today :)

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

* Re: GtkAda : Trying to derive a widget
  2021-04-09  6:18     ` Dmitry A. Kazakov
@ 2021-04-09 11:42       ` DrPi
  2021-04-09 12:23         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 9+ messages in thread
From: DrPi @ 2021-04-09 11:42 UTC (permalink / raw)


Le 09/04/2021 à 08:18, Dmitry A. Kazakov a écrit :
> On 2021-04-09 07:28, DrPi wrote:
>> Le 09/04/2021 à 00:27, Dmitry A. Kazakov a écrit :
>>> On 2021-04-08 21:27, DrPi wrote:
>>>
>>>> I'm trying to create a GtkAda widget derived from a standard widget.
>>>>
>>>> -- debug_panel.ads
>>>> with Gtk.Scrolled_Window; use Gtk.Scrolled_Window;
>>>> with Gtk.Text_View;       use Gtk.Text_View;
>>>>
>>>> package Debug_Panel is
>>>>
>>>>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with 
>>>> private;
>>>>    type Debug_Panel is access all Debug_Panel_Record'Class;
>>>>
>>>>
>>>>    procedure Gtk_New (Panel : in out Debug_Panel);
>>>>    procedure Initialize (Panel : not null access 
>>>> Debug_Panel_Record'Class);
>>>>
>>>> private
>>>>
>>>>    type Debug_Panel_Record is new Gtk_Scrolled_Window_Record with 
>>>> record
>>>>       Text       : Gtk_Text_View;
>>>>    end record;
>>>>
>>>> end Debug_Panel;
>>>>
>>>>
>>>> -- debug_panel.adb
>>>> package body Debug_Panel is
>>>>
>>>>    procedure Gtk_New (Panel : in out Debug_Panel) is
>>>>    begin
>>>>       Panel := new Debug_Panel_Record;
>>>>       Initialize (Panel);
>>>
>>>    Debug_Panel.Initialize (Panel);
>> I did try this notation and got this error :
>> debug_panel.adb:6:07: invalid prefix in selected component "Debug_Panel"
>> debug_panel.adb:6:18: prefixed call is only allowed for objects of a 
>> tagged type
>>
>> I've just realized this is because the package and the access type 
>> have the same name.
> 
> You can disambiguate it so:
> 
>    Standard.Debug_Panel.Initialize (Panel)
> 
>    Standard.Debug_Panel - The package name
>    Standard.Debug_Panel.Debug_Panel - The type name
> 
Ah. I have to remember this.
That makes "Standard" some sort of reserved keyword.


>>> Another way would be to remove "use Gtk.Scrolled_Window" and declare as
>>>
>>>    type Debug_Panel_Record is
>>>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with private;
>>>
>>> Without "use" Initialize is unambiguous.
>>>
>> That makes sense.
>> However, I don't understand why there is ambiguity when using "use".
>> Debug_Panel (the type) is of type Debug_Panel_Record, so Initialize 
>> should resolve to the one using this type. Well, I guess I'm wrong.
> 
> Debug_Panel belongs to both Debug_Panel_Record'Class and 
> Gtk_Scrolled_Window_Record'Class (and many other classes), so the 
> ambiguity.
> 
Surprising behaviour for a strongly typed language but there surely is a 
good reason.

>>> P.S. When you create new widget it is better to use a more general 
>>> ancestor hiding insufficient details, e.g.
>>>
>>>    type Debug_Panel_Record is
>>>       new Gtk.Widget.Gtk_Widget_Record with private;
>>>    ...
>>> private
>>>    type Debug_Panel_Record is
>>>       new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record with
>>>    record
>>>       ...
>>>    end record;
>>
>> I'm surprized this is possible to write such a thing in Ada.
>> What does the compiler do with this ?
> 
> The public view is Gtk_Widget_Record [with no record members], the full 
> view is Gtk_Scrolled_Window_Record [with record members you specified].
> 
Ok.

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

* Re: GtkAda : Trying to derive a widget
  2021-04-09 11:42       ` DrPi
@ 2021-04-09 12:23         ` Dmitry A. Kazakov
  2021-04-09 13:37           ` DrPi
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2021-04-09 12:23 UTC (permalink / raw)


On 2021-04-09 13:42, DrPi wrote:
> Le 09/04/2021 à 08:18, Dmitry A. Kazakov a écrit :

>> Debug_Panel belongs to both Debug_Panel_Record'Class and 
>> Gtk_Scrolled_Window_Record'Class (and many other classes), so the 
>> ambiguity.
>>
> Surprising behaviour for a strongly typed language but there surely is a 
> good reason.

It is strongly typed.

The class is defined a set of types closed upon inheritance. When you 
declare a class-wide operation like Initialize it is meant to work on 
all instances of the class. There is no type violation or type coercion 
here.

Initialize of Gtk_Scrolled_Window_Record'Class is defined on 
Gtk_Scrolled_Window_Record and all types derived from 
Gtk_Scrolled_Window_Record.

When you declare another Initialize on Debug_Panel_Record'Class it is 
defined on Debug_Panel_Record and all its descendants.

If you overload them, in a context you must disambiguate for 
Debug_Panel_Record and any descendant of.

This is not different from Ada subtypes. For example, you can declare

    procedure Foo (I : Integer);

and in some other package

    procedure Foo (I : Positive);

If both become visible in a context you would have same problem.

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

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

* Re: GtkAda : Trying to derive a widget
  2021-04-09 12:23         ` Dmitry A. Kazakov
@ 2021-04-09 13:37           ` DrPi
  0 siblings, 0 replies; 9+ messages in thread
From: DrPi @ 2021-04-09 13:37 UTC (permalink / raw)


Le 09/04/2021 à 14:23, Dmitry A. Kazakov a écrit :
> On 2021-04-09 13:42, DrPi wrote:
>> Le 09/04/2021 à 08:18, Dmitry A. Kazakov a écrit :
> 
>>> Debug_Panel belongs to both Debug_Panel_Record'Class and 
>>> Gtk_Scrolled_Window_Record'Class (and many other classes), so the 
>>> ambiguity.
>>>
>> Surprising behaviour for a strongly typed language but there surely is 
>> a good reason.
> 
> It is strongly typed.
> 
> The class is defined a set of types closed upon inheritance. When you 
> declare a class-wide operation like Initialize it is meant to work on 
> all instances of the class. There is no type violation or type coercion 
> here.
> 
> Initialize of Gtk_Scrolled_Window_Record'Class is defined on 
> Gtk_Scrolled_Window_Record and all types derived from 
> Gtk_Scrolled_Window_Record.
> 
> When you declare another Initialize on Debug_Panel_Record'Class it is 
> defined on Debug_Panel_Record and all its descendants.
> 
> If you overload them, in a context you must disambiguate for 
> Debug_Panel_Record and any descendant of.
> 
> This is not different from Ada subtypes. For example, you can declare
> 
>    procedure Foo (I : Integer);
> 
> and in some other package
> 
>    procedure Foo (I : Positive);
> 
> If both become visible in a context you would have same problem.
> 

Ok.
Thanks for clarifying.

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

end of thread, other threads:[~2021-04-09 13:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-08 19:27 GtkAda : Trying to derive a widget DrPi
2021-04-08 22:27 ` Dmitry A. Kazakov
2021-04-09  5:28   ` DrPi
2021-04-09  6:12     ` J-P. Rosen
2021-04-09 11:32       ` DrPi
2021-04-09  6:18     ` Dmitry A. Kazakov
2021-04-09 11:42       ` DrPi
2021-04-09 12:23         ` Dmitry A. Kazakov
2021-04-09 13:37           ` DrPi

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