comp.lang.ada
 help / color / mirror / Atom feed
* syntaxic exploration
@ 2017-12-20 17:28 Mehdi Saada
  2017-12-20 17:32 ` Mehdi Saada
                   ` (7 more replies)
  0 siblings, 8 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-20 17:28 UTC (permalink / raw)


I'm being modelizing polynomes. I've got those two things: p_poly_v1_g.adb:51:21: iterable name cannot be a discriminant-dependent component of a mutable object
Ah ? So I can't write that ?
return RESULTAT : T_POLYNOME := POLY do
        for ELEMENT of RESULTAT.COEF loop
                ELEMENT := - ELEMENT;
        end loop;
end return;

I've got that too:
p_poly_v1_g.adb:59:86: selector name should be identifier or "others"

return RES: T_POLYNOME := (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),POLY_A.COEF'Range => POLY_A.COEF, others => Nulle) do

I thought X'Range was strictly equivalent to X'First..X'Last ? Of course, poly is a mutable article, with two components, Degre (derived from NATURAL), and COEF, array. 

I have that too:
for IND in POLY_R.COEF'Range loop
      POLY_R.COEF(IND) := POLY_R.COEF(IND)*(IND+1);
end loop;

COEF's elements of T_RATIONNEL type, themselves record types. IND is of type T_DEGRE, so why do I have that:
p_poly_v1_g.adb:73:43: expected type "Standard.Integer"
p_poly_v1_g.adb:73:43: found private type "T_Rationnel" 

Thanks !

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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
@ 2017-12-20 17:32 ` Mehdi Saada
  2017-12-20 20:08   ` Niklas Holsti
  2017-12-21  7:21   ` Randy Brukardt
  2017-12-20 20:05 ` Niklas Holsti
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-20 17:32 UTC (permalink / raw)


Hum, how do I write a array component with one element ? Something like (_discriminant_, (0)) (array starting from 0) doesn't work. It shows:
p_poly_v1_g.adb:40:63: positional aggregate cannot have one component
p_poly_v1_g.adb:40:63: write instead "T_Vect_Coef'First => ..."

But Array_type'First..Array_type'Last doesn't seem fine when there's just one element... Or better, none. How do I write that for an empty array ??


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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
  2017-12-20 17:32 ` Mehdi Saada
@ 2017-12-20 20:05 ` Niklas Holsti
  2017-12-20 22:48 ` Mehdi Saada
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-20 20:05 UTC (permalink / raw)


On 17-12-20 19:28 , Mehdi Saada wrote:
> I'm being modelizing polynomes.

It is difficult to help you if you don't show the type declarations! So 
my suggestions below are not sure to work.

> I've got those two things:
> p_poly_v1_g.adb:51:21: iterable name cannot be a discriminant-dependent component of a mutable object
> Ah ? So I can't write that ?
> return RESULTAT : T_POLYNOME := POLY do
>         for ELEMENT of RESULTAT.COEF loop
>                 ELEMENT := - ELEMENT;
>         end loop;
> end return;

You are trying to iterate over RESULTAT.COEF, which seems to be an array 
with an index range that depends on RESULTAT.DEGRE. The error message 
tells you that this is not allowed, because RESULTAT is mutable (not 
constant) and therefore RESULTAT.DEGRE and thus the index range of 
RESULTAT.COEF could change during the iteration. The Annotated Ada 
Reference Manual gives the following rationale for this rule:

"Reason: This is the same rule that applies to renames; it serves the 
same purpose of preventing the object from disappearing while the 
iterator is still using it."

It should work if you change the loop to be an ordinary loop over 
RESULTAT.COEF'Range, with indexing of its elements. There will then be 
(at least in principle) run-time checks to ensure that the indexing is 
legal even if RESULTAT has changed. In practice these checks may be 
optimised away.

> I've got that too:
> p_poly_v1_g.adb:59:86: selector name should be identifier or "others"
>
> return RES: T_POLYNOME :=
>    (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),
>    POLY_A.COEF'Range => POLY_A.COEF, others => Nulle) do

Here you have omitted the '(' ')' around the nested array aggregate. It 
should be

   return RES: T_POLYNOME :=
      (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),
       (POLY_A.COEF'Range => POLY_A.COEF, others => Nulle)) do

> I thought X'Range was strictly equivalent to X'First..X'Last ? Of
> course, poly is a mutable article, with two components, Degre
> (derived from NATURAL), and COEF, array.

Which is why the aggregate for COEF is nested and must have its own 
parentheses.

> I have that too:
> for IND in POLY_R.COEF'Range loop
>       POLY_R.COEF(IND) := POLY_R.COEF(IND)*(IND+1);
> end loop;
>
> COEF's elements of T_RATIONNEL type, themselves record types.
> IND is of type T_DEGRE, so why do I have that:
> p_poly_v1_g.adb:73:43: expected type "Standard.Integer"
> p_poly_v1_g.adb:73:43: found private type "T_Rationnel"

Again hard to be sure, as you didn't show the actual type declarations, 
but what is your question, really? Is it (1) why the compiler gives you 
an error, or (2) why the first message says "Standard.Integer" instead 
of "T_DEGRE"?

The answer to the first question is that you have not defined an "*" 
operator for these operand types, or this operator is not visible at 
this point in the code.

The answer to the second question is probably that the index type of the 
COEF array is a subtype of Standard.Integer, not a type of its own. 
GNAT's error messages of this kind refer to the underlying type, not to 
the subtype, because the operator is identified from the type and not 
from the subtype.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


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

* Re: syntaxic exploration
  2017-12-20 17:32 ` Mehdi Saada
@ 2017-12-20 20:08   ` Niklas Holsti
  2017-12-20 22:18     ` Mehdi Saada
  2017-12-21  7:21   ` Randy Brukardt
  1 sibling, 1 reply; 49+ messages in thread
From: Niklas Holsti @ 2017-12-20 20:08 UTC (permalink / raw)


On 17-12-20 19:32 , Mehdi Saada wrote:
> Hum, how do I write a array component with one element ?

To write an array aggregate with one component, you must use the "named 
aggrage" form and define the index as well as the value, as in

    (1 => Xxx)

where "1" is the index and "Xxx" is the component value for this index.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: syntaxic exploration
  2017-12-20 20:08   ` Niklas Holsti
@ 2017-12-20 22:18     ` Mehdi Saada
  2017-12-20 22:45       ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-20 22:18 UTC (permalink / raw)


Thanks. I should have digged and post all the definitions. I'll post more details later. I had no really use of named aggregate before... How do we denote an empty array in an aggregate ?
It couldn't be applicable here, since COEF's bounds in delimited by a determinant, I'm just curious about extreme syntax cases...


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

* Re: syntaxic exploration
  2017-12-20 22:18     ` Mehdi Saada
@ 2017-12-20 22:45       ` Mehdi Saada
  2017-12-21  7:24         ` Randy Brukardt
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-20 22:45 UTC (permalink / raw)


Sorry. How about the empty array in an aggregate ?

subtype T_Degre is Natural range 0..Max;
type T_Vect_Coef is array (T_Degre range <>) of T_Rationnel;
type T_Polynome (Degre : T_Degre := 0) is
record
      Coef : T_Vect_Coef (0..Degre) := (others => Nulle);
end record;
type T_Rationnel is record
      Numerateur  : T_Entier  := 0;
      Denominateur: T_Entier_Pos := 1;
