comp.lang.ada
 help / color / mirror / Atom feed
* Containers - nontrivial element access
@ 2007-10-01 21:55 Maciej Sobczak
  2007-10-01 23:52 ` Alex R. Mosteo
                   ` (4 more replies)
  0 siblings, 5 replies; 43+ messages in thread
From: Maciej Sobczak @ 2007-10-01 21:55 UTC (permalink / raw)


I was thinking recently about what is wrong with the containers
interface. ;-)

Consider the following problem:
There is a record type (for example Person) with a couple of fields
(for example Salary) that together make the whole a bit heavy, so that
unnecessary copying of the whole is to be avoided. Objects of this
type are stored in the container.

I would like to swap salaries of two guys which I can refer with the
index/iterator/cursor/etc. The reference method is not really
important - what is important is the problem of modifying more than
one element in the container.

C++ example is easy:

vector<Person> people;
// ...
swap(people[x].salary, people[y].salary);

I hope it is obvious what it does (suppose x and y are some indices
into the vector). Just in case it isn't - all the components of the
two records stay intact except the salary, which is swapped between
the two. C++ makes it possible by explicitly returning a reference
from the method that accesses the element.

What would you suggest as the Ada solution for this problem?

The Update_Element procedure with its access to the user-provided
modifying procedure requires to pass data "under the table" (like with
a separate variable declared aside the modifying procedure) - and
seems to be just clunky. Is this the only possibility?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-01 21:55 Containers - nontrivial element access Maciej Sobczak
@ 2007-10-01 23:52 ` Alex R. Mosteo
  2007-10-02 16:40   ` Matthew Heaney
  2007-10-02 20:47   ` Maciej Sobczak
  2007-10-02  0:39 ` Jeffrey R. Carter
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 43+ messages in thread
From: Alex R. Mosteo @ 2007-10-01 23:52 UTC (permalink / raw)


Maciej Sobczak wrote:

> I was thinking recently about what is wrong with the containers
> interface. ;-)
> 
> Consider the following problem:
> There is a record type (for example Person) with a couple of fields
> (for example Salary) that together make the whole a bit heavy, so that
> unnecessary copying of the whole is to be avoided. Objects of this
> type are stored in the container.
> 
> I would like to swap salaries of two guys which I can refer with the
> index/iterator/cursor/etc. The reference method is not really
> important - what is important is the problem of modifying more than
> one element in the container.
> 
> C++ example is easy:
> 
> vector<Person> people;
> // ...
> swap(people[x].salary, people[y].salary);
> 
> I hope it is obvious what it does (suppose x and y are some indices
> into the vector). Just in case it isn't - all the components of the
> two records stay intact except the salary, which is swapped between
> the two. C++ makes it possible by explicitly returning a reference
> from the method that accesses the element.
> 
> What would you suggest as the Ada solution for this problem?
> 
> The Update_Element procedure with its access to the user-provided
> modifying procedure requires to pass data "under the table" (like with
> a separate variable declared aside the modifying procedure) - and
> seems to be just clunky. Is this the only possibility?

I don't think that's reproducible as-is with the standard containers. It
must be more verbose. There's no way to get a reference to the element in
the Ada containers (unless you want to go the 'Unrestricted_Access way
inside Update_Element, but that would require anyway extending the standard
containers), so you can have dangling cursors but no dangling pointers. 

I'm not sure the solution is clunky, unless you consider verbose=clunky.
Local scope subprograms seems just the kind of feature to do this. Then
again, it may get *very* verbose specially when comparing to your
one-liner. And subsets like SPARK may forbid it altogether, although
dynamically allocating containers may be out of the picture when using
SPARK anyway.

There are additional differences, if I'm not mistaken (my C++ is a bit
outdated). [] is, I think, unchecked (unlike .at()), so you could get a
violation with that code that shouldn't be possible in Ada. 

There was a recent thread (started by myself) on the amount of copying
involved in the use of the containers. Someone said that returning accesses
was deemed too unsafe and thus dropped, IIRC. I have not a strong position
on if dangling cursors is a great improvement over dangling accesses, given
what we gain/lose; in my experience a dangling cursor has been always as
bad as a dangling pointer, in the sense that the program was erroneous
beyond recovery; admittedly I have never got a memory violation using the
containers so post-hoc diagnostics are quicker.

Leaving scope issues aside (I'm too tired now to think about the differences
between the C++ and Ada designs), references in C++ is one of my
loved/hated features. I'm obsessed with them, they're really powerful and
give you a great deal of control (but also over things I'd prefer not to
have to worry about). On the other side, I see people getting confused with
them so easily, specially people coming from other non-CS disciplines, that
I'm somehow glad not to have to deal with them in Ada in a cooperative
context.

