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:
>>
>>> Hibou57 (Yannick Duch�ne) schrieb:
>>>
>>>> There is on the other hand, this other convention, which came from
>>>> Pascal I suppose : the one which ends types name with the suffix _Type
>>> If you can't find a name for an object, ask more questions
>>> about it, its use, its relations, the programmer, its purpose,
>>> his purpose, etc:
>>> What is the role of the object? Does the role lead to a name?
>>
>> Why should I have to waste time on this?
>
> Because the time "wasted" on thinking about the roles (properties,
> relations, ...) of named entities in your programs, and
> then not being silent about your results, instead naming the
> entities suitably according to your results, and explicitly
> saying what you mean, is
>
> (a) spent anyway, though to different extents, on this very
> issue

Yes, but that applies to both the object name and the type name;
making them _different_ requires _extra_ effort.

> P1 (in the kitchen): "P2? Mind giving me that?"
> P2 (in the living room): "What?"
> P1: "That thing over there."
> P2: "Where?"
> P1 (approaches): "There." (P2 moves) "No, there."
> "No, not that, that!"

This is _not_ a good analogy; "that" is not a subprogram parameter in
the kitchen!

>> procedure Sort (List : in out List; Order : in Order_Type);
>
> "List" is a darn bad abstraction name here!

Nonsense; it is _precisely_ what I want; a list of abstract objects.

You can't avoid the naming problem by changing the context!

Here are the similar definitions from
Ada.Containers.Indefinite_Doubly_Linked_Lists. I hope you won't start
arguing that is a bad abstraction.

package Ada.Containers.Indefinite_Doubly_Linked_Lists is

type List is tagged private;

generic
with function "<" (Left, Right : Element_Type) return Boolean is <>;
package Generic_Sorting is

function Is_Sorted (Container : List) return Boolean;
end Generic_Sorting;
end Ada.Containers.Indefinite_Doubly_Linked_Lists;

Note that it uses _Type for Element!

How is that better than this:

package Ada.Containers.Indefinite_Doubly_Linked_Lists is

type List_Type is tagged private;

generic
with function "<" (Left, Right : Element_Type) return Boolean is <>;
package Generic_Sorting is

function Is_Sorted (List : List_Type) return Boolean;
end Generic_Sorting;

end Ada.Containers.Indefinite_Doubly_Linked_Lists;

> (For illustration we could similarly praise a ubuquituous type name
> such as "Bits" when what is meant is
> "Temperature_Sensor.Connector_Bits", say.)

But nothing specific is "meant" here; it is a generic, in the truest
English meaning of that word.