end record; -- (t_entier est un type paramêtre formel du générique.
subtype T_Entier_Pos is T_Entier range 1..T_Entier'Last;

All the operations (*,-,- unaire, /, abs, relations d'ordre) sont définis pour T_Rationnel dans le même package fournissant le type.


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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
  2017-12-20 17:32 ` Mehdi Saada
  2017-12-20 20:05 ` Niklas Holsti
@ 2017-12-20 22:48 ` Mehdi Saada
  2017-12-20 23:39   ` Mehdi Saada
  2017-12-21  0:35 ` Mehdi Saada
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-20 22:48 UTC (permalink / raw)


Sorry. How about the empty array in an aggregate ? 
I found the rule very sensical. But I wonder why the more basic iterative construct, can have checks at run time, and not the more advanced one ?

subtype T_Degre is Natural range 0..Max; 
type T_Vect_Coef is array (T_Degre range <>) of T_Rationnel; 
type T_Polynome (Degre : T_Degre := 0) is 
record 
      Coef : T_Vect_Coef (0..Degre) := (others => Nulle); 
end record; 
type T_Rationnel is record 
      Numerateur  : T_Entier  := 0; 
      Denominateur: T_Entier_Pos := 1; 
end record; -- (t_entier est un type paramêtre formel du générique. 
subtype T_Entier_Pos is T_Entier range 1..T_Entier'Last; 

All the operations (*,-,- unaire, /, abs, relations d'ordre) are provided for T_Rationnel in the same package as the type itself. définis pour T_Rationnel dans le même package fournissant le type.


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

* Re: syntaxic exploration
  2017-12-20 22:48 ` Mehdi Saada
@ 2017-12-20 23:39   ` Mehdi Saada
  0 siblings, 0 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-20 23:39 UTC (permalink / raw)


Le mercredi 20 décembre 2017 23:48:45 UTC+1, Mehdi Saada a écrit :
> Sorry. How about the empty array in an aggregate ? 
> I found the rule very sensical. But I wonder why the more basic iterative construct, can have checks at run time, and not the more advanced one ?
> 
> subtype T_Degre is Natural range 0..Max; 
> type T_Vect_Coef is array (T_Degre range <>) of T_Rationnel; 
> type T_Polynome (Degre : T_Degre := 0) is 
> record 
>       Coef : T_Vect_Coef (0..Degre) := (others => Nulle); 
> end record; 
> type T_Rationnel is record 
>       Numerateur  : T_Entier  := 0; 
>       Denominateur: T_Entier_Pos := 1; 
> end record; -- (t_entier est un type paramêtre formel du générique. 
> subtype T_Entier_Pos is T_Entier range 1..T_Entier'Last; 
> 
> All the operations (*,-,- unaire, /, abs, relations d'ordre) are provided for T_Rationnel in the same package as the type itself, in the same package.

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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
                   ` (2 preceding siblings ...)
  2017-12-20 22:48 ` Mehdi Saada
@ 2017-12-21  0:35 ` Mehdi Saada
  2017-12-21  7:18 ` Randy Brukardt
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-21  0:35 UTC (permalink / raw)


Done what you said, it compiled. I had to do T_ENTIER(IND+1) to make "*" works. I don't get why, for I am not sure where this type is coming from...
The formal parameter of the generic unit where it comes is : type T_Entier is range <>;
but the package in instanciated with a (<>) actual parameter... I did wrote the generic, but not the instanciation part. I can't see a default parameter, what effect might (<>) has then ?

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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
                   ` (3 preceding siblings ...)
  2017-12-21  0:35 ` Mehdi Saada
@ 2017-12-21  7:18 ` Randy Brukardt
  2017-12-21 19:23   ` G. B.
  2017-12-21 23:46   ` bj.mooremr
  2017-12-22 13:31 ` Mehdi Saada
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 49+ messages in thread
From: Randy Brukardt @ 2017-12-21  7:18 UTC (permalink / raw)


"Mehdi Saada" <00120260a@gmail.com> wrote in message 
news:0d33e631-e63d-4346-ac95-5eec72127f4f@googlegroups.com...
> I'm being modelizing polynomes. I've got those two things: 
> p_poly_v1_g.adb:51:21: iterable name cannot be a discriminant-dependent 
> component of a mutable object
> Ah ? So I can't write that ?
> return RESULTAT : T_POLYNOME := POLY do
>        for ELEMENT of RESULTAT.COEF loop

Correct. You can't write this, because the iterable item could disappear in 
the body of the loop. (If someone assigned a different value to the mutable 
variable.)  This is the same rule as used for renames (you can't rename this 
component, either, for the same reason).

...
> I've got that too:
> p_poly_v1_g.adb:59:86: selector name should be identifier or "others"
>
> return RES: T_POLYNOME := 
> (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),POLY_A.COEF'Range => POLY_A.COEF, 
> others => Nulle) do
>
> I thought X'Range was strictly equivalent to X'First..X'Last ?

'Range is rather a wart in the language; it can only be used in a few 
specific places. That's because X'Range is neither a subtype constraint nor 
a value, and those are the only things with general rules.

However, an aggregate choice is one the places that 'Range can be used, so 
you're obviously doing something else wrong. (Which I can't see given the 
partial code here.)

                                Randy.



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

* Re: syntaxic exploration
  2017-12-20 17:32 ` Mehdi Saada
  2017-12-20 20:08   ` Niklas Holsti
@ 2017-12-21  7:21   ` Randy Brukardt
  2017-12-21 16:24     ` Jeffrey R. Carter
  1 sibling, 1 reply; 49+ messages in thread
From: Randy Brukardt @ 2017-12-21  7:21 UTC (permalink / raw)


"Mehdi Saada" <00120260a@gmail.com> wrote in message 
news:0fa75dd5-599b-4a38-a5d4-3151bbe5172f@googlegroups.com...
> Hum, how do I write a array component with one element ? Something like 
> (_discriminant_, (0)) (array starting from 0) doesn't work. It shows:
> p_poly_v1_g.adb:40:63: positional aggregate cannot have one component
> p_poly_v1_g.adb:40:63: write instead "T_Vect_Coef'First => ..."
>
> But Array_type'First..Array_type'Last doesn't seem fine when there's just 
> one element...
> Or better, none. How do I write that for an empty array ??

Ada has no good way to write an empty array. I usually use (1 .. 0 => <>) 
for that, but nothing is really satisfying.

For a single element, write a single choice (a choice doesn't have to be a 
range!) The compiler error message gives a suggestion.

                                               Randy.


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

* Re: syntaxic exploration
  2017-12-20 22:45       ` Mehdi Saada
@ 2017-12-21  7:24         ` Randy Brukardt
  2017-12-21  7:44           ` Niklas Holsti
  0 siblings, 1 reply; 49+ messages in thread
From: Randy Brukardt @ 2017-12-21  7:24 UTC (permalink / raw)


"Mehdi Saada" <00120260a@gmail.com> wrote in message 
news:baca5473-6224-481e-b4c0-0604153e11e7@googlegroups.com...
>Sorry. How about the empty array in an aggregate ?
>
>subtype T_Degre is Natural range 0..Max;
>type T_Vect_Coef is array (T_Degre range <>) of T_Rationnel;
>type T_Polynome (Degre : T_Degre := 0) is
>record
>      Coef : T_Vect_Coef (0..Degre) := (others => Nulle);

The above aggregate is fine for an empty array. The bounds come from the 
object being initialized.

               Randy.


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

* Re: syntaxic exploration
  2017-12-21  7:24         ` Randy Brukardt
@ 2017-12-21  7:44           ` Niklas Holsti
  0 siblings, 0 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-21  7:44 UTC (permalink / raw)


On 17-12-21 09:24 , Randy Brukardt wrote:
> "Mehdi Saada" <00120260a@gmail.com> wrote in message
> news:baca5473-6224-481e-b4c0-0604153e11e7@googlegroups.com...
>> Sorry. How about the empty array in an aggregate ?
>>
>> subtype T_Degre is Natural range 0..Max;
>> type T_Vect_Coef is array (T_Degre range <>) of T_Rationnel;
>> type T_Polynome (Degre : T_Degre := 0) is
>> record
>>      Coef : T_Vect_Coef (0..Degre) := (others => Nulle);
>
> The above aggregate is fine for an empty array. The bounds come from the
> object being initialized.

But (just to avoid a possible misunderstanding on Mehdi's side) the 
above aggregate can never be an empty array, because Degre >= 0. An 
array with index range 0 .. Degre is empty only if Degre < 0.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: syntaxic exploration
  2017-12-21  7:21   ` Randy Brukardt
@ 2017-12-21 16:24     ` Jeffrey R. Carter
  2017-12-22  5:01       ` Robert Eachus
  0 siblings, 1 reply; 49+ messages in thread
From: Jeffrey R. Carter @ 2017-12-21 16:24 UTC (permalink / raw)


On 12/21/2017 08:21 AM, Randy Brukardt wrote:
> 
> Ada has no good way to write an empty array. I usually use (1 .. 0 => <>)
> for that, but nothing is really satisfying.

Except perhaps the empty array aggregate

""

(only for string types, alas).

-- 
Jeff Carter
"Death awaits you all, with nasty, big, pointy teeth!"
Monty Python & the Holy Grail
20


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

* Re: syntaxic exploration
  2017-12-21  7:18 ` Randy Brukardt
@ 2017-12-21 19:23   ` G. B.
  2017-12-21 23:46   ` bj.mooremr
  1 sibling, 0 replies; 49+ messages in thread
From: G. B. @ 2017-12-21 19:23 UTC (permalink / raw)


uRandy Brukardt <randy@rrsoftware.com> wrote:
> "Mehdi Saada" <00120260a@gmail.com> wrote:
>> 
>> I thought X'Range was strictly equivalent to X'First..X'Last ?
> 
> 'Range is rather a wart in the language; it can only be used in a few 
> specific places.

So, *for* is a wart, too, then. ;-)
It, too, can only be used in a few specific places.
But, together with an object’s Range
attribute, we get an unequivocal statement that
something applies to everything in range.
The range does not need to be programmed by 
hand; that would be verbose. I like to reserve
‘Last to one-off specification of subranges.


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

* Re: syntaxic exploration
  2017-12-21  7:18 ` Randy Brukardt
  2017-12-21 19:23   ` G. B.
@ 2017-12-21 23:46   ` bj.mooremr
  2017-12-22 23:45     ` Randy Brukardt
  1 sibling, 1 reply; 49+ messages in thread
From: bj.mooremr @ 2017-12-21 23:46 UTC (permalink / raw)


On Thursday, December 21, 2017 at 12:18:39 AM UTC-7, Randy Brukardt wrote:
> "Mehdi Saada" <00120260a@gmail.com> wrote in message 
> news:0d33e631-e63d-4346-ac95-5eec72127f4f@googlegroups.com...
> > I'm being modelizing polynomes. I've got those two things: 
> > p_poly_v1_g.adb:51:21: iterable name cannot be a discriminant-dependent 
> > component of a mutable object
> > Ah ? So I can't write that ?
> > return RESULTAT : T_POLYNOME := POLY do
> >        for ELEMENT of RESULTAT.COEF loop
> 
> Correct. You can't write this, because the iterable item could disappear in 
> the body of the loop. (If someone assigned a different value to the mutable 
> variable.)  This is the same rule as used for renames (you can't rename this 
> component, either, for the same reason).
> 
> ...
> > I've got that too:
> > p_poly_v1_g.adb:59:86: selector name should be identifier or "others"
> >
> > return RES: T_POLYNOME := 
> > (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),POLY_A.COEF'Range => POLY_A.COEF, 
> > others => Nulle) do
> >
> > I thought X'Range was strictly equivalent to X'First..X'Last ?
> 
> 'Range is rather a wart in the language; it can only be used in a few 
> specific places. That's because X'Range is neither a subtype constraint nor 
> a value, and those are the only things with general rules.
> 
> However, an aggregate choice is one the places that 'Range can be used, so 
> you're obviously doing something else wrong. (Which I can't see given the 
> partial code here.)
> 
>                                 Randy.