> 
> --
> Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-01 21:55 Containers - nontrivial element access Maciej Sobczak
  2007-10-01 23:52 ` Alex R. Mosteo
@ 2007-10-02  0:39 ` Jeffrey R. Carter
  2007-10-02 16:44   ` Matthew Heaney
  2007-10-02 20:50   ` Maciej Sobczak
  2007-10-02  2:34 ` Randy Brukardt
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 43+ messages in thread
From: Jeffrey R. Carter @ 2007-10-02  0:39 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> vector<Person> people;
> // ...
> swap(people[x].salary, people[y].salary);

You have to compare apples to apples. In C/++, everything is aliased, so 
you have to make everything aliased on the Ada side, too. That means you 
store access values, not objects. Then you have something similar:

Swap (Left  => People.Element (Left).Salary,
       Right => People.Element (Right).Salary);

-- 
Jeff Carter
"This trial is a travesty. It's a travesty of a mockery of a
sham of a mockery of a travesty of two mockeries of a sham. ...
Do you realize there's not a single homosexual on that jury?"
Bananas
27



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

* Re: Containers - nontrivial element access
  2007-10-01 21:55 Containers - nontrivial element access Maciej Sobczak
  2007-10-01 23:52 ` Alex R. Mosteo
  2007-10-02  0:39 ` Jeffrey R. Carter
@ 2007-10-02  2:34 ` Randy Brukardt
  2007-10-02 16:47   ` Matthew Heaney
  2007-10-02  7:23 ` Dmitry A. Kazakov
  2007-10-02 16:37 ` Matthew Heaney
  4 siblings, 1 reply; 43+ messages in thread
From: Randy Brukardt @ 2007-10-02  2:34 UTC (permalink / raw)


"Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message
news:1191275759.184463.238350@n39g2000hsh.googlegroups.com...
...
> I would like to swap salaries of two guys which I can refer with the
> index/iterator/cursor/etc. The reference method is not really
> important - what is important is the problem of modifying more than
> one element in the container.

Why don't you just use the Swap operation of the containers? One would
presume that it is implemented as efficiently as possible. (Surely if you
are using the indefinite version of the containers, it would just be a
pointer swap; might be a copy with the definite version of vectors, but that
couldn't be avoided as the object order is significant in that sort of
implementation.)

That surely seems better than using explicit pointers; in most cases,
worries about efficiency are premature (and when they're not, you probably
shouldn't be using the predefined containers anyway).

                               Randy.





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

* Re: Containers - nontrivial element access
  2007-10-01 21:55 Containers - nontrivial element access Maciej Sobczak
                   ` (2 preceding siblings ...)
  2007-10-02  2:34 ` Randy Brukardt
@ 2007-10-02  7:23 ` Dmitry A. Kazakov
  2007-10-02 16:37 ` Matthew Heaney
  4 siblings, 0 replies; 43+ messages in thread
From: Dmitry A. Kazakov @ 2007-10-02  7:23 UTC (permalink / raw)


On Mon, 01 Oct 2007 14:55:59 -0700, Maciej Sobczak wrote:

> I was thinking recently about what is wrong with the containers
> interface. ;-)

You compare two paradigms functional (closure, to access an element) and
non-functional (explicit element access). They both are complete, in some
sense. Yes functional is often counterintuitive, and I don't like it
either.

> What would you suggest as the Ada solution for this problem?

I would use handles to elements and containers of handles.
 
> The Update_Element procedure with its access to the user-provided
> modifying procedure requires to pass data "under the table" (like with
> a separate variable declared aside the modifying procedure) - and
> seems to be just clunky. Is this the only possibility?

So one could add access closures to "a pair of elements" to containers:
Update_Two_Elements, (and then a triple, and etc (:-))

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



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

* Re: Containers - nontrivial element access
  2007-10-01 21:55 Containers - nontrivial element access Maciej Sobczak
                   ` (3 preceding siblings ...)
  2007-10-02  7:23 ` Dmitry A. Kazakov
@ 2007-10-02 16:37 ` Matthew Heaney
  2007-10-02 21:02   ` Maciej Sobczak
  4 siblings, 1 reply; 43+ messages in thread
From: Matthew Heaney @ 2007-10-02 16:37 UTC (permalink / raw)


On Oct 1, 5:55 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> There is a record type (for example Person) with a couple of fields
> (for example Salary) that together make the whole a bit heavy, so that
> unnecessary copying of the whole is to be avoided. Objects of this
> type are stored in the container.

Right, so you probably want to avoid operations Element or
Replace_Element, and use Query_Element or Update_Element instead.


> I would like to swap salaries of two guys which I can refer with the
> index/iterator/cursor/etc. The reference method is not really
> important - what is important is the problem of modifying more than
> one element in the container.
>
> C++ example is easy:
>
> vector<Person> people;
> // ...
> swap(people[x].salary, people[y].salary);


V : Person_Vectors.Vector;

declare
   procedure Process_X (PX : in out Person) is
      procedure Process_Y (PY : in out Person) is
         SX : constant Salary_Type := PX.Salary;
      begin
         PX.Salary := PY.Salary;
         PY.Salary := SX;
      end;
   begin
      V.Update_Element (Y, Process_Y'Access);
   end;
begin
   V.Update_Element (X, Process_X'Access);
end;



> I hope it is obvious what it does (suppose x and y are some indices
> into the vector). Just in case it isn't - all the components of the
> two records stay intact except the salary, which is swapped between
> the two. C++ makes it possible by explicitly returning a reference
> from the method that accesses the element.

Right, but Ada doesn't have explicit reference types, so you have to
use Update_Element, which allows in-place editing.


> What would you suggest as the Ada solution for this problem?

See above.


> The Update_Element procedure with its access to the user-provided
> modifying procedure requires to pass data "under the table" (like with
> a separate variable declared aside the modifying procedure) - and
> seems to be just clunky. Is this the only possibility?

I don't understand what you think the problem is.  There is no need
for a separate variable or anything else.





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

* Re: Containers - nontrivial element access
  2007-10-01 23:52 ` Alex R. Mosteo
@ 2007-10-02 16:40   ` Matthew Heaney
  2007-10-02 23:16     ` Alex R. Mosteo
  2007-10-02 20:47   ` Maciej Sobczak
  1 sibling, 1 reply; 43+ messages in thread
From: Matthew Heaney @ 2007-10-02 16:40 UTC (permalink / raw)


On Oct 1, 7:52 pm, "Alex R. Mosteo" <devn...@mailinator.com> wrote:
>
> I don't think that's reproducible as-is with the standard containers. It
> must be more verbose. There's no way to get a reference to the element in
> the Ada containers (unless you want to go the 'Unrestricted_Access way
> inside Update_Element, but that would require anyway extending the standard
> containers), so you can have dangling cursors but no dangling pointers.

If this is a vector, you can use index values.


> There was a recent thread (started by myself) on the amount of copying
> involved in the use of the containers. Someone said that returning accesses
> was deemed too unsafe and thus dropped, IIRC. I have not a strong position
> on if dangling cursors is a great improvement over dangling accesses, given
> what we gain/lose; in my experience a dangling cursor has been always as
> bad as a dangling pointer, in the sense that the program was erroneous
> beyond recovery; admittedly I have never got a memory violation using the
> containers so post-hoc diagnostics are quicker.

If you're using GNAT, then compile the container instantiations with -
gnata, and the container will detect dangling cursors.  Try it!




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

* Re: Containers - nontrivial element access
  2007-10-02  0:39 ` Jeffrey R. Carter
@ 2007-10-02 16:44   ` Matthew Heaney
  2007-10-03  0:20     ` Jeffrey R. Carter
  2007-10-02 20:50   ` Maciej Sobczak
  1 sibling, 1 reply; 43+ messages in thread
From: Matthew Heaney @ 2007-10-02 16:44 UTC (permalink / raw)


On Oct 1, 8:39 pm, "Jeffrey R. Carter"
<spam.jrcarter....@acm.nospam.org> wrote:

> You have to compare apples to apples. In C/++, everything is aliased, so
> you have to make everything aliased on the Ada side, too. That means you
> store access values, not objects.

But then you're not comparing apples to apples.  This problem has a
straight-forward solution, as I demonstrated in my earlier post.


>Then you have something similar:
>
> Swap (Left  => People.Element (Left).Salary,
>        Right => People.Element (Right).Salary);

This is far less safe then simply using Update_Element in nested
fashion.





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

* Re: Containers - nontrivial element access
  2007-10-02  2:34 ` Randy Brukardt
