comp.lang.ada
 help / color / mirror / Atom feed
* anonymous records as tuples
@ 2018-03-12 17:32 Stephen Leake
  2018-03-12 18:01 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Stephen Leake @ 2018-03-12 17:32 UTC (permalink / raw)


I recently had to change a function that returned a single integer into a procedure that returns two. So my code when from something like:

Next_Shared_Token := Next_Shared_Token - Tree.Count_Terminals (Index);

to:

declare
   Real : Integer;
   Virtual : Integer;
begin
   Tree.Count_Terminals (Index, Real, Virtual);
   if Virtual = 0 then
      Next_Shared_Token := Next_Shared_Token - Real;
   end if;
end;

This bothers me mainly because the variables Real, Virtual are not initialized, and not declared constant, when clearly they should be.

Some other languages handle a similar situation with tuples. For example, in Lua (https://www.lua.org/manual/5.3/manual.html#3.33) this would be:

Real, Virtual = Tree.Count_Terminals (Tree_Index);

We could do something similar in Ada with an "anonymous record":

declare
   constant record
     Real : Integer;
     Virtual : Integer;
   end record := Tree.Count_Terminals (Index);
begin 
   if Virtual = 0 then
      Next_Shared_Token := Next_Shared_Token - Real;
   end if;
end;

Perhaps the 'constant' should appear on each component instead; then some could be not constant.

Count_Terminals would be declared to return an anonymous record:

function Count_Terminals (Tree : in out Tree_Type; Index : in Index_Type)
return record 
  Real : Integer;
  Virtual : Integer;
end record;

The body of Count_Terminals would return a record aggregate for the result.

Allowing anonymous records in other contexts could easily get messy. For example, there could be a larger record containing Real, Virtual:

type Record_1 is record
   A : Float;
   Real : Integer;
   Virtual : Integer;
   B : Float;
end record;

Then an aggregate for that could be:

(A => 1.0, 
 record Real, Virtual end record => Tree.Count_Terminals (I), 
 B => 2.0)

Alternately, the function result could be implicitly deconstructed:

(1.0, Count_Terminals (I), 2.0)

Or we could require Record_1 to contain an anonymous record:

type Record_1 is record
   A : Float;
   record
      Real : Integer;
      Virtual : Integer;
   end record;
   B : Float;
end record;

I have no idea how complicated this would be for compiler implementors.

I searched the Ada Issues database (http://ada-auth.org/search-ai12s.html) for "anonymous record"; it occurs once (http://www.ada-auth.org/sresult.cgi?Search=23&Index=21&File=292&Seq=1), where Bob Duff complains that Ada has anonymous arrays but not anonymous records.

"tuples" appears many times, mostly in discussions, never in an actual proposal.

-- Stephe

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

* Re: anonymous records as tuples
  2018-03-12 17:32 anonymous records as tuples Stephen Leake
@ 2018-03-12 18:01 ` Dmitry A. Kazakov
  2018-03-12 19:17 ` Robert Eachus
  2018-03-12 21:09 ` Jeffrey R. Carter
  2 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2018-03-12 18:01 UTC (permalink / raw)


On 2018-03-12 18:32, Stephen Leake wrote:

> We could do something similar in Ada with an "anonymous record":
> 
> declare
>     constant record
>       Real : Integer;
>       Virtual : Integer;
>     end record := Tree.Count_Terminals (Index);
> begin
>     if Virtual = 0 then
>        Next_Shared_Token := Next_Shared_Token - Real;
>     end if;
> end;
> 
> Perhaps the 'constant' should appear on each component instead; then some could be not constant.

By analogy to anonymous arrays:

  Temp : constant record
                     Real    : Integer;
                     Virtual : Integer;
                  end record := Tree.Count_Terminals (Index);

> Count_Terminals would be declared to return an anonymous record:

> function Count_Terminals (Tree : in out Tree_Type; Index : in Index_Type)
> return record
>    Real : Integer;
>    Virtual : Integer;
> end record;

This has no analogy yet. If anonymous records were allowed, so must be 
arrays:

    function Read return array (Positive range <>) of Character;

BTW, this and anonymous record parameters are analogous [polymorphism] 
to abstract array/record interface. You return a "class-wide" type which 
matches any concrete type (instance) with the same structure.

I prefer explicit classes to by-structure anonymous types as more 
organized and controlled way to handle what is in the class and what is not.

> The body of Count_Terminals would return a record aggregate for the result.
> 
> Allowing anonymous records in other contexts could easily get messy.

It requires matching by-structure, which is always messy.

> Or we could require Record_1 to contain an anonymous record:
> 
> type Record_1 is record
>     A : Float;
>     record
      ^^^^
      C : record

Anonymous record type /= anonymous object/component.

>        Real : Integer;
>        Virtual : Integer;
>     end record;
>     B : Float;
> end record;
> 
> I have no idea how complicated this would be for compiler implementors.
> 
> I searched the Ada Issues database (http://ada-auth.org/search-ai12s.html) for "anonymous record"; it occurs once (http://www.ada-auth.org/sresult.cgi?Search=23&Index=21&File=292&Seq=1), where Bob Duff complains that Ada has anonymous arrays but not anonymous records.
> 
> "tuples" appears many times, mostly in discussions, never in an actual proposal.

Tuples are bit more than just anonymous record types. Tuples also 
require a method of flattening an aggregate or list of arguments/results 
and promotion to a record.

For example when you want pass a record and then pass it down to a 
subprogram as an argument list. Or when you want to declare all elements 
of the result tuple. So that instead of writing this:

    declare
       <anonymous> : record
          Real    : Integer;
          Virtual : Integer;
       end record := Count_Terminals (Tree, Index);
       Real    : Integer renames <anonymous>.Real;
       Virtual : Integer renames <anonymous>.Virtual;

You will do:

    declare
       <> : Count_Terminals (Tree, Index);

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


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

* Re: anonymous records as tuples
  2018-03-12 17:32 anonymous records as tuples Stephen Leake
  2018-03-12 18:01 ` Dmitry A. Kazakov
@ 2018-03-12 19:17 ` Robert Eachus
  2018-03-12 19:34   ` Stephen Leake
  2018-03-12 21:09 ` Jeffrey R. Carter
  2 siblings, 1 reply; 8+ messages in thread
From: Robert Eachus @ 2018-03-12 19:17 UTC (permalink / raw)


On Monday, March 12, 2018 at 1:32:46 PM UTC-4, Stephen Leake wrote:
> I recently had to change a function that returned a single integer into a procedure that returns two...

What is wrong with something like:

-- in Tree:

type Return_Values is record
   Real : Integer; 
   Virtual : Integer;
end record;

function Count_Terminals (Index...) return Return_Values;
...

declare 
  Returned: constant Tree.Return_Values := Tree.Count_Terminals(Index);
  Real: Integer renames Returned.Real;
  Virtual: Integer renames Returned.Virtual;
begin 
  if Virtual = 0 then 
     Next_Shared_Token := Next_Shared_Token - Real; 
  end if;
end;

Declaring Returned as a constant is optional.  (And declaring Real as an Integer really rubs me wrong.  But this is a example...) 


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

* Re: anonymous records as tuples
  2018-03-12 19:17 ` Robert Eachus
@ 2018-03-12 19:34   ` Stephen Leake
  2018-03-12 23:59     ` Randy Brukardt
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Leake @ 2018-03-12 19:34 UTC (permalink / raw)


On Monday, March 12, 2018 at 2:17:08 PM UTC-5, Robert Eachus wrote:
> On Monday, March 12, 2018 at 1:32:46 PM UTC-4, Stephen Leake wrote:
> > I recently had to change a function that returned a single integer into a procedure that returns two...
> 
> What is wrong with something like:
> 
> -- in Tree:
> 
> type Return_Values is record
>    Real : Integer; 
>    Virtual : Integer;
> end record;
> 
> function Count_Terminals (Index...) return Return_Values;
> ...
> 
> declare 
>   Returned: constant Tree.Return_Values := Tree.Count_Terminals(Index);
>   Real: Integer renames Returned.Real;
>   Virtual: Integer renames Returned.Virtual;
> begin 
>   if Virtual = 0 then 
>      Next_Shared_Token := Next_Shared_Token - Real; 
>   end if;
> end;

That works, but is more verbose; I have to make up a name for the result type, when it's really an anonymous tuple of values. But I suspect the ARG would say the gain is not worth the cost.

> (And declaring Real as an Integer really rubs me wrong.)

This is for a parser; it's counting "real tokens" from the source text versus "virtual tokens" inserted by an error recovery process.

I ended up resolving it a different way; first I check if there are any virtual tokens, then I count real tokens.

-- Stephe

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

* Re: anonymous records as tuples
  2018-03-12 17:32 anonymous records as tuples Stephen Leake
  2018-03-12 18:01 ` Dmitry A. Kazakov
  2018-03-12 19:17 ` Robert Eachus
@ 2018-03-12 21:09 ` Jeffrey R. Carter
  2 siblings, 0 replies; 8+ messages in thread
From: Jeffrey R. Carter @ 2018-03-12 21:09 UTC (permalink / raw)


On 03/12/2018 06:32 PM, Stephen Leake wrote:
> 
> We could do something similar in Ada with an "anonymous record":

Anonymous types are a bad idea.

-- 
Jeff Carter
"We'll make Rock Ridge think it's a chicken
that got caught in a tractor's nuts!"
Blazing Saddles
87

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

* Re: anonymous records as tuples
  2018-03-12 19:34   ` Stephen Leake
@ 2018-03-12 23:59     ` Randy Brukardt
  2018-03-13  2:51       ` Dan'l Miller
  0 siblings, 1 reply; 8+ messages in thread
From: Randy Brukardt @ 2018-03-12 23:59 UTC (permalink / raw)


"Stephen Leake" <stephen_leake@stephe-leake.org> wrote in message 
news:290ddbd1-3aa1-4238-8737-51d8090af7d3@googlegroups.com...
> On Monday, March 12, 2018 at 2:17:08 PM UTC-5, Robert Eachus wrote:
>> On Monday, March 12, 2018 at 1:32:46 PM UTC-4, Stephen Leake wrote:
>> > I recently had to change a function that returned a single integer into 
>> > a procedure that returns two...
>>
>> What is wrong with something like:
>>
>> -- in Tree:
>>
>> type Return_Values is record
>>    Real : Integer;
>>    Virtual : Integer;
>> end record;
>>
>> function Count_Terminals (Index...) return Return_Values;
>> ...
>>
>> declare
>>   Returned: constant Tree.Return_Values := Tree.Count_Terminals(Index);
>>   Real: Integer renames Returned.Real;
>>   Virtual: Integer renames Returned.Virtual;
>> begin
>>   if Virtual = 0 then
>>      Next_Shared_Token := Next_Shared_Token - Real;
>>   end if;
>> end;
>
> That works, but is more verbose; I have to make up a name for the
> result type, when it's really an anonymous tuple of values. But I
> suspect the ARG would say the gain is not worth the cost.

I know *I* would say that, and I'd go even further, and say anonymous types 
in general are a bad thing for Ada. Ada is designed around named types 
(where two objects are the same only if the underlying types come from the 
same declaration), while anonymous types pretty much have to be matched 
structurally (if two types define the same structure, then they are the 
same).

There's nothing wrong with structural equivalence per-se, but mixing it with 
named equivalence tends to produce a hodge-podge of rules that mainly 
confuse everyone (implementers and users). And there are so many Ada 
constructs which assume a name is handy (type conversion, generic 
instantiation, and so on) that anonymous types tend to always have an 
incomplete set of capabilities.

But I'm not the ARG (even if it sometimes appears that way), so others may 
feel differently.

                                         Randy.


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

* Re: anonymous records as tuples
  2018-03-12 23:59     ` Randy Brukardt
@ 2018-03-13  2:51       ` Dan'l Miller
  2018-03-13  8:28         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 8+ messages in thread
From: Dan'l Miller @ 2018-03-13  2:51 UTC (permalink / raw)


Randy Brukardt wrote:
> And there are so many Ada 
> constructs which assume a name is handy (type conversion, generic 
> instantiation, and so on) that anonymous types tend to always have an 
> incomplete set of capabilities.

Just to play devil's advocate (for a school of thought that I don't myself subscribe to regarding the current fad of tuples & lambdas), in addition to Ada's current category of •identifier•-based naming, there does exist another kind of naming:  ••reflection-based drill-down••.  Instead of full-fledged anonymity, the de facto name of a pseudo-anonymous type in some future version of Ada could be something to the effect of:  subroutine X's return type, such as with ' syntax as reflection (e.g., 'ReturnType).  (I am not sure that this extends well to anonymous functions or anonymous procedures as lambda-expressions in Ada, because I don't see an easy way to ‘find’ a lambda-expression that lacks a name via reflection.)  It would seem that at least some of Ada's language-defined ' attributes drill down to entities that have no identifier name, e.g., 'Tag and 'Class, so there is some stunted degree of embrace of using reflection drill-down as a de facto name for entities that lack identifier-names.

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

* Re: anonymous records as tuples
  2018-03-13  2:51       ` Dan'l Miller
@ 2018-03-13  8:28         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2018-03-13  8:28 UTC (permalink / raw)


On 13/03/2018 03:51, Dan'l Miller wrote:

> Instead of full-fledged anonymity, the de facto name of a pseudo-anonymous type in some future version of Ada could be something to the effect of:  subroutine X's return type, such as with ' syntax as reflection (e.g., 'ReturnType).

T'Parent, T'Interface (N), R'Member (N), A'Index, A'Element, 
T'Constraints (a tuple of discriminants and bounds)...

The question is how much such types would be allowed to be used, 
especially in generics.

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

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

end of thread, other threads:[~2018-03-13  8:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-12 17:32 anonymous records as tuples Stephen Leake
2018-03-12 18:01 ` Dmitry A. Kazakov
2018-03-12 19:17 ` Robert Eachus
2018-03-12 19:34   ` Stephen Leake
2018-03-12 23:59     ` Randy Brukardt
2018-03-13  2:51       ` Dan'l Miller
2018-03-13  8:28         ` Dmitry A. Kazakov
2018-03-12 21:09 ` Jeffrey R. Carter

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