I've been thinking lately that its a bit of a wart that 'Range or at least range syntax cant be used in more places.

Specifically, I have been thinking of container iteration.

It is currently awkward to iterate a subset of a container, given two cursors, a start and and end cursor.

for a discrete subtype, we can express in Ada;

   for I in 5 .. 10 loop
      ...
   end loop


Where the bounds of iteration can be a subset of the values of a subtype.

It seems one ought to be able to do the same with cursors.

    for Position in Cursor1 .. Cursor2 loop
        list (Position) := ...
    end loop

Note: This currently isn't legal in Ada.

Otherwise, one has to write a while loop, which is a bit awkward.

   Position : Cursor := Cursor1;

   Iteration_Loop :
   loop
       List (Position) := ...
       exit Iteration_Loop when Position := Cursor2;
       Next (Position);
   end loop;

   One can almost do this with the current containers, with Ada 2012 
   iterator syntax because they generally
   have an Iterate primitive that accepts a start cursor.

   eg.

   for I in List.Iterate(Start => Cursor1) loop
      List (I) := ...
   end loop;

   But we currently do not have Iterate primitives in the standard containers
   that also accept an End cursor, so these calls allow one to start somewhere
   in the middle of a container and iterate to the end, but not to stop
   earlier. It seems like it would be relatively easy to 
   add such calls.

   Then we could write;

   for I in List.Iterate(Start => Cursor1, Finish => Cursor2) loop
      List (I) := ...
   end loop;

   Perhaps the intent was to use exit to exit the loop earlier when you hit the
   second cursor.

   for I in List.Iterate(Start => Cursor1) loop
      List (I) := ...
      exit when I = Cursor2;
   end loop;

   I think that's somewhat satisfactory.

   But I still think it would be nice to take this one step further and
   be able to add syntactic sugar to express this with range syntax, as 
   shown in the example above.

I don't know how useful this would be, or how easy it would be to add to the language, but one place I would use it is when
trying to iterate through containers in parallel where workers are each given a subset of the container by providing each worker with a start and end cursor.

Brad


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

* Re: syntaxic exploration
  2017-12-21 16:24     ` Jeffrey R. Carter
@ 2017-12-22  5:01       ` Robert Eachus
  2017-12-22 21:15         ` Simon Clubley
  0 siblings, 1 reply; 49+ messages in thread
From: Robert Eachus @ 2017-12-22  5:01 UTC (permalink / raw)


On Thursday, December 21, 2017 at 11:24:54 AM UTC-5, Jeffrey R. Carter wrote:
> On 12/21/2017 08:21 AM, Randy Brukardt wrote:
> > 
> > Ada has no good way to write an empty array. I usually use (1 .. 0 => <>)
> > for that, but nothing is really satisfying.
> 
> Except perhaps the empty array aggregate
> 
> ""
> 
> (only for string types, alas).

Is it a reasonable language improvement request to allow "" for other empty arrays?  Another possibility is the reserved word null.  If that were allowed I might even use it in place of "" for strings, because that is not different enough from '"' when reading, depending on the type face used. 



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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
                   ` (4 preceding siblings ...)
  2017-12-21  7:18 ` Randy Brukardt
@ 2017-12-22 13:31 ` Mehdi Saada
  2017-12-22 18:00   ` Mehdi Saada
  2017-12-22 18:27   ` Niklas Holsti
  2017-12-23  1:47 ` Mehdi Saada
  2017-12-23 12:12 ` Mehdi Saada
  7 siblings, 2 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-22 13:31 UTC (permalink / raw)


It compiled, but I entered the agonizing world of debugging run time erros...
What in that:
return RES: T_POLYNOME :=
(T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),POLY_A.COEF) do
	for I in POLY_B.COEF'Range loop
		RES.COEF(I) := RES.COEF(I) + POLY_B.COEF(I);
	end loop;
	RES := POLY_REDUIT(RES);
end return;

is wrong ? Because the result is.
P1: 1 -2X 
P2: -1 
POLY1 + (POLY1 * POLY2) = 9 -15X +2X** 2  -- wrong.

It ends with raised CONSTRAINT_ERROR : p_poly_v1_g.adb:63 length check failed
 59 function "+" (POLY_A, POLY_B: T_POLYNOME) return T_POLYNOME is          
 60 begin                                                                   
 61     return RES: T_POLYNOME :=                                           
 62     (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),POLY_A.COEF) do             
 63         for I in POLY_B.COEF'Range loop                                 
 64             RES.COEF(I) := RES.COEF(I) + POLY_B.COEF(I);                
 65         end loop;                                                       
 66         RES := POLY_REDUIT(RES);                                        
 67     end return;                                                         


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