@ 2007-10-02 16:47   ` Matthew Heaney
  0 siblings, 0 replies; 43+ messages in thread
From: Matthew Heaney @ 2007-10-02 16:47 UTC (permalink / raw)


On Oct 1, 10:34 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:

> Why don't you just use the Swap operation of the containers? One would
> presume that it is implemented as efficiently as possible. (Surely if you
> are using the indefinite version of the containers, it would just be a
> pointer swap; might be a copy with the definite version of vectors, but that
> couldn't be avoided as the object order is significant in that sort of
> implementation.)

But he's trying to swap one component of a element (which happens to
be a record).  The swap operation for container swaps entire elements,
which is not what he wants.

> That surely seems better than using explicit pointers; in most cases,
> worries about efficiency are premature (and when they're not, you probably
> shouldn't be using the predefined containers anyway).

Agreed, you certainly don't need explicit pointers to solve thish
problem.  The solution I showed in my earlier post does exact what the
C++ solution does; there is no effciciency issue.






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

* Re: Containers - nontrivial element access
  2007-10-01 23:52 ` Alex R. Mosteo
  2007-10-02 16:40   ` Matthew Heaney
@ 2007-10-02 20:47   ` Maciej Sobczak
  2007-10-02 23:23     ` Alex R. Mosteo
  1 sibling, 1 reply; 43+ messages in thread
From: Maciej Sobczak @ 2007-10-02 20:47 UTC (permalink / raw)


On 2 Pa , 01:52, "Alex R. Mosteo" <devn...@mailinator.com> wrote:

> I'm not sure the solution is clunky, unless you consider verbose=clunky.

The point is that in order to swap data, you need to pass the new
value to the modifying procedure. Since there are no on-the-fly
binders, this value has to be provided by additional variable, which
exists outside of the procedure, which access is passed. This looks
like a dodgy hack: I provide a procedure, which is not self-contained
anyway, so I also sneak around the value.

I have nothing against the procedure, even if it is longer (/= clunky)
than what I can do in C++. I have, however, a *serious* problem with
sneaking this value around.
This *is* clunky.

> There are additional differences, if I'm not mistaken (my C++ is a bit
> outdated). [] is, I think, unchecked (unlike .at()), so you could get a
> violation with that code that shouldn't be possible in Ada.

You are half right. The standard does not require [] to be checked. It
does not forbid it, either.

The point is not about [], actually, but about references. I might
have written my example like this:

swap(people.at(x).salary, people.at(y).salary);

and then you would not have been able to nit-pick on the possible
violation. :-)

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-02  0:39 ` Jeffrey R. Carter
  2007-10-02 16:44   ` Matthew Heaney
@ 2007-10-02 20:50   ` Maciej Sobczak
  2007-10-03  0:22     ` Jeffrey R. Carter
  1 sibling, 1 reply; 43+ messages in thread
From: Maciej Sobczak @ 2007-10-02 20:50 UTC (permalink / raw)


On 2 Pa , 02:39, "Jeffrey R. Carter"
<spam.jrcarter....@acm.nospam.org> wrote:

> You have to compare apples to apples. In C/++, everything is aliased, so
> you have to make everything aliased on the Ada side, too. That means you
> store access values, not objects.

I'm not convinced. I don't want to change the design of the data
structure only to support some obvious access pattern.
In particular, the data structure might be already there, and I might
just have to deal with new requirement of swapping salaries. I hope it
is clear that in this context changing the data structure is not
feasible.

I know that I compare apples to oranges. My point is that I should not
have to do it.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-02 16:37 ` Matthew Heaney
@ 2007-10-02 21:02   ` Maciej Sobczak
  2007-10-02 22:20     ` Matthew Heaney
  0 siblings, 1 reply; 43+ messages in thread
From: Maciej Sobczak @ 2007-10-02 21:02 UTC (permalink / raw)


On 2 Pa , 18:37, Matthew Heaney <mhea...@on2.com> wrote:

> V : Person_Vectors.Vector;
>
> declare
>    procedure Process_X (PX : in out Person) is
>       procedure Process_Y (PY : in out Person) is
>          SX : constant Salary_Type := PX.Salary;
>       begin
>          PX.Salary := PY.Salary;
>          PY.Salary := SX;
>       end;
>    begin
>       V.Update_Element (Y, Process_Y'Access);
>    end;
> begin
>    V.Update_Element (X, Process_X'Access);
> end;

I have mixed feelings about this example.

I like it, because it solves the problem without requiring any
additional variable.
I don't like it, because it imposes some artificial assymetry (one of
the procedures has to be nested) where the problem is strictly
symmetrical.

OK, this assymetry stuff is nit-picking. I accept this as a valid
solution, even though it is not even close in readability to my
initial C++ example.

BTW - above, PX plays the role of that additional variable that is
sneaked around to the second procedure. Here it just pretends to not
exist by taking the form of a parameter in the outer procedure. I
don't think there is a reasonable way to avoid it.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-02 21:02   ` Maciej Sobczak
@ 2007-10-02 22:20     ` Matthew Heaney
  2007-10-03 19:59       ` Maciej Sobczak
  0 siblings, 1 reply; 43+ messages in thread
From: Matthew Heaney @ 2007-10-02 22:20 UTC (permalink / raw)


On Oct 2, 5:02 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> BTW - above, PX plays the role of that additional variable that is
> sneaked around to the second procedure. Here it just pretends to not
> exist by taking the form of a parameter in the outer procedure. I
> don't think there is a reasonable way to avoid it.

The number of "additional variables" is exactly the same in both the C+
+ and Ada examples.  The only difference is how the variables are
named.





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

* Re: Containers - nontrivial element access
  2007-10-02 16:40   ` Matthew Heaney
@ 2007-10-02 23:16     ` Alex R. Mosteo
  0 siblings, 0 replies; 43+ messages in thread
From: Alex R. Mosteo @ 2007-10-02 23:16 UTC (permalink / raw)


Matthew Heaney wrote:

> On Oct 1, 7:52 pm, "Alex R. Mosteo" <devn...@mailinator.com> wrote:
>>
>> I don't think that's reproducible as-is with the standard containers. It
>> must be more verbose. There's no way to get a reference to the element in
>> the Ada containers (unless you want to go the 'Unrestricted_Access way
>> inside Update_Element, but that would require anyway extending the
>> standard containers), so you can have dangling cursors but no dangling
>> pointers.
> 
> If this is a vector, you can use index values.

Yep, I was just talking in general. In any case one has to go to some
lengths to get dangling cursors; in typical usage this has *very very*
rarely happened to me.

> 
> 
>> There was a recent thread (started by myself) on the amount of copying
>> involved in the use of the containers. Someone said that returning
>> accesses was deemed too unsafe and thus dropped, IIRC. I have not a
>> strong position on if dangling cursors is a great improvement over
>> dangling accesses, given what we gain/lose; in my experience a dangling
>> cursor has been always as bad as a dangling pointer, in the sense that
>> the program was erroneous beyond recovery; admittedly I have never got a
>> memory violation using the containers so post-hoc diagnostics are
>> quicker.
> 
> If you're using GNAT, then compile the container instantiations with -
> gnata, and the container will detect dangling cursors.  Try it!

Ummm, perhaps I'm confused. IIRC, the dangling cursor is detected once you
try to use it, not if the container goes out of scope or the element is
removed by other means than that cursor. Is this what you mean? I'm not
trying to imply otherwise.



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

* Re: Containers - nontrivial element access
  2007-10-02 20:47   ` Maciej Sobczak
@ 2007-10-02 23:23     ` Alex R. Mosteo
  0 siblings, 0 replies; 43+ messages in thread
From: Alex R. Mosteo @ 2007-10-02 23:23 UTC (permalink / raw)


Maciej Sobczak wrote:

> On 2 Pa , 01:52, "Alex R. Mosteo" <devn...@mailinator.com> wrote:
> 
>> I'm not sure the solution is clunky, unless you consider verbose=clunky.
> 
> The point is that in order to swap data, you need to pass the new
> value to the modifying procedure. Since there are no on-the-fly
> binders, this value has to be provided by additional variable, which
> exists outside of the procedure, which access is passed. This looks
> like a dodgy hack: I provide a procedure, which is not self-contained
> anyway, so I also sneak around the value.

Uh? I think Matthew's solution doesn't use anything extra?

Further example: imagine that containers had this subprogram:

procedure Operate 
  (This : in out Vector;
   I, J :        Index_Type;
   Op   : access not null procedure (L, R : in out Element_Type));

Now, this Operate procedure does Matthew's nested accessing in place and
calls the provided Op procedure. Swapping (or anything else) would be:

declare
   procedure Swap (L, R : in out Whatever) is
   -- You know the deal
begin
   My_Vector.Operate (X, Y, Swap'Access);
end;

Does it look good? This isn't in the containers, but you can provide it
yourself. Is what I thought of yesterday night, but I (mistakenly) thought
you were more concerned with verbosity so I didn't bothered to exemplify.

> 
> I have nothing against the procedure, even if it is longer (/= clunky)
> than what I can do in C++. I have, however, a *serious* problem with
> sneaking this value around.
> This *is* clunky.

Can you summarize it for me? Is Matthew's solution satisfactory? I've passed
a bit fast over the thread :)

> 
>> There are additional differences, if I'm not mistaken (my C++ is a bit
>> outdated). [] is, I think, unchecked (unlike .at()), so you could get a
>> violation with that code that shouldn't be possible in Ada.
> 
> You are half right. The standard does not require [] to be checked. It
> does not forbid it, either.
> 
> The point is not about [], actually, but about references. I might
> have written my example like this:
> 
> swap(people.at(x).salary, people.at(y).salary);
> 
> and then you would not have been able to nit-pick on the possible
> violation. :-)

