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

Vector (container) initialization: the schizophrenic ampersand

83 views
Skip to first unread message

Marius Amado-Alves

unread,
May 17, 2012, 4:20:31 PM5/17/12
to
Shouldn't this be the right idiom to initialize a vector (container) with literals:

use My_Vectors;
V : My_Vectors.Vector := Element1 & Element2 & Element3;

Looks nice, but does not compile (with GNAT), because the compiler cannot make a decision on which "&" function to use where. Is there a way to give precedence to one of the "&" functions? Or some other nice solution? Thanks.

/*
My current solution is to rename one of the functions:

use My_Vectors;

function "+" (L : My_Vectors.Vector; R : My_Element_Type)
renames My_Vectors."&";

V : My_Vectors.Vector := Element1 & Element2 + Element3;

Not elegant at all.
*/

Jeffrey Carter

unread,
May 17, 2012, 4:24:54 PM5/17/12
to
On 05/17/2012 01:20 PM, Marius Amado-Alves wrote:
> Shouldn't this be the right idiom to initialize a vector (container) with
> literals:
>
> use My_Vectors; V : My_Vectors.Vector := Element1& Element2& Element3;
>
> Looks nice, but does not compile (with GNAT), because the compiler cannot
> make a decision on which "&" function to use where. Is there a way to give
> precedence to one of the"&" functions? Or some other nice solution? Thanks.

Does using parentheses help?

V : Vector := (E1 & E2) & E3;

--
Jeff Carter
Just as Khan was hindered by two-dimensional thinking in a
three-dimensional situation, so many developers are hindered
by sequential thinking in concurrent situations.
118

--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Pascal Obry

unread,
May 17, 2012, 4:26:12 PM5/17/12
to
Le 17/05/2012 22:20, Marius Amado-Alves a écrit :
> Shouldn't this be the right idiom to initialize a vector (container) with literals:
>
> use My_Vectors;
> V : My_Vectors.Vector := Element1 & Element2 & Element3;

Won't this works:

V : My_Vectors.Vector := (Element1 & Element2) & Element3;

?

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.net - http://v2p.fr.eu.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver keys.gnupg.net --recv-key F949BD3B

Adam Beneschan

unread,
May 17, 2012, 7:33:48 PM5/17/12
to
It compiled for me the first time I tried it, so I think we need more information, in particular what your element type is. A complete example that compiles except for that error would be helpful.

Parentheses won't help. The operator precedence rules mean that the expression is always interpreted as (Element1 & Element2) & Element3 regardless of what functions the operators refer to.

If your element type is some sort of array, then there could be a conflict with the built-in array concatenation operator. The solution might be

V : My_Vectors.Vector := My_Vectors.Vector'(Element1 & Element2) & Element3;

to make it clear that the first "&" must be the one that returns a Vector.

-- Adam

Marius Amado-Alves

unread,
May 18, 2012, 2:34:31 AM5/18/12
to
> If your element type is some sort of array, then there could be a conflict with the built-in array concatenation operator. (Adam)

The element are indeed an array, but the compiler only mentions the vector "&" functions in the error messages... But you can still be right. I'll check.

Thanks a lot.

Marius Amado-Alves

unread,
May 18, 2012, 2:51:52 AM5/18/12
to
Adam is right: it is confusion with the predefined "&" for arrays, when the elements are arrays. (But the compiler error messages indicate undecision only between the two Vectors "&" functions.) So my new solution is

function "+" (L : My_Vectors.Vector; R : My_Element_Type)
renames My_Vectors."&";

function "+" (L, R : My_Element_Type)
renames My_Vectors."&";

V : My_Vectors.Vector := Element1 + Element2 + Element3;

A bit less inelegant.

/* But more than parenthesis or T'(...) in my view. */

Thanks a lot. This group is outstanding.

Robert A Duff

unread,
May 18, 2012, 9:31:59 AM5/18/12
to
You mean more inelegant, or more elegant?

IMHO, a qualified expression is the elegant (and usual)
way to resolve ambiguities. Renaming "&" to be "+" just
seems confusing, to me.

- Bob

Shark8

unread,
May 18, 2012, 2:55:44 PM5/18/12
to
On Friday, May 18, 2012 8:31:59 AM UTC-5, Robert A Duff wrote:
>
> IMHO, a qualified expression is the elegant (and usual)
> way to resolve ambiguities. Renaming "&" to be "+" just
> seems confusing, to me.
>
> - Bob

Isn't that the whole point of having the qualified expression, to tell the compiler "this is the type for this ambiguous operation"?

Robert A Duff

unread,
May 18, 2012, 6:44:57 PM5/18/12
to
Yes, exactly.

Although qualified expressions also do some run-time checks, so
it's not the whole point, but the main point.

- Bob

Marius Amado-Alves