* Re: syntaxic exploration
  2017-12-22 13:31 ` Mehdi Saada
@ 2017-12-22 18:00   ` Mehdi Saada
  2017-12-22 18:27   ` Niklas Holsti
  1 sibling, 0 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-22 18:00 UTC (permalink / raw)


I must add too,
T_Entier is range -40 000..40 000; is the scalar type at the core of T_Rationnel, the type of elements of T_POLYNOME.COEF. But I doubt it went beyond these bounds anywhere close.

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

* Re: syntaxic exploration
  2017-12-22 13:31 ` Mehdi Saada
  2017-12-22 18:00   ` Mehdi Saada
@ 2017-12-22 18:27   ` Niklas Holsti
  2017-12-22 20:25     ` Mehdi Saada
  1 sibling, 1 reply; 49+ messages in thread
From: Niklas Holsti @ 2017-12-22 18:27 UTC (permalink / raw)


On 17-12-22 15:31 , Mehdi Saada wrote:
> It compiled, but I entered the agonizing world of debugging run time erros...
> What in that:
> return RES: T_POLYNOME :=
> (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),POLY_A.COEF) do
> 	for I in POLY_B.COEF'Range loop
> 		RES.COEF(I) := RES.COEF(I) + POLY_B.COEF(I);
> 	end loop;
> 	RES := POLY_REDUIT(RES);
> end return;
>
> is wrong ? Because the result is.
> P1: 1 -2X
> P2: -1
> POLY1 + (POLY1 * POLY2) = 9 -15X +2X** 2  -- wrong.

I can't help with that, because you do not show the input values, nor 
the output procedures.

> It ends with raised CONSTRAINT_ERROR : p_poly_v1_g.adb:63 length check failed
>  59 function "+" (POLY_A, POLY_B: T_POLYNOME) return T_POLYNOME is
>  60 begin
>  61     return RES: T_POLYNOME :=
>  62     (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),POLY_A.COEF) do

RES.COEF should have a length of RES.DEGRE, but the aggregate above 
supplies an array (POLY_A.COEF) with a length of POLY_A.DEGRE. If 
POLY_B.DEGRE is larger than POLY_A.DEGRE, these lengths are different.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: syntaxic exploration
  2017-12-22 18:27   ` Niklas Holsti
@ 2017-12-22 20:25     ` Mehdi Saada
  2017-12-22 22:33       ` Niklas Holsti
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-22 20:25 UTC (permalink / raw)