Of course :). It was just something that came to me when reading your post
and just throw it in with the rest of the lot.

> 
> --
> Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-02 16:44   ` Matthew Heaney
@ 2007-10-03  0:20     ` Jeffrey R. Carter
  2007-10-03 19:40       ` Maciej Sobczak
  0 siblings, 1 reply; 43+ messages in thread
From: Jeffrey R. Carter @ 2007-10-03  0:20 UTC (permalink / raw)


Matthew Heaney wrote:
> 
> This is far less safe then simply using Update_Element in nested
> fashion.

Sure, I wouldn't recommend it, any more than I'd recommend using C/++. 
But since C/++ uses reference semantics, while Ada uses value semantics, 
this kind of mess is needed to get something in the C/++ spirit.

-- 
Jeff Carter
"Every sperm is sacred."
Monty Python's the Meaning of Life
55



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

* Re: Containers - nontrivial element access
  2007-10-02 20:50   ` Maciej Sobczak
@ 2007-10-03  0:22     ` Jeffrey R. Carter
  2007-10-03  8:26       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 43+ messages in thread
From: Jeffrey R. Carter @ 2007-10-03  0:22 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> I know that I compare apples to oranges. My point is that I should not
> have to do it.

You must. C++ is based on widespread use of reference semantics; Ada on 
value semantics. Any non-trivial comparison compares reference semantics 
to value semantics, also known as apples to oranges.

-- 
Jeff Carter
"Every sperm is sacred."
Monty Python's the Meaning of Life
55



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

* Re: Containers - nontrivial element access
  2007-10-03  0:22     ` Jeffrey R. Carter
@ 2007-10-03  8:26       ` Dmitry A. Kazakov
  2007-10-03 18:49         ` Jeffrey R. Carter
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry A. Kazakov @ 2007-10-03  8:26 UTC (permalink / raw)


On Wed, 03 Oct 2007 00:22:24 GMT, Jeffrey R. Carter wrote:

> You must. C++ is based on widespread use of reference semantics; Ada on 
> value semantics.

How so? Ada abstracts by-value/reference issue away (except for some
special cases). Whether an in-out parameter is passed by reference or by
value is not a question of sematic in Ada.

> Any non-trivial comparison compares reference semantics 
> to value semantics, also known as apples to oranges.

This is IMO utterly wrong. The semantics of swapping element's fields is
well-defined independently on the way of access. In question in not the
semantics of, but the syntax sugar, namely an array-like indexing of the
container.

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



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

* Re: Containers - nontrivial element access
  2007-10-03  8:26       ` Dmitry A. Kazakov
@ 2007-10-03 18:49         ` Jeffrey R. Carter
  2007-10-03 19:09           ` Matthew Heaney
                             ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Jeffrey R. Carter @ 2007-10-03 18:49 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> 
> How so? Ada abstracts by-value/reference issue away (except for some
> special cases). Whether an in-out parameter is passed by reference or by
> value is not a question of sematic in Ada.

I'm not discussing parameter-passing mechanisms.

> This is IMO utterly wrong. The semantics of swapping element's fields is
> well-defined independently on the way of access. In question in not the
> semantics of, but the syntax sugar, namely an array-like indexing of the
> container.

Swapping was only an example. Essentially, the OP was looking for the
ability to do

People.Element (X).Salary := S;

and have it modify the value in the data structure.

C++ uses reference semantics, so that a modification of a field modifies 
the value in the data structure. Ada uses value semantics, so that 
modification of a field does not modify the value in the data structure.

-- 
Jeff Carter
"Spam! Spam! Spam! Spam! Spam! Spam! Spam! Spam!"
Monty Python's Flying Circus
53



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

* Re: Containers - nontrivial element access
  2007-10-03 18:49         ` Jeffrey R. Carter
@ 2007-10-03 19:09           ` Matthew Heaney
  2007-10-03 19:15           ` Simon Wright
  2007-10-03 19:35           ` Dmitry A. Kazakov
  2 siblings, 0 replies; 43+ messages in thread
From: Matthew Heaney @ 2007-10-03 19:09 UTC (permalink / raw)


On Oct 3, 2:49 pm, "Jeffrey R. Carter"
<spam.jrcarter....@acm.nospam.org> wrote:
>
> People.Element (X).Salary := S;
>
> and have it modify the value in the data structure.
>
> C++ uses reference semantics,

No, C++ has explicit reference types.  Ada of course has "reference
semantics" too, for composite types (at the discretion of the
implementation), for tagged types, and for limited types that are
"inherently" limited.

The C++ STL declares the index operator to return a reference to the
element:

   value_type& operator[](size_type);
   const value_type& operator[](size_type) const;

Of course, the C++ has by-value passing too.  The C++ STL uses by-
value passing for some of its operations, e.g.

   iterator operator++(int);  //post-fix form of inc operator

In fact, any arithmetic operator would have to return its result by-
value.


> so that a modification of a field modifies
> the value in the data structure. Ada uses value semantics,

Ada has both value semantics and reference semantics.  The language
specifies value semantics for some parameter classes (scalar or access
values) and reference semantics for others (tagged, limited, etc).


> so that
> modification of a field does not modify the value in the data structure.

But reference passing mechanism is completely orthogonal to the issue
being able to modify --in situ-- the container element.




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

* Re: Containers - nontrivial element access
  2007-10-03 18:49         ` Jeffrey R. Carter
  2007-10-03 19:09           ` Matthew Heaney
@ 2007-10-03 19:15           ` Simon Wright
  2007-10-03 19:48             ` Maciej Sobczak
  2007-10-03 19:58             ` Matthew Heaney
  2007-10-03 19:35           ` Dmitry A. Kazakov
  2 siblings, 2 replies; 43+ messages in thread
From: Simon Wright @ 2007-10-03 19:15 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@acm.nospam.org> writes:

> C++ uses reference semantics, so that a modification of a field
> modifies the value in the data structure. Ada uses value semantics,
> so that modification of a field does not modify the value in the
> data structure.

I'm no expert, but I would have expected C++ to distinguish given

   struct Foo {
      ...
   };

the three different functions

   Foo return_by_value();
   Foo* return_by_access();
   Foo& return_by_reference();

I wonder what the difference between Foo* and Foo& is? I don't suppose
there's any difference at the object code level? (except Foo* can be
0).

--S



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

* Re: Containers - nontrivial element access
  2007-10-03 18:49         ` Jeffrey R. Carter
  2007-10-03 19:09           ` Matthew Heaney
  2007-10-03 19:15           ` Simon Wright
