From: tmoran on
> In Ada, if you do "P(X(5..10));" procedure P can see that the
> lower bound is 5. That's a break in the abstraction -- P shouldn't
> know or care where the string came from.
For many, but not all, P.

> Actually, slices are one of the least useful features of Ada.
> I wouldn't mind (much) if they didn't exist in the first place.
Wow, I beg to strongly differ.
From: Robert A Duff on
tmoran(a)acm.org writes:

>> In Ada, if you do "P(X(5..10));" procedure P can see that the
>> lower bound is 5. That's a break in the abstraction -- P shouldn't
>> know or care where the string came from.
> For many, but not all, P.

Can you give an example where P should know that its String
parameter came from a slice, and should know the lower bound
of that slice? I can't think of any off the top of my head
-- it just seems like a fundamentally broken abstraction if
you care about the lower bound of a string.

Just to be clear: I'm talking about Strings here, and other
array types that have a natural lower bound (usually 1,
sometimes 0). I'm not necessarily talking about all
array types -- the discriminated arrays feature I am
imagining would allow the programmer to choose whether
to fix the lower bound at a particular value. Or the upper
bound, or both, or neither.

>> Actually, slices are one of the least useful features of Ada.
>> I wouldn't mind (much) if they didn't exist in the first place.
> Wow, I beg to strongly differ.

OK, I guess I shouldn't have said "least useful". I should have
said that it's easy enough to work around the lack of this
feature. In my experience, almost all slices are of
type String. And almost all are R-values. So a function:

function Slice (S: String; First: Positive; Last: Natural) return String;

would do the trick, at some small efficiency cost. (Note that we
tolerate this interface in the case of unbounded strings.)

Think about it this way: Name some features of Ada that you
would rather do without than slices. I can think of a few,
but not many. It would be much more painful to do without,
say, case statements than slices.

Or think about it this way: Name some features that Ada does
not have that you'd be willing to trade slices for. For example,
I'd love to be able to fix the lower bound of an array type, and I'd
happily do without slices for that. ;-)

And if you want a really useful/powerful slice facility, look to
Fortran!

- Bob
From: Pascal Obry on
Bob,

> OK, I guess I shouldn't have said "least useful". I should have
> said that it's easy enough to work around the lack of this
> feature. In my experience, almost all slices are of
> type String. And almost all are R-values. So a function:
>
> function Slice (S: String; First: Positive; Last: Natural) return String;

I beg to disagree strongly to that too :)

I have lot of code like this one:

S (A .. B) := R (C .. D);

or

S (A .. B) := V;

I would say that slices are really what make life easier in Ada compared
to other languages in many ways.

Pascal.

--

--|------------------------------------------------------
--| 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

From: (see below) on
On 08/02/2010 21:20, in article wccd40fpgpu.fsf(a)shell01.TheWorld.com,
"Robert A Duff" <bobduff(a)shell01.TheWorld.com> wrote:

> It's trivial if you only want slices as R-values.
> And anyway, slices as L-values don't really work:

I can't agree. I have this code:

procedure FFT_to_HWT (FFTCs : in complex_array; ...
HWT_tree : out complex_array; ...) is
....
iFFTCs : complex_array (1..f(FFTCs'length));
begin
....
iFFTCs(1..nr_bins) := FFTCs(first_bin..last_bin);
iFFTCs(nr_bins+1..iFFT_size) := (others => (0.0,0.0));
inverse_FFT(iFFTCs(1..iFFT_size));
....
HWT_tree(next_HWTC..next_HWTC+iFFT_size-1) := iFFTCs(1..iFFT_size);
....
end FFT_to_HWT;

I think that using slices as L-values as well as R-values helps to make this
a lot clearer than it otherwise would be, and probably faster as well.

--
Bill Findlay
<surname><forename> chez blueyonder.co.uk


From: Randy Brukardt on

"(see below)" <yaldnif.w(a)blueyonder.co.uk> wrote in message
news:C7964E2E.135979%yaldnif.w(a)blueyonder.co.uk...
> On 08/02/2010 21:20, in article wccd40fpgpu.fsf(a)shell01.TheWorld.com,
> "Robert A Duff" <bobduff(a)shell01.TheWorld.com> wrote:
>
>> It's trivial if you only want slices as R-values.
>> And anyway, slices as L-values don't really work:
>
> I can't agree. I have this code:
>
> procedure FFT_to_HWT (FFTCs : in complex_array; ...
> HWT_tree : out complex_array; ...) is
> ...
> iFFTCs : complex_array (1..f(FFTCs'length));
> begin
> ...
> iFFTCs(1..nr_bins) := FFTCs(first_bin..last_bin);
> iFFTCs(nr_bins+1..iFFT_size) := (others => (0.0,0.0));
> inverse_FFT(iFFTCs(1..iFFT_size));
> ...
> HWT_tree(next_HWTC..next_HWTC+iFFT_size-1) := iFFTCs(1..iFFT_size);
> ...
> end FFT_to_HWT;
>
> I think that using slices as L-values as well as R-values helps to make
> this
> a lot clearer than it otherwise would be, and probably faster as well.

It's cases like this that make both the pro and con for slices. Expressions
like these are probably easier to read and probably faster than the
equivalent non-slice code.

But on the flip side, it's very hard to get the bounds right (I think I get
these sorts of slices wrong 25% of the time). So you end up spending a lot
of time debugging (at least Ada detects this). Moreover, it's hard to figure
out from the code whether or not the bounds are right -- I'll often end
drawing a picture and plug in various values to see if it makes sense. Case
in point is the first statement; it fails unless last_bin - first_bin + 1 =
nr_bins. So it's not clear how that is saving anything.

Randy.