How about that, then:
return RES: T_POLYNOME :=
	T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),(0..POLY_A.COEF'Last => POLY_A.COEF, others => Nulle)) do
It says "p_poly_v1_g.adb:63:51: dynamic or empty choice in aggregate must be the only choice"
I would like to write this (POLY_A.COEF'Range => POLY_A.COEF, others => Nulle) but I know "POLY_A.COEF'Range =>" must be followed by a value of T_RATIONNEL, not a slice. But I don't know how to write "PUT POLY_A.COEF there, and as much Nulle as needed to fill the void if by chance POLY_B.DEGRE > POLY_A.DEGRE"

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

* Re: syntaxic exploration
  2017-12-22  5:01       ` Robert Eachus
@ 2017-12-22 21:15         ` Simon Clubley
  2017-12-22 22:11           ` Niklas Holsti
  0 siblings, 1 reply; 49+ messages in thread
From: Simon Clubley @ 2017-12-22 21:15 UTC (permalink / raw)


On 2017-12-22, Robert Eachus <rieachus@comcast.net> wrote:
> On Thursday, December 21, 2017 at 11:24:54 AM UTC-5, Jeffrey R. Carter wrote:
>> On 12/21/2017 08:21 AM, Randy Brukardt wrote:
>> > 
>> > Ada has no good way to write an empty array. I usually use (1 .. 0 => <>)
>> > for that, but nothing is really satisfying.
>> 
>> Except perhaps the empty array aggregate
>> 
>> ""
>> 
>> (only for string types, alas).
>
> Is it a reasonable language improvement request to allow "" for other
> empty arrays?


No. That would be too confusing IMHO because it would initially appear
to be a string type to anyone unfamiliar with that part of the code
and that just feels _way_ wrong.

>  Another possibility is the reserved word null.  If that were
> allowed I might even use it in place of "" for strings, because that is not
> different enough from '"' when reading, depending on the type face used. 
>

null is an interesting option for the empty array. However, for your
strings idea, would people unfamiliar with the code and this new usage
of null read this new usage as a null pointer instead of an empty string ?
That could be confusing.

The 1..0 notation is ugly but anyone who sees it knows instantly
exactly what the original programmer meant. Any cleaner replacement
should instantly come across as the empty array without the
possibility of confusion because someone reused Ada syntax
for this in an ambiguous way.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


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

* Re: syntaxic exploration
  2017-12-22 21:15         ` Simon Clubley
@ 2017-12-22 22:11           ` Niklas Holsti
  2017-12-22 22:51             ` Dmitry A. Kazakov
  2017-12-23 16:23             ` Jeffrey R. Carter
  0 siblings, 2 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-22 22:11 UTC (permalink / raw)


On 17-12-22 23:15 , Simon Clubley wrote:
> On 2017-12-22, Robert Eachus <rieachus@comcast.net> wrote:
>> On Thursday, December 21, 2017 at 11:24:54 AM UTC-5, Jeffrey R. Carter wrote:
>>> On 12/21/2017 08:21 AM, Randy Brukardt wrote:
>>>>
>>>> Ada has no good way to write an empty array. I usually use (1 .. 0 => <>)
>>>> for that, but nothing is really satisfying.
>>>
>>> Except perhaps the empty array aggregate
>>>
>>> ""
>>>
>>> (only for string types, alas).
>>
>> Is it a reasonable language improvement request to allow "" for other
>> empty arrays?
>
>
> No. That would be too confusing IMHO because it would initially appear
> to be a string type to anyone unfamiliar with that part of the code
> and that just feels _way_ wrong.

I agree.

>>  Another possibility is the reserved word null.

    [snip]

> null is an interesting option for the empty array. However, for your
> strings idea, would people unfamiliar with the code and this new usage
> of null read this new usage as a null pointer instead of an empty string ?
> That could be confusing.

I agree, again.

I think the aggregate form (null array) was suggested some time ago, in 
analogy with the existing (null record). It looks good to me, but as I 
remember, there was some objection. One problem is that if the index 
type has exactly one value, then a null array with that index type 
cannot exist (because then A'First = A'Last for any such array A).

> The 1..0 notation is ugly but anyone who sees it knows instantly
> exactly what the original programmer meant.

Yes, but it becomes rather more ugly if the index type is an 
enumeration, or a generic formal discrete type, something like

    Thingummybob'Succ (Thingummybob'First) .. Thingummybob'First

Note that Thingummybob'Last .. Thingummybob'First won't be a null range 
if Thingummybob has exactly one value.

> Any cleaner replacement
> should instantly come across as the empty array without the
> possibility of confusion because someone reused Ada syntax
> for this in an ambiguous way.

I think (null array) satisfies that. I wish it could be introduced.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: syntaxic exploration
  2017-12-22 20:25     ` Mehdi Saada
@ 2017-12-22 22:33       ` Niklas Holsti
  0 siblings, 0 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-22 22:33 UTC (permalink / raw)


On 17-12-22 22:25 , Mehdi Saada wrote:
> How about that, then:
> return RES: T_POLYNOME :=
> 	T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE),(0..POLY_A.COEF'Last => POLY_A.COEF, others => Nulle)) do
> It says "p_poly_v1_g.adb:63:51: dynamic or empty choice in aggregate must be the only choice"

(You have omitted the opening '(', after the ":=".)

Yes, the range 0..POLY_A.COEF'Last is dynamic, so the error message is 
valid.

Moreover, here, too, the expression after the index range should be a 
T_RATIONNEL, not an array like POLY_A.COEF. The semantics of an 
association A .. B => X, in an array aggregate, is to give the same 
value, X, to all elements in the index range A .. B, so it is _not_ what 
you want to do here.

> I would like to write this (POLY_A.COEF'Range => POLY_A.COEF, others => Nulle)

That is equivalent, and should give you the same error, and also be 
wrong in the same way.

> but I know "POLY_A.COEF'Range =>" must be followed by a value
> of T_RATIONNEL, not a slice.

The same is true for "0..POLY_A.COEF'Last =>".

> But I don't know how to write "PUT POLY_A.COEF there, and as much
> Nulle as needed to fill the void if by chance POLY_B.DEGRE > POLY_A.DEGRE"

If you insist on using an aggregate to initialise RES, you could use 
this form, with array concatenation ("&" operator) for the COEF component:

    return RES : T_POLYNOME :=
      (T_DEGRE'MAX (POLY_A.DEGRE, POLY_B.DEGRE),
         POLY_A.COEF
       & (1 .. Xxx'MAX (0, POLY_B.DEGRE - POLY_A.DEGRE) => Nulle));

where Xxx is the index type of the COEF array (I forget its name).

However, I would do it differently; I would declare RES with just its 
discriminant:

    return
       RES : T_POLYNOME (T_DEGRE'MAX (POLY_A.DEGRE, POLY_B.DEGRE))
    do
       -- Assign values to RES.COEF using loops, something like:

       for C in RES.COEF'Range loop
          RES.COEF(C) :=
              (if C in POLY_A.COEF'Range then POLY_A.COEF(C) else 0)
            + (if C in POLY_B.COEF'Range then POLY_B.COEF(C) else 0);
       end loop;
    end return;

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: syntaxic exploration
  2017-12-22 22:11           ` Niklas Holsti
@ 2017-12-22 22:51             ` Dmitry A. Kazakov
  2017-12-23  7:15               ` Niklas Holsti
  2017-12-23 16:23             ` Jeffrey R. Carter
  1 sibling, 1 reply; 49+ messages in thread
From: Dmitry A. Kazakov @ 2017-12-22 22:51 UTC (permalink / raw)


On 2017-12-22 23:11, Niklas Holsti wrote:

> I think the aggregate form (null array) was suggested some time ago, in 
> analogy with the existing (null record).

These two totally different things. "null record" is not a record 
aggregate (a value of record type), it is a type construct (a value of a 
record type's type). Correspondingly "null array" would mean a type of 
arrays rather than an empty aggregate of an array type.

> I think (null array) satisfies that. I wish it could be introduced.

If "" is QK, why () isn't?

    Empty : My_Array := ();

It could be an attribute as well:

    Empty : My_Array := My_Array'Null;

(You are right about indices. String has the lower bound set to 1. That 
gives an unambiguous range of an empty string. For general case arrays 
it is ambiguous)

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

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

* Re: syntaxic exploration
  2017-12-21 23:46   ` bj.mooremr
@ 2017-12-22 23:45     ` Randy Brukardt
  0 siblings, 0 replies; 49+ messages in thread
From: Randy Brukardt @ 2017-12-22 23:45 UTC (permalink / raw)


<bj.mooremr@gmail.com> wrote in message 
news:b81c7f6f-dda7-4cd1-a9c6-953d0d30e7d4@googlegroups.com...
...
> Otherwise, one has to write a while loop, which is a bit awkward.
>
>   Position : Cursor := Cursor1;
>
>   Iteration_Loop :
>   loop
>       List (Position) := ...
>       exit Iteration_Loop when Position := Cursor2;
>       Next (Position);
>   end loop;

This works, of course.

>   One can almost do this with the current containers, with Ada 2012
>   iterator syntax because they generally
>   have an Iterate primitive that accepts a start cursor.
>
>   eg.
>
>   for I in List.Iterate(Start => Cursor1) loop
>      List (I) := ...
>   end loop;

This is true, too. But you just need to exit the loop at the end cursor to 
get the semantics you want:

   for I in List.Iterate(Start => Cursor1) loop
      List (I) := ...
      exit when I = Cursor2;
   end loop;

Ada doesn't care what kind of loop you use an exit in!

If there was to be a complaint here, it's that you can't easily use the 
element form ("of") with an ending cursor (because the cursor has to be 
explicit). But it seems weird to me to want to use cursors and yet hide them 
at the same time.

Conclusion: There isn't a need for an explicit "ending cursor", because an 
exit works fine for that in the cursor form. There still might be some sort 
of consistency argument, but we didn't add it originally since the exit is 
so easy to use for ending a loop "early".

                                 Randy.


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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
                   ` (5 preceding siblings ...)
  2017-12-22 13:31 ` Mehdi Saada
@ 2017-12-23  1:47 ` Mehdi Saada
  2017-12-23  7:17   ` Niklas Holsti
  2017-12-23 12:12 ` Mehdi Saada
  7 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23  1:47 UTC (permalink / raw)


Thank you, Niklas Holsti. Your way of doing it is just beautiful, as always with conditional expressions. Also, I simply forgot about the & operator for non-strings arrays.
Still:
p_poly_v1_g.adb:64:92: expected private type "T_Rationnel" defined at p_rationnels_g.ads:11, instance at p_poly_v1_g.ads:19
p_poly_v1_g.adb:64:92: found type universal integer
p_poly_v1_g.adb:64:149: expected private type "T_Rationnel" defined at p_rationnels_g.ads:11, instance at p_poly_v1_g.ads:19
p_poly_v1_g.adb:64:149: found type universal integer
gnatmake: "p_poly_v1_g.adb" compilation error

with the same sentences as in your exemple. At least, I can't see the difference with what you wrote. 
return RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE)) do
	for I in RES.COEF'Range loop
           RES.COEF(I) := (if I in POLY_A.COEF'Range then POLY_A.COEF(I) else 0) + (if I in POLY_B.COEF'Range then POLY_B.COEF(I) else 0);
	end loop;
	RES := POLY_REDUIT(RES);
end return;


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

* Re: syntaxic exploration
  2017-12-22 22:51             ` Dmitry A. Kazakov
@ 2017-12-23  7:15               ` Niklas Holsti
  0 siblings, 0 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-23  7:15 UTC (permalink / raw)


On 17-12-23 00:51 , Dmitry A. Kazakov wrote:
> On 2017-12-22 23:11, Niklas Holsti wrote:
>
>> I think the aggregate form (null array) was suggested some time ago,
>> in analogy with the existing (null record).
>
> These two totally different things. "null record" is not a record
> aggregate (a value of record type), it is a type construct (a value of a
> record type's type).

Yes and no. Compare

    type Nothing is null record;  -- Last choice in RM 3.8(3).

and

    N : Nothing := (null record);  -- Last choice in RM 4.3.1(3).

So "null record" in a type declaration is a record_definition (RM 
3.8(3)) but it can also occur in an expression as a 
record_component_association_list (RM 4.3.1(3)). Thus "(null record)" is 
a record aggregate.

> Correspondingly "null array" would mean a type of
> arrays rather than an empty aggregate of an array type.
>
>> I think (null array) satisfies that. I wish it could be introduced.
>
> If "" is QK, why () isn't?

Could be, but parentheses are already so overloaded (which quotes are 
not) that I like (null array) better.

> It could be an attribute as well:
>
>    Empty : My_Array := My_Array'Null;

Could be, but it is not much better than My_Array'(null array).

> (You are right about indices. String has the lower bound set to 1. That
> gives an unambiguous range of an empty string.

No, for example (16 .. -40 => ' ') is an empty string, with bounds 16 .. 
-40.

The index range of the empty string denoted by the null string literal 
"" is defined in the RM unambiguously.

> For general case arrays it is ambiguous)

Yes, the index bounds of "(null array)" would have to be specifically 
defined in the RM, similarly to the case for the null string literal.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: syntaxic exploration
  2017-12-23  1:47 ` Mehdi Saada
@ 2017-12-23  7:17   ` Niklas Holsti
  2017-12-23 11:23     ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Niklas Holsti @ 2017-12-23  7:17 UTC (permalink / raw)


On 17-12-23 03:47 , Mehdi Saada wrote:
> Thank you, Niklas Holsti. Your way of doing it is just beautiful, as
> always with conditional expressions. Also, I simply forgot about
> the & operator for non-strings arrays.
> Still:
> p_poly_v1_g.adb:64:92: expected private type "T_Rationnel" defined at p_rationnels_g.ads:11, instance at p_poly_v1_g.ads:19
> p_poly_v1_g.adb:64:92: found type universal integer
> p_poly_v1_g.adb:64:149: expected private type "T_Rationnel" defined at p_rationnels_g.ads:11, instance at p_poly_v1_g.ads:19
> p_poly_v1_g.adb:64:149: found type universal integer

Sorry, I should have written "else Nulle" instead of "else 0". I forgot 
that your coefficients are rationals and not integers.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


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

* Re: syntaxic exploration
  2017-12-23  7:17   ` Niklas Holsti
@ 2017-12-23 11:23     ` Mehdi Saada
  2017-12-23 11:39       ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23 11:23 UTC (permalink / raw)


And I was no stupid enough to see that "0" were indeed in the wrong place, and were the only thing close to an Integer here ... Damn, the brain is so limited.
I love your discussion about null and such, and the fact I understand all of it ;-)

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