> (Rules here: Bits _of_ something, sensor _of_ something,
> these are examples following Tom Moran's comment, if I'm
> not mistaken. Names Sensor and Bits are really quite abstract.
> I would force them to be used for abstract types' names, at best.)

Yes, if you have a specific context and a specific meaning, then you
should use a specific name. The corollary is that if you have a
generic context, you should use a generic name.

> List in your original example without the Order parameter was
> almost certainly a Partial_Order even without an Order parameter
> in sight (since in the modified example you have given in this
> posting there is an Order parameter). Next, the List is a partial
> order of element of some type. Only in a reusable subprogram
> their type, if irrelevant, adds but noise (as per Bob Duff's rule).
> Since there is now an explicit Order parameter, I will assume
> that the List is really just a set of items without an order,
> and the name "List" only alludes to the mode of accessing
> the elements (sequentially, linked in some unknown way).

Ok.

> If I understand "Sort" meant as a generically useful procedure,
> then, as Dmitry has said, the first argument can be named "Container",
> since it contains the elements of the list (the type of Container).

Obviously; that's the approach Ada.Containers takes. It can also be
named "list", since that means exactly the same thing. Or the type can
be named "container", for the same reason.

There is the large risk that one person will decide on :

procedure Sort (Container : in out List);

and another will choose:

procedure Sort (List : in out Container);

Now somebody has to decide, and one has to go back and make lots of
trivial (and therefore error-prone) edits.

I suppose one person could choose List_Type and the other
Container_Type, but at least that's a smaller fix to unify them.

> Without some hint to an order, a type name "List" says enough about
> the structure of the actual parameter (Container).
>
> "Order" is somewhat unspecific.

Yes, deliberately.

> The "List" context helps when guessing that Order refers to a
> mathematical ordering relation. Its not a call to order, say, in a
> program controlling the president's electronic bell in some
> parliament.

Yes, obviously; this is a programming language context, not "the real
world".

> Inside the procedure, you might want to emphasize the links of
> the elements to be sorted.

Who said this was a linked list? Ada.Containers.Doubly_Linked_Lists
is, my original example doesn't care. I guess you could be refering to
abstract links.

See http://www.stephe-leake.org/ada/sal.html
sal-gen-alg-find_linear-sorted.ads for an abstract sort procedure. It
uses Container and Container_Type; "list" does have the connotation of
"linked list", "container" is slightly more abstract. But I often use
the name "list" for an implementation that happens to be an unbounded
array; "list" tends to imply some access order, meaning there is at
least First, Next, Is_Done. Containers don't have those functions.

> One way to achieve this is to rename the parameter "Container"
> to "Linked_Elements" (I'd think it is somewhat pompous, though.
> The implementer will know how to deal with the name Container.
> The reader of Sort's body will know what Container is, too.
> Because the type name, such as "Linked_List" gives the necessary
> information.)

That would be wrong; you are adding/imposing a structure that is not
necessarily there.

> generic
> type Less_Equal is new Ordering with private;
> procedure Sort (Container : in out Linked_List);
>
> Is anything lost here?

Yes! You have lost the fact that this is a generic procedure that
doesn't care about the internal structure of the list. You have also
lost the ability to specify the Order at run-time.

And "less_equal" implies a mathematical sort. All I really need for a
sort that produces a linear order is "goes_before". We tend to map all
things into numbers, so "less_equal" makes sense. But it's really
better to say "A goes before B", instead of "A is less than B".

"Ordering" could also imply a partial order, as for military rank; all
generals first, then all lieutenants, seargents, etc. Less_Equal can
mean that, but "Military_Rank" would be clearer.

>>> Naming conventions always make me think of features
>>> that a language does not offer. I don't think this is
>>> the case with types and objects in Ada.
>>
>> It _is_ the case for Ada! The feature "separate name spaces for types
>> and objects" is not offered by Ada. I'm not aware of a language that
>> does offer this feature, but it certainly is within the realm of
>> possibility.
>
> I think Dylan made an attempt, at least if one is satified with "car"
> being in a different namespace than "<car>".

Clearly it's a different name; it's a different lexeme. That's
the same as the _Type convention.

> I'd still not pick essentially the same name for object Car
> and type Car though. Even if Ada had one namespace for types
> and one for other entities. An object is never the same
> as a type, therefore it should be possible to distinguish
> the difference using words.

Yes! Car is distinguished from Car_Type, but List is not distinguished
from Container. Thank you for agreeing with me :).

Actually, I disagree with this statement; overloading types and
objects is fine, since the language does make the distinction clear
from context. In Dylan, I would use "car" and "<car>".

It sounds like you don't like overloading in the first place. How
about this:

adding integers is never the same as adding float; it should be
possible to distinguish the difference using words

So you don't like "+" (Left, Right : in Integer) and "+" (Left, Right
: in Float)?

If you do like operator overloading, how is that different from
object/type overloading?

--
-- Stephe
From: Stephen Leake on
"Jeffrey R. Carter" <spam.jrcarter.not(a)spam.acm.org> writes:

> Stephen Leake wrote:
>>
>> Why should I have to waste time on this?
>
> The time is not wasted. I've said before that _T[ype] is an excuse for
> not doing necessary thinking. Good names document the code and make it
> easier to understand; mindlessly adding _T[ype] to a general concept
> name for the type name and mindlessly using the general concept name
> for all parameters and objects of the type doesn't. If you don't spend
> the time and effort involved to think about and use good names, then
> everyone who reads the resulting code has to do the equivalent
> thinking to understand the code.

Yes, you need to pick good names. Having picked good names, why waste
_more_ time picking _different_ names for type vs object?

> When you see
>
> Append (List => List, Element => Element);
>
> you don't really know what's being appended to what.

In a purely generic context, like in the body of
Ada.Containers.Indefinite_Doubply_Linked_LIsts, that is precisely what
you should know.

What's wrong with that?

Ah, perhaps you mean "am I appending Element to List, or List to
Element"? I don't think that's a reasonable objection; List is clearly
the container, here, given the English meanings of the words.

