Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Basic issue with dotted notation and tagged types

162 views
Skip to first unread message

Yannick Duchêne (Hibou57)

unread,
Oct 21, 2012, 6:55:08 PM10/21/12
to
I can't remember if this was already discussed here, somewhere in a
rationale or an RM comment, here is something I really don't like, with a
field (or member) of a tagged type and a function, both of the same name;
a very basic case:


with Ada.Text_IO;

procedure Test2 is

package IO renames Ada.Text_IO;

-- type T is tagged;
-- function F (E : T'Class) return Character;

type T
is tagged record
F : Character := 'A';
end record;

function F
(E : T'Class)
return Character
is ('B');

E : T;
C : Character := E.F; -- The function or the field?
begin
IO.Put (C);
end;


Will this display `A` or `B`? Actually, the program compiled with GNAT
4.6, displays `A`. It displays the same even when the two commented lines
are commented‑out and thus the function `F` is declared before the field
`F`. I can't remember if the RM have special wordings about it, but I feel
this does not honour the principle of least surprise. May be this should
be disallowed, to access any one of the two, when both are together
visible from a scope?


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

J-P. Rosen

unread,
Oct 22, 2012, 3:46:49 AM10/22/12
to
Le 22/10/2012 00:55, Yannick Duchêne (Hibou57) a écrit :
> [Snip]
> Will this display `A` or `B`? Actually, the program compiled with GNAT
> 4.6, displays `A`. It displays the same even when the two commented
> lines are commented‑out and thus the function `F` is declared before the
> field `F`. I can't remember if the RM have special wordings about it,
> but I feel this does not honour the principle of least surprise. May be
> this should be disallowed, to access any one of the two, when both are
> together visible from a scope?
>
>
RM2005 4.1.3 (9.2/2): "The designator of the subprogram shall not be the
same as that of a component of the tagged type visible at the point of
the selected_component."

BTW, this corresponds to /my/ view of least surprise: a prefixed view is
merely a writing simplification, and you are always free not to use it
without losing any functionality. OTOH, you would have no other way to
access a subcomponent. Therefore, it makes sense that the subcomponent
is "stronger".
--
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

Dmitry A. Kazakov

unread,
Oct 22, 2012, 4:02:16 AM10/22/12
to
On Mon, 22 Oct 2012 09:46:49 +0200, J-P. Rosen wrote:

> Le 22/10/2012 00:55, Yannick Duchêne (Hibou57) a écrit :
>> [Snip]
>> Will this display `A` or `B`? Actually, the program compiled with GNAT
>> 4.6, displays `A`. It displays the same even when the two commented
>> lines are commented‑out and thus the function `F` is declared before the
>> field `F`. I can't remember if the RM have special wordings about it,
>> but I feel this does not honour the principle of least surprise. May be
>> this should be disallowed, to access any one of the two, when both are
>> together visible from a scope?
>>
> RM2005 4.1.3 (9.2/2): "The designator of the subprogram shall not be the
> same as that of a component of the tagged type visible at the point of
> the selected_component."
>
> BTW, this corresponds to /my/ view of least surprise: a prefixed view is
> merely a writing simplification, and you are always free not to use it
> without losing any functionality. OTOH, you would have no other way to
> access a subcomponent. Therefore, it makes sense that the subcomponent
> is "stronger".

From a wider (and simpler) point of view a record component is just a pair
of primitive operations (getter/setter) on the record type. That makes them
conflicting with any user-defined primitive operations of same signature.

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

AdaMagica

unread,
Oct 22, 2012, 6:41:07 AM10/22/12
to
There is a similar problem:

type T is record
I: Integer;
end record;

function F return T is
I: Integer := -1; -- *
begin
return F.I; -- recursive call to F and select component I;
-- or I declared inside F at *
end F;

Without looking in the RM, I guess it's the latter.

Marius Amado-Alves

unread,
Oct 22, 2012, 6:52:25 AM10/22/12
to
> RM2005 4.1.3 (9.2/2): "The designator of the subprogram shall not be the
> same as that of a component of the tagged type visible at the point of
> the selected_component."

Hmm... shouldn't the compiler complain then? (about the program above)

Georg Bauhaus

unread,
Oct 22, 2012, 7:18:18 AM10/22/12
to
Maybe this piece of 2012 support is not yet implemented. With some changes,

with Ada.Text_IO;

procedure Test2 is

package IO renames Ada.Text_IO;

-- type T is tagged;
-- function F (E : T'Class) return Character;

package Wrap is

type T
is tagged record
F : Character := 'A';
end record;

function F
(E : T'Class; Dummy : Boolean) -- or E : T; ...
return T
is (T'(F => 'B'));

end wrap;


E : Wrap.T;
C : Character := E.F; -- The function or the field?
begin
IO.Put (C);
E := E.F (Dummy => True);
end;

I get

GNAT GPL 2012 (20120509)
Copyright 1992-2012, Free Software Foundation, Inc.

Compiling: test2.adb (source file time stamp: 2012-10-22 10:31:50)

29. E := E.F (Dummy => True);
|
>>> name in call is not a callable entity

30 lines: 1 error
gnatmake: "test2.adb" compilation error

Marius Amado-Alves

unread,
Oct 22, 2012, 7:37:38 AM10/22/12
to
> Maybe this piece of 2012 support is not yet implemented...

Dot notation is 2005. But I see now there is a 2012 thing in your code: an expression function. So yes, maybe it's an interference with 2012, which is still a bit "glitchy" in this compiler. The failure to complain about the illegal(?) naming, that is (4.1.3 9.2/2)

Niklas Holsti

unread,
Oct 22, 2012, 7:45:28 AM10/22/12
to
No, the quoted RM part just says that the prefixed call notation
(object.operation) is available /only/ when there is no (visible)
component that has the same name as the operation. If there is a
(visible) component with the same name, then the component effectively
hides the operation, in the object.name syntax.

So the program is legal. However, it may not work as the programmer
intended. An optional compiler warning could be helpful.

This really seems too much of a trap to accept silently. Just for
example, suppose there is a class hierarchy, and Ob is an object of some
derived type, and Foo some primitive operation of this derived type. The
meaning of Ob.Foo then depends on whether or not some level of the
hierarchy adds a component Foo to the type, and whether the component is
visible or not. Yuck! Most cases of confusion will probably be caught by
some type mismatch (or lack of actual parameters), but some will pass
undetected by the compiler.

--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .

Yannick Duchêne (Hibou57)

unread,
Oct 22, 2012, 9:46:12 AM10/22/12
to
Le Mon, 22 Oct 2012 10:02:16 +0200, Dmitry A. Kazakov
<mai...@dmitry-kazakov.de> a écrit:
> From a wider (and simpler) point of view a record component is just a
> pair of primitive operations (getter/setter) on the record type. That
> makes them conflicting with any user-defined primitive operations of
> same signature.

That's why I can't make my mind, as I feel both the same as you and the
same as J.Pierre too.

J.P Rosen wrote:
> and you are always free not to use it without losing any functionality.
> OTOH, you would have no other way to access a subcomponent.

Yannick Duchêne (Hibou57)

unread,
Oct 22, 2012, 9:50:22 AM10/22/12
to
Le Mon, 22 Oct 2012 12:52:25 +0200, Marius Amado-Alves
<amado...@gmail.com> a écrit:
No, it's the way it is to be interpreted. If you look at the context what
J.P. quoted, it's part of a
[Name Resolution
Rules](http://www.adaic.org/resources/add_content/standards/05rm/html/RM-4-1-3.html)

Yannick Duchêne (Hibou57)

unread,
Oct 22, 2012, 10:11:10 AM10/22/12
to
Le Mon, 22 Oct 2012 13:18:18 +0200, Georg Bauhaus
<rm.dash...@futureapps.de> a écrit:
> I get
>
> GNAT GPL 2012 (20120509)
> Copyright 1992-2012, Free Software Foundation, Inc.
>
> Compiling: test2.adb (source file time stamp: 2012-10-22 10:31:50)
>
> 29. E := E.F (Dummy => True);
> |
> >>> name in call is not a callable entity

Looks like it use only the name for the resolution, and does not use the
signature.

Maciej Sobczak

unread,
Oct 22, 2012, 10:17:01 AM10/22/12
to
W dniu poniedziałek, 22 października 2012 13:45:29 UTC+2 użytkownik Niklas Holsti napisał:

> Just for
> example, suppose there is a class hierarchy, and Ob is an object of some
> derived type, and Foo some primitive operation of this derived type. The
> meaning of Ob.Foo then depends on whether or not some level of the
> hierarchy adds a component Foo to the type, and whether the component is
> visible or not. Yuck!

I believe this falls in the following description:

http://en.wikipedia.org/wiki/Fragile_base_class

--
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com
0 new messages