From: Phil Clayton on
On Jul 6, 8:36 am, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de>
wrote:
> On Mon, 5 Jul 2010 15:47:41 -0700 (PDT), Phil Clayton wrote:
> > On Jul 5, 2:12 pm, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de>
> > wrote:
> >> On Sun, 4 Jul 2010 18:27:04 -0700 (PDT), Phil Clayton wrote:
> >>> In my view, condition expressions are a step in the right direction....
> >>> but I'm the sort of person who wants to write an array aggregate like
>
> >>>   (for I in 1 .. 5 => (for J in 1 .. 7 => (if I = J then 1.0 else
> >>> 0.0)))
>
> >>   (for I in 1..5 => (for J in 1..7 => Float (Boolean'Pos (I = J))))
>
> > Yep, I should have seen that one coming straight back... and taken
> > steps to avoid it :)
>
> BTW, is your construct 1) a macro expansion (as I remember PL/1
> preprocessor also had %for statement alike) and how far are you ready to go
> allowing "for" macros? Loops unrolling? Or else 2) it is an attempt to name
> the components of an array element index.

Definitely the latter...


> In the latter case
>
>    (I, J : others => <an expression involving I,J>)
>    (I : 1..5 => <an expression involving I>)
>    (Odd : 1 | 3 | 5 | 7 => <an expression involving Odd>, others => 0.0)
>    etc
>
> looks to me more consistent with existing Ada, e.g. when Error : others =>
> in exception handlers.

Interesting. So, considering the difference between

1. X : T
2. for X in T

My take on Ada is that [1] just declares a new variable X of subtype T
(which may be initialized depending on context) whilst [2] is used
when declaring a new variable X of subtype T and then giving X the
values of T in some specified order, i.e. introducing some iteration
scheme. If that is a fair assessment of things, then perhaps

(for I in 1 .. 5 => F(I))

is more in keeping with existing Ada? (If I'm talking absolute
drivel, please let me know...)


The concept of an order is important because the function F could have
side effects in the above example (though I would not advocate that as
good practice). However, we would be able to write

(for I in reverse A'Range => A(I))

to represent the reverse of the array A is perhaps a little confusing.


Also, it really only makes sense to have one variable holding the
array index. For example, if we could write

(I, J : 1 .. 5 => ...)

surely I and J would always be equal: there are only 5 elements in the
array. Having

(for I in 1 .. 5 => ...)

syntactically rules out multiple variables.

Phil
From: Dmitry A. Kazakov on
On Tue, 6 Jul 2010 09:31:05 -0700 (PDT), Phil Clayton wrote:

> The concept of an order is important because the function F could have
> side effects in the above example (though I would not advocate that as
> good practice).

AFAIK, presently the order is not defined. So though this is legal

X : String (1..80) := (others => Character'Read (Stream'Access));

It is not a good idea.

> However, we would be able to write
>
> (for I in reverse A'Range => A(I))
>
> to represent the reverse of the array A is perhaps a little confusing.

The effect is undefined. Theoretically the compiler could initialize array
elements concurrently on a multi-core processor.

> Also, it really only makes sense to have one variable holding the
> array index. For example, if we could write
>
> (I, J : 1 .. 5 => ...)
>
> surely I and J would always be equal: there are only 5 elements in the
> array. Having
>
> (for I in 1 .. 5 => ...)
>
> syntactically rules out multiple variables.

Yes, but many other things as well. However I prefer an absolutely
different approach anyway, e.g. proper index types. In my world a diagonal
would be initialized like:

(Diagonal (5, 5) => 1.0, others => 0.0)

where Diagonal is a proper function.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Phil Clayton on
On Jul 6, 6:18 pm, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de>
wrote:
> On Tue, 6 Jul 2010 09:31:05 -0700 (PDT), Phil Clayton wrote:
> > The concept of an order is important because the function F could have
> > side effects in the above example (though I would not advocate that as
> > good practice).
>
> AFAIK, presently the order is not defined. So though this is legal
>
>    X : String (1..80) := (others => Character'Read (Stream'Access));
>
> It is not a good idea.

It would be good if the order was not defined because that would
prevent people depending on it, so making it easier for a compiler to
parallelize.