* Re: syntaxic exploration
  2017-12-23 11:23     ` Mehdi Saada
@ 2017-12-23 11:39       ` Mehdi Saada
  2017-12-23 12:09         ` Niklas Holsti
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23 11:39 UTC (permalink / raw)


And I was no stupid enough not to see that "0" were indeed in the wrong place, and were the only thing close to an Integer here ... Damn, the brain is so limited.
I love your discussion about null and such, and the fact I understand all of it ;-)

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

* Re: syntaxic exploration
  2017-12-23 11:39       ` Mehdi Saada
@ 2017-12-23 12:09         ` Niklas Holsti
  0 siblings, 0 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-23 12:09 UTC (permalink / raw)


On 17-12-23 13:39 , Mehdi Saada wrote:
> And I was no stupid enough not to see that "0" were indeed
> in the wrong place, and were the only thing close to an Integer
> here ... Damn, the brain is so limited.

That's why we have compilers to tell us where the error is ;-)

GNAT's error messages are usually very helpful and to the point.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


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

* Re: syntaxic exploration
  2017-12-20 17:28 syntaxic exploration Mehdi Saada
                   ` (6 preceding siblings ...)
  2017-12-23  1:47 ` Mehdi Saada
@ 2017-12-23 12:12 ` Mehdi Saada
  2017-12-23 12:16   ` Mehdi Saada
  7 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23 12:12 UTC (permalink / raw)


I think I found the cause of the error.
As I see it, but I don't know the intricated rules of extended return statements, RES seems to be initialized as a constrained record object.
Does "return RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE)) do"
constrains its discrimant ?
I would explain that RES := POLY_REDUIT(RES) three lines below causes "raised CONSTRAINT_ERROR : p_poly_v1_g.adb:67 discriminant check failed"

return RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE)) do
   for I in RES.COEF'Range loop
	RES.COEF(I) := (if I in POLY_A.COEF'Range then POLY_A.COEF(I) else Nulle) + (if I in POLY_B.COEF'Range then POLY_B.COEF(I) else Nulle);
   end loop;
   RES := POLY_REDUIT(RES);
end reutrn;


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

* Re: syntaxic exploration
  2017-12-23 12:12 ` Mehdi Saada
@ 2017-12-23 12:16   ` Mehdi Saada
  2017-12-23 13:04     ` Niklas Holsti
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23 12:16 UTC (permalink / raw)


As I see it, but I don't know the intricated rules of extended return statements, RES seems to be initialized as a constrained record object.
Does "return RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE)) do"
constrains its discrimant ?
I would explain that RES := POLY_REDUIT(RES) three lines below causes "raised CONSTRAINT_ERROR : p_poly_v1_g.adb:67 discriminant check failed"
 
return RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE)) do
   for I in RES.COEF'Range loop
	RES.COEF(I) := (if I in POLY_A.COEF'Range then POLY_A.COEF(I) else Nulle) + (if I in POLY_B.COEF'Range then POLY_B.COEF(I) else Nulle);
   end loop;
   RES := POLY_REDUIT(RES);
end return;

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

* Re: syntaxic exploration
  2017-12-23 12:16   ` Mehdi Saada
@ 2017-12-23 13:04     ` Niklas Holsti
  2017-12-23 14:02       ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Niklas Holsti @ 2017-12-23 13:04 UTC (permalink / raw)


On 17-12-23 14:16 , Mehdi Saada wrote:
> As I see it, but I don't know the intricated rules of
> extended return statements, RES seems to be initialized as
> a constrained record object.

I believe it is. Does the DEGRE discriminant have a default value? If 
not, all T_POLYNOME objects are constrained.

> Does "return RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE)) do"
> constrains its discrimant ?

Yes, just as a declaration X : String(1..4) constrains the index bounds 
of X.

> It would explain that RES := POLY_REDUIT(RES) three lines below
> causes "raised CONSTRAINT_ERROR : p_poly_v1_g.adb:67 discriminant check failed"

Certainly, if POLY_REDUIT returns a value with a different value of the 
DEGRE discriminant. I guess POLY_REDUIT drops any zero-valued high-order 
coefficients, so it can return a poly with a smaller DEGRE than its input.

I would make RES into a local variable (not an extended return object), 
declare and assign it as now, and then just

    return POLY_REDUIT (RES);

at the end.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


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

* Re: syntaxic exploration
  2017-12-23 13:04     ` Niklas Holsti
@ 2017-12-23 14:02       ` Mehdi Saada
  2017-12-23 14:46         ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23 14:02 UTC (permalink / raw)


The discrimant has indeed a default value, hence my "what the heck"-like reaction.
type T_Polynome (Degre : T_Degre := 0) is
   record
      Coef : T_Vect_Coef (0..Degre) := (others => 0);
   end record;

But I'll stop with putting "extended" everywhere. I first found it really cool, but not so much now.

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

* Re: syntaxic exploration
  2017-12-23 14:02       ` Mehdi Saada
@ 2017-12-23 14:46         ` Mehdi Saada
  2017-12-23 15:03           ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23 14:46 UTC (permalink / raw)


Now I'm sure the function "+" is wrong as well. I know I shouldn't think like this, but sometimes I , POLY_B: T_POLYNOME) return T_POLYNOME is
	RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE));
begin
	ADA.TEXT_IO.PUT_LINE("POLY A: ");
	ECRIRE (POLY_A);
	ADA.TEXT_IO.PUT_LINE("POLY B: ");
	ECRIRE (POLY_B);

	for IND in RES.COEF'Range loop
		RES.COEF(IND) := (if IND in POLY_A.COEF'Range then POLY_A.COEF(IND) else Nulle) + (if IND in POLY_B.COEF'Range then POLY_B.COEF(IND) else Nulle);
	end loop;
	ADA.TEXT_IO.PUT_LINE("RES avant d'être réduit : "); ADA.TEXT_IO.NEW_LINE;
	ECRIRE(RES);
	ADA.TEXT_IO.PUT_LINE ("ALORS ,");

	return POLY_REDUIT(RES);
end;

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

