From: Dmitry A. Kazakov on
On Thu, 05 Nov 2009 10:48:51 +0200, Niklas Holsti wrote:

> Dmitry A. Kazakov wrote:
>
>> Consider it this way, if _Type is felt appropriate then that is
>> semantically equivalent to types having a separate name space. The latter
>> could be introduced in Ada at any time, being fully backward compatible.
>
> I'm not sure about the backward compatibility. For one thing, the 'Size
> attribute may have a different value for a type and for an object of the
> type. This means that given an object declaration "List : List", where
> the latter List is a type name, the expression List'Size would be
> ambiguous and could have a different value for the object List and the
> type List.

Yes, it is ambiguous, but backward compatible.

Another disadvantage of a separate name space were barring types as
first-class objects. I don't know how actual the latter might be.

I have no clear opinion on separate name space for types. Clearly if
considered, it should be accompanied with the separate name spaces for
labels and package names.

Further, the problem of what to do with

type T_Ptr is access T;
type T_Ref is access constant T;
type T_Class_Ptr is access T'Class;

will remain.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Vincent Marciante on
"Stephen Leake" <stephen_leake(a)stephe-leake.org> wrote in message
news:u1vkdrert.fsf(a)stephe-leake.org...
> "Peter C. Chapin" <pcc482719(a)gmail.com> writes:
>
>> Stephen Leake <stephen_leake(a)stephe-leake.org> wrote in
>> news:u4ope4pqa.fsf(a)stephe-leake.org:
>>
>>> Yes, but reading is also important. The _Type suffix is essentially
>>> noise when reading; it's only there for the compiler, not the human.
>>> So you want to read it as few times as possible, as well as write it
>>> as few times as possible.
>>
>> This seems backwards to me. I could use a type name such as X72efY9 for
>> all
>> the compiler cares. The _Type suffix is most definitely for the human. It
>> says, "Hey! This is the name of a type so keep that in mind when looking
>> at
>> this code."
>
> Well, you can read it that way. But the original reason the _Type
> convention got started (at least, as far as I'm concerned) is to solve
> the problem of overlapping object and type namespaces.
>
> This is illegal:
>
> procedure (List : in list);
>
> So we have to add noise to either the object or the type, to keep the
> compiler happy. That's all there is to it.

That is not necessary:

package sdgfkjasf is -- or whayever

type List is ...

procedure jsdfks (List : sdgfkjasf.List);

...


>> In the past I used _Type as a suffix for all of my types. However, there
>> are times when that doesn't seem to fit. After all the standard types
>> don't
>> (usually) use a _Type suffix (Character, Integer, Positive, Vector, etc).
>
> The standard is Just Wrong. But we have to live with it.
>
> --
> -- Stephe


Vinny


From: Stephen Leake on
Niklas Holsti <niklas.holsti(a)tidorum.invalid> writes:

> Dmitry A. Kazakov wrote:
>
>> Consider it this way, if _Type is felt appropriate then that is
>> semantically equivalent to types having a separate name space. The latter
>> could be introduced in Ada at any time, being fully backward compatible.
>
> I'm not sure about the backward compatibility. For one thing, the
> Size attribute may have a different value for a type and for an object
> of the type. This means that given an object declaration "List :
> List", where the latter List is a type name, the expression List'Size
> would be ambiguous and could have a different value for the object
> List and the type List.

The definition of "backward compatible" is "all existing legal
programs will still be legal".

This ambiguity does not exist in existing legal programs.

It is a good reason not to have separate name spaces; how would we
resolve the ambiguity?

--
-- Stephe
From: Stephen Leake on
Georg Bauhaus <rm.dash-bauhaus(a)futureapps.de> writes:

> Stephen Leake schrieb:
>> Georg Bauhaus <rm.dash-bauhaus(a)futureapps.de> writes:
>>
>>> Stephen Leake schrieb:
>>>
>>>> Op_1 (onto => list, element => object_1);
>>>> Op_2 (from => list, element => object_2);
>>>> Op_3 (container => list, element => object_3);
> ...
>> I meant easier in all senses; fewer compiler errors, fewer real
>> errors, less development time.
>
> What about the time needed to understand the program,
> or to communicate its meaning, and be it just the outlining
> of the don't-care parts absent from the naming scheme?

I don't understand why you are excluding the naming scheme. Naming
conventions are huge gain in understanding.

If I am reading a package that defines an abstract type List_Type, and
all primitive operations on List_Type have a parameter named List,
then I don't have to try to understand whatever name got used instead
of List.

>>> I think the ease argument will be interesting if it becomes
>>> clear what the Op_N stand for, respectively.
>>
>> If you start asking about what they stand for, you've missed the
>> point. I should not have to waste time thinking about that; I know
>
> Here we are... You may know, but I don't; if I am important
> as a user of your programs, I'd kindly ask you to have the
> knowledge shine through the names.

The names of the Op_N, sure. The name of the List parameter is
unlikely to add any information.

If there is more than one List paramter (say for Copy, or Splice),
then they need better names, of course.

>> they come from the list package, so the type is List_Type, and the
>> parameter name is List. Now I can think about the _other_ parameters.
>
> In this case (two things we know: we have a list package and
> a list type), it is possible instead to give, first,
>
> package List is
>
> type Container is private;
>
> procedure Sort (Elements : in out Container; ...);
>
> and,

Why is this better? It's just a different convention. If you follow it
uniformly, it will be just as good as List : in out List_Type.

> second, a rule that forces programmers to use a prefix in clients,
> to make sure the type of "Container" can be seen immediately:
>
> procedure Some_Client
> (<problem-domain-name> : List.Container; ...);
>
> Left_Queue, Right_Queue : List.Container;

What if the problem domain is "any list"? We keep pointing this out,
people keep ignoring it.

List.Container is much longer than it needs to be. But that's the
"don't use 'use'" argument.

>>> Cf. valid Eiffel:
>>>
>>> local
>>> string: STRING
>>> do
>>> ... -- more uses of string and STRING. Or StrINg.
>>
>> That is the argument both for and against case sensitivity.
>
> No, the argument is that a language allowing the same name
> ("string") to stand for different things, for both objects and
> types, in the same scope will necessarily add another dimension
> to the confusion space. Specifically, "string" and "STRING" do
> not denote the same thing *even* *though* the language
> Eiffel is case insensitive, like Ada.

That makes no sense. Ah; Eiffel has separate type and object name
spaces. So I don't understand the original example; what was the
point?

Yes, this is an example of name overloading. Overloading, like any
good thing, can be abused.

> The lexical overlap of names in separate name spaces plus the case
> insensitivity add to to the combinatorial explosives in front of the
> reader. (Of course, in real life forcing good standalone names are
> simply(*) is countered with "works for me".)

That is the argument against case insensitivity. I like GNAT's
solution to that; issue a warning when an identifier has different
casing than the first use.

> procedure Something (List : in out List; ....), with a
> namespace for objects and another for types, just places
> the burden of disambiguation on the reader.

Yes. But it is a very small burden, pretty much the same as having to
read _Type.

The syntax provides all the information necessary; Object : Type.

> Continuing Dmitry's argument
>
> package List_Package is
>
> type List_Type is private;
>
>
> function List_Function return List_Type;
>
> end List_Package;
>
> Here, I must choose List_Function because Ada lets me have
> only one namespace. So I need to add noise, but
> I (the author) know that the function is just
> returning a new List, no need to think of a good name,
> since I know what I am doing... What am I doing?

I don't understand your point. No one has suggested choosing generic
names for functions; clearly they need to indicate what the function
does. If this function returns a new empty list, I would call it
New_Empty_List.

Hmm. I guess you are pointing out that package names, subprogram
names, object names, and type names all share the same namespace.
Since we feel the need to add noise to types, why don't we feel the
same need to add noise to packages and subprograms?

The answer is we just don't :).

There are far fewer package names than other names, and come from the
domain, so it's not hard to come up with unique names. Making them
plural and everything else singular works pretty well.

Subprogram names tend to be more specific than parameters of an abstract
type.

I sometimes have package names that collide with enumeration
identifiers:

package Root_Serial_IO is

type Supported_Cards_Type is (Motorola_1, Intel_1,
national_semiconductor_42);

type Device_Type is abstract tagged private;

...
end Root_Serial_IO;

then I want child packages with the names Root_Serial_IO.Motorola_1
etc; that causes ambiguities, and sometimes ends up being unworkable.

--
-- Stephe
From: Dmitry A. Kazakov on
On Fri, 06 Nov 2009 04:54:46 -0500, Stephen Leake wrote:

> Niklas Holsti <niklas.holsti(a)tidorum.invalid> writes:
>
>> Dmitry A. Kazakov wrote:
>>
>>> Consider it this way, if _Type is felt appropriate then that is
>>> semantically equivalent to types having a separate name space. The latter
>>> could be introduced in Ada at any time, being fully backward compatible.
>>
>> I'm not sure about the backward compatibility. For one thing, the
>> Size attribute may have a different value for a type and for an object
>> of the type. This means that given an object declaration "List :
>> List", where the latter List is a type name, the expression List'Size
>> would be ambiguous and could have a different value for the object
>> List and the type List.
>
> The definition of "backward compatible" is "all existing legal
> programs will still be legal".
>
> This ambiguity does not exist in existing legal programs.

And it will not be imposed there by introducing a separation, because
presently such names collide.

> It is a good reason not to have separate name spaces; how would we
> resolve the ambiguity?

As always by using full names. Note that the argument that some of such
names are still ambiguous does not really work, because this is already so
in Ada. For example, overloaded subprograms and literals may have
indistinguishable full names. So this problem must be addressed anyway. The
traditional Ada way would be a qualified expression:

(type'(T))'Size

This returns us back to a more important argument against separate name
spaces. Do we really want to have types second-class citizens forever? Are
we sure that a type never ever appear in a context of an object? A
qualified expression at least suggests that a type is an object.

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