@ 2007-10-03 19:35           ` Dmitry A. Kazakov
  2 siblings, 0 replies; 43+ messages in thread
From: Dmitry A. Kazakov @ 2007-10-03 19:35 UTC (permalink / raw)


On Wed, 03 Oct 2007 18:49:58 GMT, Jeffrey R. Carter wrote:

> Dmitry A. Kazakov wrote:
>> 
>> This is IMO utterly wrong. The semantics of swapping element's fields is
>> well-defined independently on the way of access. In question in not the
>> semantics of, but the syntax sugar, namely an array-like indexing of the
>> container.
> 
> Swapping was only an example. Essentially, the OP was looking for the
> ability to do
> 
> People.Element (X).Salary := S;
> 
> and have it modify the value in the data structure.

Which is no problem if Element is an array field of records having the
field Salary. Ada does not prescribe whether that would be by reference.
AFAIK, the compiler is allowed to rewrite the whole People if it wanted to.

The compiler is free to choose between the decompositions:

":=" (People.Element (X).Salary, 3)
":=" (People.Element (X), ".Salary", 3)
":=" (People, "Element", X, "Salary", 3)

This freedom is not offered to the developer of a component library.

> C++ uses reference semantics, so that a modification of a field modifies 
> the value in the data structure. Ada uses value semantics, so that 
> modification of a field does not modify the value in the data structure.

? For by-value things Ada compiler just does copy-out / copy-in,
transparently.

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



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

* Re: Containers - nontrivial element access
  2007-10-03  0:20     ` Jeffrey R. Carter
@ 2007-10-03 19:40       ` Maciej Sobczak
  2007-10-03 19:56         ` Matthew Heaney
                           ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Maciej Sobczak @ 2007-10-03 19:40 UTC (permalink / raw)


On 3 Pa , 02:20, "Jeffrey R. Carter"
<spam.jrcarter....@acm.nospam.org> wrote:

> But since C/++ uses reference semantics, while Ada uses value semantics,
> this kind of mess is needed to get something in the C/++ spirit.

Let's leave C++ aside then.

Imagine I haven an *array* of Person(s) and I do this:

Swap (People (X).Salary, People (Y).Salary);

This is Ada.

(is it value semantics for you, btw?)

Now I want to do the same with vector.

In other words, I want to use Ada in the Ada spirit.
What kind of mess do you recommend to achieve it?

If we realize that vector is a generalization of array, is it
revolutionary to expect that the common functionality should have
common interface?

The C++ example was just... an example. I'm sorry if it distracted you
from the real issue.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-03 19:15           ` Simon Wright
@ 2007-10-03 19:48             ` Maciej Sobczak
  2007-10-03 19:58             ` Matthew Heaney
  1 sibling, 0 replies; 43+ messages in thread
From: Maciej Sobczak @ 2007-10-03 19:48 UTC (permalink / raw)


On 3 Pa , 21:15, Simon Wright <simon.j.wri...@mac.com> wrote:

> I'm no expert, but I would have expected C++ to distinguish given
>
>    struct Foo {
>       ...
>    };
>
> the three different functions
>
>    Foo return_by_value();
>    Foo* return_by_access();
>    Foo& return_by_reference();

Yes, it does distinguish them.
Note that first and third version are not distinguishable in syntax at
the call-site (except that only the third one allows to bind to non-
const references).

> I wonder what the difference between Foo* and Foo& is? I don't suppose
> there's any difference at the object code level? (except Foo* can be
> 0).

Foo* can be NULL, and there is no provision for anything at the object
code level.
Actually, this "level" is not relevant at all as far as the language
is concerned.

But in practical terms (standard aside), you can expect that Foo* and
Foo& will not differ at the object level, although things can get more
interesting when the calls are inlined.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-03 19:40       ` Maciej Sobczak
@ 2007-10-03 19:56         ` Matthew Heaney
  2007-10-03 20:21           ` Dmitry A. Kazakov
  2007-10-03 22:02         ` Jeffrey R. Carter
  2007-10-04  0:16         ` Robert A Duff
  2 siblings, 1 reply; 43+ messages in thread
From: Matthew Heaney @ 2007-10-03 19:56 UTC (permalink / raw)


On Oct 3, 3:40 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> Now I want to do the same with vector.

You can -- but you must use a different syntax (as I showed in my
previous post).


> In other words, I want to use Ada in the Ada spirit.
> What kind of mess do you recommend to achieve it?

Well, I don't know if I would describe the technique as "a mess", but
it can be done using nested invocations of Update_Element.


> If we realize that vector is a generalization of array,

No, not really.  (That would be more true of the C++ STL vector
container.)  In the Ada case, a "vector" is simply a container that
directly supports random access.


> is it
> revolutionary to expect that the common functionality should have
> common interface?

But a vector (in Ada) is not a generalization of an array, so the
analogy doesn't hold.




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

* Re: Containers - nontrivial element access
  2007-10-03 19:15           ` Simon Wright
  2007-10-03 19:48             ` Maciej Sobczak
@ 2007-10-03 19:58             ` Matthew Heaney
  1 sibling, 0 replies; 43+ messages in thread
From: Matthew Heaney @ 2007-10-03 19:58 UTC (permalink / raw)


On Oct 3, 3:15 pm, Simon Wright <simon.j.wri...@mac.com> wrote:
> I'm no expert, but I would have expected C++ to distinguish given
>
>    struct Foo {
>       ...
>    };
>
> the three different functions
>
>    Foo return_by_value();
>    Foo* return_by_access();
>    Foo& return_by_reference();

Yes, it does, but in C++ you cannot overload by function return type.




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

* Re: Containers - nontrivial element access
  2007-10-02 22:20     ` Matthew Heaney
@ 2007-10-03 19:59       ` Maciej Sobczak
  2007-10-03 22:55         ` Matthew Heaney
                           ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Maciej Sobczak @ 2007-10-03 19:59 UTC (permalink / raw)


On 3 Pa , 00:20, Matthew Heaney <mhea...@on2.com> wrote:

> > BTW - above, PX plays the role of that additional variable that is
> > sneaked around to the second procedure. Here it just pretends to not
> > exist by taking the form of a parameter in the outer procedure. I
> > don't think there is a reasonable way to avoid it.
>
> The number of "additional variables" is exactly the same in both the C+
> + and Ada examples.  The only difference is how the variables are
> named.

No. The difference is in whether the subprogram's protocol is fully
described by its signature.

Your nested procedures have the signature that gives provisions for
one parameter only. The other one is sneaked in bypassing the
signature (so that the protocol is wider than the signature and this
is not explicit). This hinders analysis.

I can even think about coding standards that explicitly forbid
subprograms that use anything other than what is in their signature
(except for the main subprogram, which might need to access some
library-level objects).

Your solution requires some dose of liberal thinking, which I'm not
easily willing to accept in the language that boasts high-integrity
mindset. ;-)

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




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