> > However, we would be able to write
>
> >   (for I in reverse A'Range => A(I))
>
> > to represent the reverse of the array A is perhaps a little confusing.
>
> The effect is undefined. Theoretically the compiler could initialize array
> elements concurrently on a multi-core processor.

There are really two concepts here:
1. the order of evaluation of the expressions for each index
2. the value the bound variable I gets for each index

I didn't make it clear that I was switching from [1] to [2], sorry.
This above reverse example was really about [2] to show that the use
of the keyword 'reverse' would result in I having the value A'Last at
index A'First, A'Last - 1 at index A'First + 1, etc. I don't think it
matters whether A(I) is evaluated for each index in parallel, so I
think the expression should be well defined.


> > Also, it really only makes sense to have one variable holding the
> > array index.  For example, if we could write
>
> >   (I, J : 1 .. 5 => ...)
>
> > surely I and J would always be equal: there are only 5 elements in the
> > array.  Having
>
> >   (for I in 1 .. 5 => ...)
>
> > syntactically rules out multiple variables.
>
> Yes, but many other things as well. However I prefer an absolutely
> different approach anyway, e.g. proper index types. In my world a diagonal
> would be initialized like:
>
>    (Diagonal (5, 5) => 1.0, others => 0.0)
>
> where Diagonal is a proper function.

Interesting.. how would you make the expression a function of the
index? For example, how would you write

(for I in 3 .. 8 => A(I) + B(I - 2))

?

Phil
From: Dmitry A. Kazakov on
On Wed, 7 Jul 2010 05:00:47 -0700 (PDT), Phil Clayton wrote:

> On Jul 6, 6:18�pm, "Dmitry A. Kazakov" <mail...(a)dmitry-kazakov.de>
> wrote:
>> On Tue, 6 Jul 2010 09:31:05 -0700 (PDT), Phil Clayton wrote:
>>> The concept of an order is important because the function F could have
>>> side effects in the above example (though I would not advocate that as
>>> good practice).
>>
>> AFAIK, presently the order is not defined. So though this is legal
>>
>> � �X : String (1..80) := (others => Character'Read (Stream'Access));
>>
>> It is not a good idea.
>
> It would be good if the order was not defined because that would
> prevent people depending on it, so making it easier for a compiler to
> parallelize.

But then the language should define pure functions (relatively to the given
context) and prohibit usage of impure ones in the constructs like above.

>>> However, we would be able to write
>>
>>> � (for I in reverse A'Range => A(I))
>>
>>> to represent the reverse of the array A is perhaps a little confusing.
>>
>> The effect is undefined. Theoretically the compiler could initialize array
>> elements concurrently on a multi-core processor.
>
> There are really two concepts here:
> 1. the order of evaluation of the expressions for each index
> 2. the value the bound variable I gets for each index
>
> I didn't make it clear that I was switching from [1] to [2], sorry.
> This above reverse example was really about [2] to show that the use
> of the keyword 'reverse' would result in I having the value A'Last at
> index A'First, A'Last - 1 at index A'First + 1, etc.

OK. The objection is that in this case I is not the array's index, but a
mapping of. That looks totally obscure.

>>> Also, it really only makes sense to have one variable holding the
>>> array index. �For example, if we could write
>>
>>> � (I, J : 1 .. 5 => ...)
>>
>>> surely I and J would always be equal: there are only 5 elements in the
>>> array. �Having
>>
>>> � (for I in 1 .. 5 => ...)
>>
>>> syntactically rules out multiple variables.
>>
>> Yes, but many other things as well. However I prefer an absolutely
>> different approach anyway, e.g. proper index types. In my world a diagonal
>> would be initialized like:
>>
>> � �(Diagonal (5, 5) => 1.0, others => 0.0)
>>
>> where Diagonal is a proper function.
>
> Interesting.. how would you make the expression a function of the
> index?

I don't want such expressions at all. I mean if these are necessary it must
be a function returning an array. Reading aggregates containing some
inlined code is not readable to me.

This is yet another topic, but I favor user-defined aggregates instead of
hard coded special stuff like index dependent expressions. E.g. if you have
some frequently used special type of "array literals" you should be able
to provide a custom aggregate of. For example, let you deal with band
matrices. The language should allow you to define a custom aggregate like

A : Square_Matrix :=
( Upper => (1.0, 2.4),
Diagonal => (7.3, 8.0, 9.1),
Lower => (3.0, 2.1) );

P.S. This issue boils down to the interfaces. The point is that you should
be able to implement interface of any type for the given one. A record of
arrays is an interface which has aggregates like above. Hang it on
Square_Matrix and you will be able to do above aggregates and other useful
stuff, like A.Upper.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
First  |  Prev  | 
Pages: 1 2 3 4 5 6
Prev: Ann: Generic Image Decoder v.01
Next: ANN: Tables 1.10