* Re: syntaxic exploration
  2017-12-23 14:46         ` Mehdi Saada
@ 2017-12-23 15:03           ` Mehdi Saada
  2017-12-23 22:11             ` Niklas Holsti
  0 siblings, 1 reply; 49+ messages in thread
From: Mehdi Saada @ 2017-12-23 15:03 UTC (permalink / raw)


the function "+" is wrong as well.

input (-2 + X, 7 - 1X) the output is 5 -2X**2, which is complete nonsense, especially since that piece of code (conditional expression) isn't mine. The chunk of test program calling "+" is:
Put_Line ("Pl + P2 = ");
Ecrire(Poly1 + Poly2);

function "+" (POLY_A, POLY_B: T_POLYNOME) return T_POLYNOME is
  RES: T_POLYNOME (T_DEGRE'MAX(POLY_A.DEGRE,POLY_B.DEGRE));
  begin
    ADA.TEXT_IO.PUT_LINE("POLY A: ");
    ECRIRE (POLY_A);
    ADA.TEXT_IO.PUT_LINE("POLY B: ");
    ECRIRE (POLY_B);
    for IND in RES.COEF'Range loop
       RES.COEF(IND) := (if IND in POLY_A.COEF'Range then POLY_A.COEF(IND) else Nulle) + (if IND in POLY_B.COEF'Range then POLY_B.COEF(IND) else Nulle);
    end loop;
    ADA.TEXT_IO.PUT_LINE("RES avant d'être réduit : "); ADA.TEXT_IO.NEW_LINE;
    ECRIRE(RES);
    return POLY_REDUIT(RES);
    end;

It outputs:
Pl + P2 = 
POLY A: 
-2 +X 
POLY B: 
7 -1X 
RES avant d'être réduit : 

5 -2X** 2 

Do you thing I should take a break from Ada and invest time more on algorithmic courses ? Because I feel really down now. I simply shouldn't be so mediocre. I didn't use to be a second-rate student for the matters I liked.


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

* Re: syntaxic exploration
  2017-12-22 22:11           ` Niklas Holsti
  2017-12-22 22:51             ` Dmitry A. Kazakov
@ 2017-12-23 16:23             ` Jeffrey R. Carter
  2017-12-24  3:37               ` Robert Eachus
  2017-12-24 13:32               ` Niklas Holsti
  1 sibling, 2 replies; 49+ messages in thread
From: Jeffrey R. Carter @ 2017-12-23 16:23 UTC (permalink / raw)


On 12/22/2017 11:11 PM, Niklas Holsti wrote:
> 
> I think the aggregate form (null array) was suggested some time ago, in analogy 
> with the existing (null record). It looks good to me, but as I remember, there 
> was some objection. One problem is that if the index type has exactly one value, 
> then a null array with that index type cannot exist (because then A'First = 
> A'Last for any such array A).

Actually, a null array of such a type can exist if it's a string type, because 
you can use the string literal "" for such types. AIUI, 'Last is undefined for 
such a value. Allowing (null array) for non-string array types with an index 
type with a single value would presumably work the same.

-- 
Jeff Carter
"The time has come to act, and act fast. I'm leaving."
Blazing Saddles
36

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

* Re: syntaxic exploration
  2017-12-23 15:03           ` Mehdi Saada
@ 2017-12-23 22:11             ` Niklas Holsti
  2017-12-24  0:55               ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Niklas Holsti @ 2017-12-23 22:11 UTC (permalink / raw)


On 17-12-23 17:03 , Mehdi Saada wrote:
> the function "+" is wrong as well.

Sorry, can't much help you debug this, as most of your code is still not 
shown. For example, the error might be in your ECRIRE procedure, or in 
your operations on T_Rationnel.

> Do you thing I should take a break from Ada and invest time more on
> algorithmic courses ? Because I feel really down now. I simply
> shouldn't be so mediocre. I didn't use to be a second-rate student
> for the matters I liked.

Have you _reviewed_ and _tested_ your code for T_Rationnel and ECRIRE? 
Are you sure that they work?

How about starting with T_Rationnel replaced by Integer (for example, 
subtype T_Rationnel is Integer), and then seeing if the polynomial 
operations work with this simpler coefficient type?

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


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

* Re: syntaxic exploration
  2017-12-23 22:11             ` Niklas Holsti
@ 2017-12-24  0:55               ` Mehdi Saada
  0 siblings, 0 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-24  0:55 UTC (permalink / raw)


I haven't tested them, since they are provided to the student. Hence the unlikeliness of them containing errors... also, I shouldn't, at that point, be testing anything so thoroughly.

It's ok, my stagnation is logical, since 5 directed works are lacking. The best course available ever, with a third of its exercices, absent, nowhere to be found on the internet... I just contacted the teacher. That's ridiculously detrimental to the community as a whole, at least the French Ada community. 

But I'll replace rationals by integers or float, good exercice. simplifies the whole for my head too :-)


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

* Re: syntaxic exploration
  2017-12-23 16:23             ` Jeffrey R. Carter
@ 2017-12-24  3:37               ` Robert Eachus
  2017-12-24 13:39                 ` Niklas Holsti
  2017-12-24 13:32               ` Niklas Holsti
  1 sibling, 1 reply; 49+ messages in thread
From: Robert Eachus @ 2017-12-24  3:37 UTC (permalink / raw)


On Saturday, December 23, 2017 at 11:23:32 AM UTC-5, Jeffrey R. Carter wrote:
> On 12/22/2017 11:11 PM, Niklas Holsti wrote:
> > 
> > I think the aggregate form (null array) was suggested some time ago, in analogy 
> > with the existing (null record). It looks good to me, but as I remember, there 
> > was some objection. One problem is that if the index type has exactly one value, 
> > then a null array with that index type cannot exist (because then A'First = 
> > A'Last for any such array A).
> 
> Actually, a null array of such a type can exist if it's a string type, because 
> you can use the string literal "" for such types. AIUI, 'Last is undefined for 
> such a value. Allowing (null array) for non-string array types with an index 
> type with a single value would presumably work the same.

The rule that allows 1..0 as a null string range only has a problem if you have an array with an enumeration index type containing a single component.  I think that is one of those cases where we say, "Don't do that!" and move on.

A more complex, and potentially ugly case is for multidimensional arrays.  Defining (null array) as being empty in all dimensions with Foo'Range(n) = Bar'First..Bar'Pred(Bar'First) where Bar is the nth index SUBtype for Foo works.  If the last materialized is a (real) Numeric_Error AKA Constraint_Error?  Again, only an issue for smart alecks. In general, you should be surprised if Foo'Last(N) for a null array doesn't raise Constraint_Error.


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

* Re: syntaxic exploration
  2017-12-23 16:23             ` Jeffrey R. Carter
  2017-12-24  3:37               ` Robert Eachus
@ 2017-12-24 13:32               ` Niklas Holsti
  2017-12-25 13:40                 ` Jeffrey R. Carter
  1 sibling, 1 reply; 49+ messages in thread
From: Niklas Holsti @ 2017-12-24 13:32 UTC (permalink / raw)


On 17-12-23 18:23 , Jeffrey R. Carter wrote:
> On 12/22/2017 11:11 PM, Niklas Holsti wrote:
>>
>> I think the aggregate form (null array) was suggested some time ago,
>> in analogy with the existing (null record). It looks good to me, but
>> as I remember, there was some objection. One problem is that if the
>> index type has exactly one value, then a null array with that index
>> type cannot exist (because then A'First = A'Last for any such array A).
>
> Actually, a null array of such a type can exist if it's a string type,
> because you can use the string literal "" for such types. AIUI, 'Last is
> undefined for such a value.

RM 4.2(9) says "for a null string literal, the upper bound is the 
predecessor of the lower bound". I would understand this to mean 
applying 'Pred to the lower bound, which will raise Constraint_Error if 
the type has only one value.

If I try this with GNAT:

    type One_T is (Unique);
    type Str_T is array (One_T range <>) of Character;
    S : constant Str_T := "";

I get compilation errors:

    nullstr.adb:11:26: null string literal not allowed for type
       "Str_T"  defined at line 9
    nullstr.adb:11:26: static expression fails Constraint_Check

where line 11 is the one with the "" literal.

So one can try to make a null array of this type with "", but it will fail.

> Allowing (null array) for non-string array
> types with an index type with a single value would presumably work the
> same.

I agree, it should also raise Constraint_Error.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


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

* Re: syntaxic exploration
  2017-12-24  3:37               ` Robert Eachus
@ 2017-12-24 13:39                 ` Niklas Holsti
  0 siblings, 0 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-24 13:39 UTC (permalink / raw)


On 17-12-24 05:37 , Robert Eachus wrote:
> On Saturday, December 23, 2017 at 11:23:32 AM UTC-5, Jeffrey R.
> Carter wrote:
>> On 12/22/2017 11:11 PM, Niklas Holsti wrote:
>>>
>>> I think the aggregate form (null array) was suggested some time
>>> ago, in analogy with the existing (null record). It looks good to
>>> me, but as I remember, there was some objection. One problem is
>>> that if the index type has exactly one value, then a null array
>>> with that index type cannot exist (because then A'First = A'Last
>>> for any such array A).

   [snip]

> A more complex, and potentially ugly case is for multidimensional
> arrays.  Defining (null array) as being empty in all dimensions with
> Foo'Range(n) = Bar'First..Bar'Pred(Bar'First) where Bar is the nth
> index SUBtype for Foo works.