unread,
May 19, 2012, 5:03:56 AM5/19/12
to
> > V : My_Vectors.Vector := Element1 + Element2 + Element3;
> >
> > A bit less inelegant.
> >
> > /* But more than parenthesis or T'(...) in my view. */
>
> You mean more inelegant, or more elegant?

Oops, sorry, I mean more elegant, i.e. I find

Element1 + Element2 + Element3

more elegant than

(T'(Element1) & T'(Element2)) & T'(Element3)

or variations thereof. (Textual elegancy. I agree the latter form has more semantic rigour = abstract elegancy.)

Dmitry A. Kazakov

unread,
May 19, 2012, 5:28:31 AM5/19/12
to
On Thu, 17 May 2012 23:51:52 -0700 (PDT), Marius Amado-Alves wrote:

> Adam is right: it is confusion with the predefined "&" for arrays, when
> the elements are arrays. (But the compiler error messages indicate
> undecision only between the two Vectors "&" functions.) So my new solution
> is
>
> function "+" (L : My_Vectors.Vector; R : My_Element_Type)
> renames My_Vectors."&";
>
> function "+" (L, R : My_Element_Type)
> renames My_Vectors."&";
>
> V : My_Vectors.Vector := Element1 + Element2 + Element3;

What if My_Element_Type is numeric?

It is always problematic to mix sets and elements of. The idea to overload
an operation for both is attractive but guaranteed to have issues.

Semantically correct is:

(Element1, Element2, Element3)

Yet another trick to disambiguate:

Empty & Element1 & Element2 & Element3

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

Robert A Duff

unread,
May 19, 2012, 12:15:44 PM5/19/12
to
You don't need to qualify everything. Just enough to disambiguate.
I don't know what operators are visible in this example,
nor what the context is, but this should work:

T'(Element1 & Element2 & Element3)

- Bob

Adam Beneschan

unread,
May 21, 2012, 11:57:18 AM5/21/12
to
FYI, the last expression won't work the way you wrote it. If Element1 is an object declared with type T, then saying T'(Element1) won't gain you anything (other than possibly clarifying things for a reader), since the compiler already knows that Element1 has type T. The & operation needs to be enclosed in the parentheses in T'(...) to make a difference. That's what tells the compiler that when there are competing possibilities for &, to use the one that returns T.

As for which one is more elegant: this is a matter of opinion, but personally, if you have a small (maybe 15 lines) subprogram or block that uses this expression, and the "+" rename is declared locally within that subprogram or block, it wouldn't be hard to figure out. But if I'm trying to read your code, and I see this expression and start having to hunt for what "+" means, the result will probably include a set of curse words that are not very elegant. So in that sense, using the "+" rename reduces overall elegance. I'm sure you already realize this, but for others' benefit: elegance is a worthwhile goal only if it enhances readability by removing clutter without doing anything else that makes it harder to understand. Otherwise, the only way elegance is useful is if your goal is to hang a framed listing of your program on the wall, rather than to run it.

-- Adam

Adam Beneschan

unread,
May 21, 2012, 12:02:27 PM5/21/12
to
On Saturday, May 19, 2012 9:15:44 AM UTC-7, Robert A Duff wrote:

> You don't need to qualify everything. Just enough to disambiguate.
> I don't know what operators are visible in this example,
> nor what the context is, but this should work:
>
> T'(Element1 & Element2 & Element3)

Sorry, it won't work. Assume all the elements have some array type Arr. Syntactically, the above is equivalent to

Vector'((Element1 & Element2) & Element3)

before any overload resolution is done. The compiler still cannot tell whether the above means

Vector'(Arr'(Element1 & Element2) & Element3)
or
Vector'(Vector'(Element1 & Element2) & Element3)

So it's still ambiguous.

-- Adam

Robert A Duff

unread,
May 21, 2012, 1:04:30 PM5/21/12
to
Adam Beneschan <ad...@irvine.com> writes:

> On Saturday, May 19, 2012 9:15:44 AM UTC-7, Robert A Duff wrote:
>
>> You don't need to qualify everything. Just enough to disambiguate.
>> I don't know what operators are visible in this example,
>> nor what the context is, but this should work:
>>
>> T'(Element1 & Element2 & Element3)
>
> Sorry, it won't work.

Hmm. You're probably right. I'm not sure, because I haven't
seen what "&" operators we're talking about, nor what
the context is (is the concatenation assigned into
a variable, passed to an overloaded procedure, ...?).

- Bob

Adam Beneschan

unread,
May 21, 2012, 1:57:25 PM5/21/12
to
On Monday, May 21, 2012 10:04:30 AM UTC-7, Robert A Duff wrote:
"T" is the Vector type from an instance of Ada.Containers.Vectors. The & operators are also from the instance and have been made directly visible with "use". The & operators can take all four combinations of Element&Element, Element&Vector, Vector&Element, Vector&Vector.

-- Adam

0 new messages