> Compare that to
>
> Append (Onto => Widget_List, Item => Next_Widget);

In the body of a container of widgets, yes, this is appropriate.

I don't see any difference between "Item" and "Element";
Ada.Containers uses "Element", SAL uses "Item".

"Onto" almost makes sense, because "Append this onto that" is proper
English. Note that the order in the code is wrong, though!

But in a package containing several operations on an abstract type,
it's better to use the same name for the abstract type parameter in
all operations. Otherwise the user has to keep checking what that name
is:

Op_1 (onto => list, element => object_1);
Op_2 (from => list, element => object_2);
Op_3 (container => list, element => object_3);

It's much easier if it's always "list => list".

--
-- Stephe
From: Stephen Leake on
tmoran(a)acm.org writes:

>> An example trap (to me at least) : what about a type which would seems
>> obviously named Size and a parameter which seems obviously named
>> Size ? X would surely not be OK, neither Item.
>
> There is no Size by itself - it's the Size of something. So a function
> to calculate the price of a pumpkin, based on its size, would be
> function Price(Pumpkin_Size : Size) return Dollars;

You need 100,000 of these functions in a typical large grocery store.
Ada doesn't support this:

function Price(Pumpkin_Size : Size) return Dollars;
function Price(Milk_Size : Size) return Dollars;
function Price(Granny_Smith_Apple_Size : Size) return Dollars;

Clearly this will be

function Price (Item : Item_Type; Size : Size_Type) return Dollars;

The context associates Size with Item; no need to add more noise.

> function Price(Its_Size : Size) return Dollars;
> That's as far as you can go if Size is the type name. If you used
> something else, eg Size_Type or Size_T or Sizes, then you could
> shorten the parameter name all the way to Size. Since you probably
> write variable names much more often in the code than the type name,
> it makes sense to try to shorten them, at the expense of slightly
> longer type names. IMHO

Exactly; that's why we use Size_Type.

--
-- Stephe
From: Hibou57 (Yannick Duchêne) on
On 31 oct, 12:47, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de>
wrote:
> On Sat, 31 Oct 2009 04:30:38 -0700 (PDT), Hibou57 (Yannick Duchêne) wrote:
> > On 31 oct, 10:49, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de>
> > wrote:
> >> "the cats"
> > This is a class, not a type
> > So let's call classes The_Xxxs (with an ending S)
> > But what about types ? (and instances of a type)
>
> Class is a set of types. Type is a set of values. When the cat is an
> object, the cats is its type. Mammals is the set of types that contain the
> type cats. The corresponding type can be the mammals, i.e. flatten mammals
> class.
You are right, this is not a class.
But the type may rather be seen as an abstraction of each individual
instance (or as a representation of all the possible instances, thus
the set, but not as a set of instances). The type, provide the way to
create an instance, it may be used to create a set of value, but it is
not a set of value (I know you use type right, I'm just trying to make
terms clear).

So let say now your « The Cats » is a type, and finally there is
something which mark it, so this goes in the way of a mark to state a
name is used a a type. “ The ” and the plural, may be seen as
equivalent to the “ _Type ”

The only disclaimer I would add, is that I would not name a type using
a plural. This may seems natural at the type definition, but this will
be less natural at object instantiations (unless the type is a
containers, and the containers is named after the concrete type of
items it contains).

> In Ada there is no notation for the class. T'Class is a type, the closure
> of the class rooted in T, i.e. all values of the members of types derived
> from T.
This do the job, isn't it ? And this is true that a type — which may
be, at least potentially — the subject of any number of derivations,
at least potentially stands for a class, even it is not actually
derived. So there is no trouble to get the class rooted at a type from
a type attribute. There is no need for an explicit declaration of a
class, because the class associated to a tagged type, always exist,
that's the concept, and does not need any declaration (the subtype is
there, if a declaration is needed or wished).


Thanks for having notice (I mean, thanks for the correction)
From: Hibou57 (Yannick Duchêne) on
On 31 oct, 13:21, Stephen Leake <stephen_le...(a)stephe-leake.org>
wrote:
> > type Foo_Type is private;
> > type Foo_Access is access all Foo_Type;
>
> I use Foo_Access_Type for this.

What's your reason to use Foo_Access_Type instead of Foo_Access ?
Is that because of objects named Foo_Access ?

(just wanted to know)