In other words, the same as the current rule for the null string literal "".

> In general, you should be surprised if Foo'Last(N) for a null
> array doesn't raise Constraint_Error.

That is not true in current Ada, as I understand it.

That would be very bad -- it would mean that any general operation that 
loops over an array that is potentially null would have to first check 
the 'Length. Fortunately this is not the case.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


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

* Re: syntaxic exploration
  2017-12-24 13:32               ` Niklas Holsti
@ 2017-12-25 13:40                 ` Jeffrey R. Carter
  2017-12-25 14:42                   ` Mehdi Saada
  0 siblings, 1 reply; 49+ messages in thread
From: Jeffrey R. Carter @ 2017-12-25 13:40 UTC (permalink / raw)


On 12/24/2017 02:32 PM, Niklas Holsti wrote:
> 
> If I try this with GNAT:
> 
>     type One_T is (Unique);
>     type Str_T is array (One_T range <>) of Character;
>     S : constant Str_T := "";
> 
> I get compilation errors:
> 
>     nullstr.adb:11:26: null string literal not allowed for type
>        "Str_T"  defined at line 9
>     nullstr.adb:11:26: static expression fails Constraint_Check

Interesting. I'm pretty sure that used to work. Has that changed in a recent 
revision?

-- 
Jeff Carter
"My little plum, I am like Robin Hood. I take from
the rich, and I give to the poor. ... Us poor."
Poppy
96


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

* Re: syntaxic exploration
  2017-12-25 13:40                 ` Jeffrey R. Carter
@ 2017-12-25 14:42                   ` Mehdi Saada
  2017-12-25 17:03                     ` Dmitry A. Kazakov
                                       ` (2 more replies)
  0 siblings, 3 replies; 49+ messages in thread
From: Mehdi Saada @ 2017-12-25 14:42 UTC (permalink / raw)


More importantly, why would anyone use an enumeration type with only one  value ? I don't get it.

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

* Re: syntaxic exploration
  2017-12-25 14:42                   ` Mehdi Saada
@ 2017-12-25 17:03                     ` Dmitry A. Kazakov
  2017-12-25 18:27                     ` Niklas Holsti
  2017-12-25 20:12                     ` Jacob Sparre Andersen
  2 siblings, 0 replies; 49+ messages in thread
From: Dmitry A. Kazakov @ 2017-12-25 17:03 UTC (permalink / raw)


On 2017-12-25 15:42, Mehdi Saada wrote:
> More importantly, why would anyone use an enumeration type with only
> one value ? I don't get it.

Consider table-driven descent-recursive parser. The template is

    case Statement_Table.Match (Source) is
       when If_Token =>
          ...
       when For_Token =>
          ...
    end case;

Statement_Table is a type from a generic table package instantiated with 
a token enumeration type. Should the table have only one expected match 
the enumeration type has just one element.

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

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

* Re: syntaxic exploration
  2017-12-25 14:42                   ` Mehdi Saada
  2017-12-25 17:03                     ` Dmitry A. Kazakov
@ 2017-12-25 18:27                     ` Niklas Holsti
  2017-12-25 20:12                     ` Jacob Sparre Andersen
  2 siblings, 0 replies; 49+ messages in thread
From: Niklas Holsti @ 2017-12-25 18:27 UTC (permalink / raw)


On 17-12-25 16:42 , Mehdi Saada wrote:
> More importantly, why would anyone use an enumeration
> type with only one  value ? I don't get it.

It's a limit case that comes up fairly often when one creates generic 
software components parametrized by enumeration types, or other discrete 
types. (Sometimes one would like to use such a component with an 
enumeration type that has _no_ elements, but that seldom works...)

Null record types (with no components) and empty arrays are similar 
limit cases. The number zero and the empty set are others. It is 
important that language has sensible and consistent rules for these 
limits (for example, a loop over an empty array should execute the loop 
body zero times) so that generic code can be written without always 
handling these limit cases separately.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: syntaxic exploration
  2017-12-25 14:42                   ` Mehdi Saada
  2017-12-25 17:03                     ` Dmitry A. Kazakov
  2017-12-25 18:27                     ` Niklas Holsti
@ 2017-12-25 20:12                     ` Jacob Sparre Andersen
  2 siblings, 0 replies; 49+ messages in thread
From: Jacob Sparre Andersen @ 2017-12-25 20:12 UTC (permalink / raw)


Mehdi Saada <00120260a@gmail.com> writes:

> More importantly, why would anyone use an enumeration type with only
> one value ? I don't get it.

Because it is planned that there may be more than one value.  Or because
the type had more than one value, but doesn't have it in the current
version of the program.

If you look at a program which isn't a teenager anymore, both of those
cases can apply.

Greetings,

Jacob
-- 
"The three principal virtues of a programmer are Laziness,
 Impatience, and Hubris"                       -- Larry Wall

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

end of thread, other threads:[~2017-12-25 20:12 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-20 17:28 syntaxic exploration Mehdi Saada
2017-12-20 17:32 ` Mehdi Saada
2017-12-20 20:08   ` Niklas Holsti
2017-12-20 22:18     ` Mehdi Saada
2017-12-20 22:45       ` Mehdi Saada
2017-12-21  7:24         ` Randy Brukardt
2017-12-21  7:44           ` Niklas Holsti
2017-12-21  7:21   ` Randy Brukardt
2017-12-21 16:24     ` Jeffrey R. Carter
2017-12-22  5:01       ` Robert Eachus
2017-12-22 21:15         ` Simon Clubley
2017-12-22 22:11           ` Niklas Holsti
2017-12-22 22:51             ` Dmitry A. Kazakov
2017-12-23  7:15               ` Niklas Holsti
2017-12-23 16:23             ` Jeffrey R. Carter
2017-12-24  3:37               ` Robert Eachus
2017-12-24 13:39                 ` Niklas Holsti
2017-12-24 13:32               ` Niklas Holsti
2017-12-25 13:40                 ` Jeffrey R. Carter
2017-12-25 14:42                   ` Mehdi Saada
2017-12-25 17:03                     ` Dmitry A. Kazakov
2017-12-25 18:27                     ` Niklas Holsti
2017-12-25 20:12                     ` Jacob Sparre Andersen
2017-12-20 20:05 ` Niklas Holsti
2017-12-20 22:48 ` Mehdi Saada
2017-12-20 23:39   ` Mehdi Saada
2017-12-21  0:35 ` Mehdi Saada
2017-12-21  7:18 ` Randy Brukardt
2017-12-21 19:23   ` G. B.
2017-12-21 23:46   ` bj.mooremr
2017-12-22 23:45     ` Randy Brukardt
2017-12-22 13:31 ` Mehdi Saada
2017-12-22 18:00   ` Mehdi Saada
2017-12-22 18:27   ` Niklas Holsti
2017-12-22 20:25     ` Mehdi Saada
2017-12-22 22:33       ` Niklas Holsti
2017-12-23  1:47 ` Mehdi Saada
2017-12-23  7:17   ` Niklas Holsti
2017-12-23 11:23     ` Mehdi Saada
2017-12-23 11:39       ` Mehdi Saada
2017-12-23 12:09         ` Niklas Holsti
2017-12-23 12:12 ` Mehdi Saada
2017-12-23 12:16   ` Mehdi Saada
2017-12-23 13:04     ` Niklas Holsti
2017-12-23 14:02       ` Mehdi Saada
2017-12-23 14:46         ` Mehdi Saada
2017-12-23 15:03           ` Mehdi Saada
2017-12-23 22:11             ` Niklas Holsti
2017-12-24  0:55               ` Mehdi Saada

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