* Re: Containers - nontrivial element access
  2007-10-03 19:56         ` Matthew Heaney
@ 2007-10-03 20:21           ` Dmitry A. Kazakov
  2007-10-03 22:37             ` Matthew Heaney
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry A. Kazakov @ 2007-10-03 20:21 UTC (permalink / raw)


On Wed, 03 Oct 2007 12:56:04 -0700, Matthew Heaney wrote:

> But a vector (in Ada) is not a generalization of an array, so the
> analogy doesn't hold.

Egh, but vector is an array, see 1b in:

http://www.thefreedictionary.com/dict.asp?Word=vector

vector
n.
1. Mathematics
a. A quantity, such as velocity, completely specified by a magnitude and a
direction.
b. A one-dimensional array.
c. An element of a vector space.

2. Pathology An organism, such as a mosquito or tick, that carries
disease-causing microorganisms from one host to another.

3. Genetics A bacteriophage, plasmid, or other agent that transfers genetic
material from one cell to another.

4. A force or influence.

5. A course or direction, as of an airplane.

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



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

* Re: Containers - nontrivial element access
  2007-10-03 19:40       ` Maciej Sobczak
  2007-10-03 19:56         ` Matthew Heaney
@ 2007-10-03 22:02         ` Jeffrey R. Carter
  2007-10-04  0:16         ` Robert A Duff
  2 siblings, 0 replies; 43+ messages in thread
From: Jeffrey R. Carter @ 2007-10-03 22:02 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> Imagine I haven an *array* of Person(s) and I do this:
> 
> Swap (People (X).Salary, People (Y).Salary);
> 
> This is Ada.
> 
> (is it value semantics for you, btw?)
> 
> Now I want to do the same with vector.

You can want to do anything, but that's a good way to be disappointed.

Let's deal with the simpler

People (X).Salary := S;

so we're not mislead by the call to Swap.

With an array, there are no operations (subprograms or entries) invoked. 
With a data structure, you must invoke an operation to get at a value 
stored in it. That's what causes the difference. The operations on the 
data structure return values, so modifying them does not change the 
value stored in the data structure.

> In other words, I want to use Ada in the Ada spirit.

No, the Ada spirit is generally to deal with values (as Ada.Containers 
does), not anonymous references, as is common in C/++ and the STL (since 
everything in C/++ is aliased), though one could argue that the addition 
of anonymous access types and values in Ada 95, and its expansion in Ada 
07 (things I don't like; pointers should be as difficult to use as 
possible), changes the spirit.

> If we realize that vector is a generalization of array, is it
> revolutionary to expect that the common functionality should have
> common interface?

If we realize that package Ada.Containers.Vectors is an 
unbounded-sequence data structure (as is Doubly_Linked_Lists), then we 
would not expect anything of the kind. There are hints in the discussion 
and some of the operations that Vectors is intended specifically for an 
array implementation, but an implementation built on top of 
Doubly_Linked_Lists would be perfectly legal and correct. There are 
analogs of array operations, but they are only analogs.

Ada.Containers is quite general and as safe as possible; it is unlikely 
to be appropriate for many applications. It may be that you should write 
your own, with "access Element" prevalent, for your specific needs. If 
not, you'll have to use the syntax and semantics of the existing packages.

-- 
Jeff Carter
"Spam! Spam! Spam! Spam! Spam! Spam! Spam! Spam!"
Monty Python's Flying Circus
53



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

* Re: Containers - nontrivial element access
  2007-10-03 20:21           ` Dmitry A. Kazakov
@ 2007-10-03 22:37             ` Matthew Heaney
  2007-10-04  8:06               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 43+ messages in thread
From: Matthew Heaney @ 2007-10-03 22:37 UTC (permalink / raw)


On Oct 3, 4:21 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
>
> Egh, but vector is an array, see 1b in:

I have no interest engaging in ontological debates.  (I am a
pragmatist, not a Platonist.)  The vector container in the Ada
standard container library (and I'm in a very good position to know!)
is emphatically not a generalization of an Ada array.

My reason for saying that the C++ vector *is* a like an array, and the
Ada vector is *not* like an array, is that in C++ the vector is
guaranteed to be implemented as contiguous array of memory.  There is
a separate container (a deque) that has time and space semantics
different from a vector.

The standard container library in Ada does not make such a
distinction, and the standard vector container can be implemented
using whatever mechanism suits the implementation.  Hence my claim
that the vector (in the Ada standard container library) is not a
generalization of an array.




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

* Re: Containers - nontrivial element access
  2007-10-03 19:59       ` Maciej Sobczak
@ 2007-10-03 22:55         ` Matthew Heaney
  2007-10-04  0:22         ` Robert A Duff
  2007-10-04 13:01         ` Georg Bauhaus
  2 siblings, 0 replies; 43+ messages in thread
From: Matthew Heaney @ 2007-10-03 22:55 UTC (permalink / raw)


On Oct 3, 3:59 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>
> Your solution requires some dose of liberal thinking,

But my solution works!  You are free to criticize it, but you have
nothing to compare it to (at least none that I've seen, or can even
think of).


> which I'm not
> easily willing to accept in the language that boasts high-integrity
> mindset. ;-)

Oh dear, I hope you haven't seen my latest Ada gem:

http://www.adacore.com/2007/09/17/ada-gem-9/

Up-level references galore!




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

* Re: Containers - nontrivial element access
  2007-10-03 19:40       ` Maciej Sobczak
  2007-10-03 19:56         ` Matthew Heaney
  2007-10-03 22:02         ` Jeffrey R. Carter
@ 2007-10-04  0:16         ` Robert A Duff
  2007-10-07  8:41           ` Jacob Sparre Andersen
  2 siblings, 1 reply; 43+ messages in thread
From: Robert A Duff @ 2007-10-04  0:16 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> On 3 Pa , 02:20, "Jeffrey R. Carter"
> <spam.jrcarter....@acm.nospam.org> wrote:
>
>> But since C/++ uses reference semantics, while Ada uses value semantics,
>> this kind of mess is needed to get something in the C/++ spirit.
>
> Let's leave C++ aside then.
>
> Imagine I haven an *array* of Person(s) and I do this:
>
> Swap (People (X).Salary, People (Y).Salary);
>
> This is Ada.
>
> (is it value semantics for you, btw?)
>
> Now I want to do the same with vector.

I agree with you on this point.  Vector and array are basically the same
thing (except vectors can grow), and it's annoying that you have to use
different syntax to deal with them.

In Ada, "array" is built in, and has all kinds of cool features
(aggregates, with full-coverage checking, for example).
It's annoying that vectors can't have all of those features.

- Bob



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

* Re: Containers - nontrivial element access
  2007-10-03 19:59       ` Maciej Sobczak
  2007-10-03 22:55         ` Matthew Heaney
@ 2007-10-04  0:22         ` Robert A Duff
  2007-10-04 13:01         ` Georg Bauhaus
  2 siblings, 0 replies; 43+ messages in thread
From: Robert A Duff @ 2007-10-04  0:22 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> On 3 Pa , 00:20, Matthew Heaney <mhea...@on2.com> wrote:
>
>> > BTW - above, PX plays the role of that additional variable that is
>> > sneaked around to the second procedure. Here it just pretends to not
>> > exist by taking the form of a parameter in the outer procedure. I
>> > don't think there is a reasonable way to avoid it.
>>
>> The number of "additional variables" is exactly the same in both the C+
>> + and Ada examples.  The only difference is how the variables are
>> named.
>
> No. The difference is in whether the subprogram's protocol is fully
> described by its signature.
>
> Your nested procedures have the signature that gives provisions for
> one parameter only. The other one is sneaked in bypassing the
> signature (so that the protocol is wider than the signature and this
> is not explicit). This hinders analysis.

I don't agree.  In Ada, and many other languages, you have to get used
to nested subprograms, and the fact that they can see more-global
stuff.  It's really not a big deal, so long as you keep them small.

> I can even think about coding standards that explicitly forbid
> subprograms that use anything other than what is in their signature
> (except for the main subprogram, which might need to access some
> library-level objects).

I can imagine that, too.  In fact I've seen it.  But it's not really a
good idea.  You can't reasonably do iterators, for example, without some
sort of nested procedures.

> Your solution requires some dose of liberal thinking, which I'm not
> easily willing to accept in the language that boasts high-integrity
> mindset. ;-)

- Bob



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

* Re: Containers - nontrivial element access
  2007-10-03 22:37             ` Matthew Heaney
@ 2007-10-04  8:06               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 43+ messages in thread
From: Dmitry A. Kazakov @ 2007-10-04  8:06 UTC (permalink / raw)


On Wed, 03 Oct 2007 15:37:53 -0700, Matthew Heaney wrote:

> On Oct 3, 4:21 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>>
> My reason for saying that the C++ vector *is* a like an array, and the
> Ada vector is *not* like an array, is that in C++ the vector is
> guaranteed to be implemented as contiguous array of memory.  There is
> a separate container (a deque) that has time and space semantics
> different from a vector.

[ Does RM require contiguous allocation of arrays? I am not sure.]

Anyway, Robert Duff has already expressed what I meant in another
subthread:

"Vector and array are basically the same
thing (except vectors can grow), and it's annoying that you have to use
different syntax to deal with them.

In Ada, "array" is built in, and has all kinds of cool features
(aggregates, with full-coverage checking, for example).
It's annoying that vectors can't have all of those features."

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



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

* Re: Containers - nontrivial element access
  2007-10-03 19:59       ` Maciej Sobczak
  2007-10-03 22:55         ` Matthew Heaney
  2007-10-04  0:22         ` Robert A Duff
@ 2007-10-04 13:01         ` Georg Bauhaus
  2007-10-04 14:01           ` Matthew Heaney
  2007-10-04 21:58           ` Matthew Heaney
  2 siblings, 2 replies; 43+ messages in thread
From: Georg Bauhaus @ 2007-10-04 13:01 UTC (permalink / raw)


Maciej Sobczak wrote:

> Your solution requires some dose of liberal thinking, which I'm not
> easily willing to accept in the language that boasts high-integrity
> mindset. ;-)

To me, nesting procedures seems a still easier
to understand than having to understand what magic (yes!)
f(foo[x].bar, foo[y].bar) will do behind the scenes.

You saw that is was necessary to explain swap() in the first
place because it isn't obvious what it does, and how.
When I just see
   swap(foo[x].bar, foo[y].bar);
   copy(foo[x].bar, foo[y].bar);
will the names let me guess (correctly!) that the two functions
supposedly employ different mechanism and achieve
different effects, if so? BTW, the second line shows
how this isn't explicitly stating things at all: in which
direction would copy() be working?

You said that an Ada solution will pass things below the table
(nesting procedures yielding less immediate visibility (uplevel
references)). IMHO, swap(a[b].c, d[e].c) is passing
things under the carpet below the table.

Why not strive for something like

   swap_salary(c1, c2);
where
   c1, c2: Cursor;

As these all are implementation level thoughts, inviting
proper information hiding in place of hinting to mechanisms
in function names (swap), IMHO.



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

* Re: Containers - nontrivial element access
  2007-10-04 13:01         ` Georg Bauhaus
@ 2007-10-04 14:01           ` Matthew Heaney
  2007-10-04 21:58           ` Matthew Heaney
  1 sibling, 0 replies; 43+ messages in thread
From: Matthew Heaney @ 2007-10-04 14:01 UTC (permalink / raw)


On Oct 4, 9:01 am, Georg Bauhaus <rm.tsoh+bauh...@maps.futureapps.de>
wrote:
> Why not strive for something like
>
>    swap_salary(c1, c2);
> where
>    c1, c2: Cursor;
>
> As these all are implementation level thoughts, inviting
> proper information hiding in place of hinting to mechanisms
> in function names (swap), IMHO.


Right, and you can generalize that further:

generic
   with package VT is new Vectors (<>);
   with procedure Process (I, J : VT.Element_Type);
procedure Generic_Update_Elements_By_Index
  (V    : in out Vector;
   I, J : in VT.Index_Type);


procedure Generic_Update_Elements_By_Index
  (V    : in out Vector;
   I, J : in VT.Index_Type)
is
   procedure Process_I (EI : in out ET) is
      procedure Process_J (EJ : in out ET) is
      begin
         Process (EI, EJ);
      end;
   begin
      V.Update_Element (J, Process_J'Access);
   end;
begin
   V.Update_Element (I, Process_I'Access);
end Generic_Update_Elements_By_Index;


So now you can say:

procedure Swap_Salary (I, J : in out Person) is
   S : constant Salary_Type := I.Salary;
begin
   I.Salary := J.Salary;
   J.Salary := S;
end;

procedure Swap_Salary is
  new Generic_Update_Elements_By_Index
   (People_Vectors.Vector_Type,
    Swap_Salary);

V : Vector;

Swap_Salary (V, I, J);




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

* Re: Containers - nontrivial element access
  2007-10-04 13:01         ` Georg Bauhaus
  2007-10-04 14:01           ` Matthew Heaney
@ 2007-10-04 21:58           ` Matthew Heaney
  1 sibling, 0 replies; 43+ messages in thread
From: Matthew Heaney @ 2007-10-04 21:58 UTC (permalink / raw)


On Oct 4, 9:01 am, Georg Bauhaus <rm.tsoh+bauh...@maps.futureapps.de>
wrote:
>
> Why not strive for something like
>
>    swap_salary(c1, c2);
> where
>    c1, c2: Cursor;

This is not quite right, since you need a variable view of the
container.  You'll have to do something like:

swap_salary(v, c1, c2);

If you want to generalize:

generic
   with package VT is new Vectors (<>);
procedure Generic_Update_Elements
  (V : in out Vector;
   C1, C2 : Cursor,
   Process : access procedure (E1, E2 : in out ET));

So you could say:

procedure Update_Elements is
  new Generic_Update_Elements (People_Vectors);

procedure Swap_Elements (E1, E2 : in out ET);

Update_Elements (V, C1, C2, Swap_Elements'Access);

Of course, you could also pass in Swap_Elements as a generic actual.




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

* Re: Containers - nontrivial element access
  2007-10-04  0:16         ` Robert A Duff
@ 2007-10-07  8:41           ` Jacob Sparre Andersen
  2007-10-11 19:15             ` Robert A Duff
  0 siblings, 1 reply; 43+ messages in thread
From: Jacob Sparre Andersen @ 2007-10-07  8:41 UTC (permalink / raw)


Robert A Duff wrote:

> In Ada, "array" is built in, and has all kinds of cool features
> (aggregates, with full-coverage checking, for example).  It's
> annoying that vectors can't have all of those features.

What is the reason that vectors (and trees and linked lists) aren't
built in, while arrays are?

Greetings,

Jacob
-- 
"Then, after a second or so, nothing continued to happen."



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

* Re: Containers - nontrivial element access
  2007-10-07  8:41           ` Jacob Sparre Andersen
@ 2007-10-11 19:15             ` Robert A Duff
  2007-10-14  4:59               ` Jacob Sparre Andersen
  0 siblings, 1 reply; 43+ messages in thread
From: Robert A Duff @ 2007-10-11 19:15 UTC (permalink / raw)


Jacob Sparre Andersen <sparre@nbi.dk> writes:

> Robert A Duff wrote:
>
>> In Ada, "array" is built in, and has all kinds of cool features
>> (aggregates, with full-coverage checking, for example).  It's
>> annoying that vectors can't have all of those features.
>
> What is the reason that vectors (and trees and linked lists) aren't
> built in, while arrays are?

Building things in tends to make a language much more complicated.
I'd say too many things are built in to Ada already.

Also, there is an open-ended list of things like vectors.
It's impossible to build them ALL in, since there are too many
(and they have not all been invented yet!).  Ideally, if
Ada.Containers.Vectors did not exist, any programmer should be
able to create it (and make it have all the cool features
of arrays).

- Bob



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

* Re: Containers - nontrivial element access
  2007-10-11 19:15             ` Robert A Duff
@ 2007-10-14  4:59               ` Jacob Sparre Andersen
  2007-10-14  7:24                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 43+ messages in thread
From: Jacob Sparre Andersen @ 2007-10-14  4:59 UTC (permalink / raw)


Robert A Duff wrote:
> Jacob Sparre Andersen <sparre@nbi.dk> writes:
>> Robert A Duff wrote:

>> What is the reason that vectors (and trees and linked lists) aren't
>> built in, while arrays are?
>
> Building things in tends to make a language much more complicated.

Yes.

> I'd say too many things are built in to Ada already.

I am not sure I agree (but I haven't tried to create an Ada compiler).

> Also, there is an open-ended list of things like vectors.

Yes.  But why do we stop at arrays, instead of at binary trees or
doubly linked lists?

Greetings,

Jacob
-- 
�For there are only two reasons why war is made against a
 republic: The one, to become lord over her: the other, the
 fear of being occupied by her.�       -- Nicolo Machiavelli



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

* Re: Containers - nontrivial element access
  2007-10-14  4:59               ` Jacob Sparre Andersen
@ 2007-10-14  7:24                 ` Dmitry A. Kazakov
  2007-10-14 13:49                   ` Georg Bauhaus
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry A. Kazakov @ 2007-10-14  7:24 UTC (permalink / raw)


On Sun, 14 Oct 2007 06:59:16 +0200, Jacob Sparre Andersen wrote:

> Yes.  But why do we stop at arrays, instead of at binary trees or
> doubly linked lists?

And why have we started at arrays? With their dopes, index types, slices
etc? The least aggregation primitive is pair. The question is what is the
minimal set of primitives [complete + extensible + readable].

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



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

* Re: Containers - nontrivial element access
  2007-10-14  7:24                 ` Dmitry A. Kazakov
@ 2007-10-14 13:49                   ` Georg Bauhaus
  2007-10-14 15:07                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 43+ messages in thread
From: Georg Bauhaus @ 2007-10-14 13:49 UTC (permalink / raw)



On Sun, 2007-10-14 at 09:24 +0200, Dmitry A. Kazakov wrote:
> On Sun, 14 Oct 2007 06:59:16 +0200, Jacob Sparre Andersen wrote:
> 
> > Yes.  But why do we stop at arrays, instead of at binary trees or
> > doubly linked lists?
> 
> And why have we started at arrays? With their dopes, index types, slices
> etc?

I guess because of the ways computers were built, and used.

>  The least aggregation primitive is pair.

CAR + CDR?






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

* Re: Containers - nontrivial element access
  2007-10-14 13:49                   ` Georg Bauhaus
@ 2007-10-14 15:07                     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 43+ messages in thread
From: Dmitry A. Kazakov @ 2007-10-14 15:07 UTC (permalink / raw)


On Sun, 14 Oct 2007 15:49:21 +0200, Georg Bauhaus wrote:

> On Sun, 2007-10-14 at 09:24 +0200, Dmitry A. Kazakov wrote:
>> On Sun, 14 Oct 2007 06:59:16 +0200, Jacob Sparre Andersen wrote:
>> 
>>> Yes.  But why do we stop at arrays, instead of at binary trees or
>>> doubly linked lists?
>> 
>> And why have we started at arrays? With their dopes, index types, slices
>> etc?
> 
> I guess because of the ways computers were built, and used.

Were used compilers, or languages?

>>  The least aggregation primitive is pair.
> 
> CAR + CDR?

These are operations on an ordered tuple. I think unordered containers
could be useful.

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



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

end of thread, other threads:[~2007-10-14 15:07 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-01 21:55 Containers - nontrivial element access Maciej Sobczak
2007-10-01 23:52 ` Alex R. Mosteo
2007-10-02 16:40   ` Matthew Heaney
2007-10-02 23:16     ` Alex R. Mosteo
2007-10-02 20:47   ` Maciej Sobczak
2007-10-02 23:23     ` Alex R. Mosteo
2007-10-02  0:39 ` Jeffrey R. Carter
2007-10-02 16:44   ` Matthew Heaney
2007-10-03  0:20     ` Jeffrey R. Carter
2007-10-03 19:40       ` Maciej Sobczak
2007-10-03 19:56         ` Matthew Heaney
2007-10-03 20:21           ` Dmitry A. Kazakov
2007-10-03 22:37             ` Matthew Heaney
2007-10-04  8:06               ` Dmitry A. Kazakov
2007-10-03 22:02         ` Jeffrey R. Carter
2007-10-04  0:16         ` Robert A Duff
2007-10-07  8:41           ` Jacob Sparre Andersen
2007-10-11 19:15             ` Robert A Duff
2007-10-14  4:59               ` Jacob Sparre Andersen
2007-10-14  7:24                 ` Dmitry A. Kazakov
2007-10-14 13:49                   ` Georg Bauhaus
2007-10-14 15:07                     ` Dmitry A. Kazakov
2007-10-02 20:50   ` Maciej Sobczak
2007-10-03  0:22     ` Jeffrey R. Carter
2007-10-03  8:26       ` Dmitry A. Kazakov
2007-10-03 18:49         ` Jeffrey R. Carter
2007-10-03 19:09           ` Matthew Heaney
2007-10-03 19:15           ` Simon Wright
2007-10-03 19:48             ` Maciej Sobczak
2007-10-03 19:58             ` Matthew Heaney
2007-10-03 19:35           ` Dmitry A. Kazakov
2007-10-02  2:34 ` Randy Brukardt
2007-10-02 16:47   ` Matthew Heaney
2007-10-02  7:23 ` Dmitry A. Kazakov
2007-10-02 16:37 ` Matthew Heaney
2007-10-02 21:02   ` Maciej Sobczak
2007-10-02 22:20     ` Matthew Heaney
2007-10-03 19:59       ` Maciej Sobczak
2007-10-03 22:55         ` Matthew Heaney
2007-10-04  0:22         ` Robert A Duff
2007-10-04 13:01         ` Georg Bauhaus
2007-10-04 14:01           ` Matthew Heaney
2007-10-04 21:58           ` Matthew Heaney

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