comp.lang.ada
 help / color / mirror / Atom feed
* Better way to fill Storage_IO?
@ 2021-05-17 18:44 Michael Hardeman
  2021-05-17 19:14 ` Simon Wright
  2021-05-18 16:50 ` Shark8
  0 siblings, 2 replies; 20+ messages in thread
From: Michael Hardeman @ 2021-05-17 18:44 UTC (permalink / raw)


So I've been messing around with the new Ada 2020 package Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it correctly it allows you to treat your program's memory like a stream without having to open file descriptors (which should make it faster?). That seems like a powerful abstraction to me and a great addition to the language.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams; use Ada.Streams;
with Ada.Streams.Storage.Unbounded; use Ada.Streams.Storage.Unbounded;

procedure Test is
  Test : String := "040b2cec765b4bbbdb29d83b6dcaf776";
  Test_Stream : aliased Stream_Type;
begin
  String'Write(Test_Stream'Access, Test);
  for I in 1 .. Element_Count (Test_Stream) loop
    declare
      C : Character;
    begin
      Character'Read (Test_Stream'Access, C);
      Put (C);
    end;
  end loop;
end Test;

I was wondering if we could find a better way to fill the stream other than writing the variables into it? Can anyone figure out a good way to just stream a variable's bytes directly?

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

* Re: Better way to fill Storage_IO?
  2021-05-17 18:44 Better way to fill Storage_IO? Michael Hardeman
@ 2021-05-17 19:14 ` Simon Wright
  2021-05-17 19:23   ` Michael Hardeman
  2021-05-17 20:20   ` Dmitry A. Kazakov
  2021-05-18 16:50 ` Shark8
  1 sibling, 2 replies; 20+ messages in thread
From: Simon Wright @ 2021-05-17 19:14 UTC (permalink / raw)


Michael Hardeman <mhardeman25@gmail.com> writes:

> So I've been messing around with the new Ada 2020 package
> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
> correctly it allows you to treat your program's memory like a stream
> without having to open file descriptors (which should make it
> faster?). That seems like a powerful abstraction to me and a great
> addition to the language.

This would be my version:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams.Storage.Unbounded;

procedure Test is
  Test : constant String := "040b2cec765b4bbbdb29d83b6dcaf776";
  Test_Stream : aliased Ada.Streams.Storage.Unbounded.Stream_Type;
begin
   String'Output (Test_Stream'Access, Test);
   declare
      S : constant String := String'Input (Test_Stream'Access);
   begin
      Put_Line (S);
   end;
end Test;

'Output writes the discriminants of the object, if any, then the object;
'Input uses them to reconstruct the object, so in this case that means
the bounds, and hence the length.

> I was wondering if we could find a better way to fill the stream other
> than writing the variables into it? Can anyone figure out a good way
> to just stream a variable's bytes directly?

This *is* the way to just stream the variable's bytes directly. What
sort of syntax were you hoping for?

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

* Re: Better way to fill Storage_IO?
  2021-05-17 19:14 ` Simon Wright
@ 2021-05-17 19:23   ` Michael Hardeman
  2021-05-18 20:39     ` Simon Wright
  2021-05-17 20:20   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 20+ messages in thread
From: Michael Hardeman @ 2021-05-17 19:23 UTC (permalink / raw)


On Monday, May 17, 2021 at 3:14:43 PM UTC-4, Simon Wright wrote:
> 
> 'Output writes the discriminants of the object, if any, then the object; 
> 'Input uses them to reconstruct the object, so in this case that means 
> the bounds, and hence the length.
> > I was wondering if we could find a better way to fill the stream other 
> > than writing the variables into it? Can anyone figure out a good way 
> > to just stream a variable's bytes directly?
> This *is* the way to just stream the variable's bytes directly. What 
> sort of syntax were you hoping for?

I was kind of hoping there would be an interface like Ada.Text_IO.Text_Streams, where you could just directly stream from the variable's address or access without having to write the variable into the stream first. I'm not sure, but the writing part seems a bit like an extra step.

This would be my version: 
> 
> with Ada.Text_IO; use Ada.Text_IO; 
> with Ada.Streams.Storage.Unbounded; 
> 
> procedure Test is 
> Test : constant String := "040b2cec765b4bbbdb29d83b6dcaf776"; 
> Test_Stream : aliased Ada.Streams.Storage.Unbounded.Stream_Type; 
> begin 
> String'Output (Test_Stream'Access, Test); 
> declare 
> S : constant String := String'Input (Test_Stream'Access); 
> begin 
> Put_Line (S); 
> end; 
> end Test; 

I was kind of trying to show you could move through the stream like a parser instead of just consuming the whole thing. i.e. like if you wanted to parse the hex into an array of Unsigned_32 or Unsigned_64 for some algorithm.

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

* Re: Better way to fill Storage_IO?
  2021-05-17 19:14 ` Simon Wright
  2021-05-17 19:23   ` Michael Hardeman
@ 2021-05-17 20:20   ` Dmitry A. Kazakov
  2021-05-17 20:48     ` Michael Hardeman
  2021-05-18  9:08     ` J-P. Rosen
  1 sibling, 2 replies; 20+ messages in thread
From: Dmitry A. Kazakov @ 2021-05-17 20:20 UTC (permalink / raw)


On 2021-05-17 21:14, Simon Wright wrote:
> Michael Hardeman <mhardeman25@gmail.com> writes:
> 
>> So I've been messing around with the new Ada 2020 package
>> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
>> correctly it allows you to treat your program's memory like a stream
>> without having to open file descriptors (which should make it
>> faster?). That seems like a powerful abstraction to me and a great
>> addition to the language.

1. It was always possible, since Ada 95, actually. So it is not that 
great addition.

2. The package as described is not a replacement for I/O, because it 
lacks blocking/synchronization and because it does not work between 
processes. E.g. at the end of the stream Read must rather block for an 
incoming Write. Both are quite possible to implement though.

A great addition would be properly tagged protected objects and tasks. A 
blocking stream cannot support timed entry call syntax like this:

    select
       S := String'Input (Pipe'Access); -- This is not Ada!
    or delay 1.0;
       raise Timed_Out;
    end select;

And note another problem. Entries do not work with indefinite objects. 
You cannot return String from an entry call.

And yet another problem, you cannot use returned objects in many places, 
like in an entry call above.

>> I was wondering if we could find a better way to fill the stream other
>> than writing the variables into it? Can anyone figure out a good way
>> to just stream a variable's bytes directly?

Allocators, of course. I am using both allocators and memory-mapped 
streams (though of a greater variety, e.g. for blocked exchange, 
encryption, interporcess communication).

> This *is* the way to just stream the variable's bytes directly. What
> sort of syntax were you hoping for?

Both allocators and streams require explicit specification of the type. 
Clearly, that is a way around multiple dispatch, but it is way too 
heavy. Access to stream is no more necessary in 'Input. It was not 
necessary when it was introduced in Ada 95. The Rosen's trick allows 
circumvent in- parameter modes, when necessary.

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

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

* Re: Better way to fill Storage_IO?
  2021-05-17 20:20   ` Dmitry A. Kazakov
@ 2021-05-17 20:48     ` Michael Hardeman
  2021-05-18 14:00       ` Per Sandberg
  2021-05-18  9:08     ` J-P. Rosen
  1 sibling, 1 reply; 20+ messages in thread
From: Michael Hardeman @ 2021-05-17 20:48 UTC (permalink / raw)


On Monday, May 17, 2021 at 4:20:14 PM UTC-4, Dmitry A. Kazakov wrote:
> On 2021-05-17 21:14, Simon Wright wrote: 
> > Michael Hardeman <mhard...@gmail.com> writes: 
> > 
> >> So I've been messing around with the new Ada 2020 package 
> >> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it 
> >> correctly it allows you to treat your program's memory like a stream 
> >> without having to open file descriptors (which should make it 
> >> faster?). That seems like a powerful abstraction to me and a great 
> >> addition to the language.
> 1. It was always possible, since Ada 95, actually. So it is not that 
> great addition. 
> 
> 2. The package as described is not a replacement for I/O, because it 
> lacks blocking/synchronization and because it does not work between 
> processes. E.g. at the end of the stream Read must rather block for an 
> incoming Write. Both are quite possible to implement though. 
> 
> A great addition would be properly tagged protected objects and tasks. A 
> blocking stream cannot support timed entry call syntax like this: 
> 
> select 
> S := String'Input (Pipe'Access); -- This is not Ada! 
> or delay 1.0; 
> raise Timed_Out; 
> end select; 
> 
> And note another problem. Entries do not work with indefinite objects. 
> You cannot return String from an entry call. 
> 
> And yet another problem, you cannot use returned objects in many places, 
> like in an entry call above.
> >> I was wondering if we could find a better way to fill the stream other 
> >> than writing the variables into it? Can anyone figure out a good way 
> >> to just stream a variable's bytes directly?
> Allocators, of course. I am using both allocators and memory-mapped 
> streams (though of a greater variety, e.g. for blocked exchange, 
> encryption, interporcess communication).
> > This *is* the way to just stream the variable's bytes directly. What 
> > sort of syntax were you hoping for?
> Both allocators and streams require explicit specification of the type. 
> Clearly, that is a way around multiple dispatch, but it is way too 
> heavy. Access to stream is no more necessary in 'Input. It was not 
> necessary when it was introduced in Ada 95. The Rosen's trick allows 
> circumvent in- parameter modes, when necessary. 
> 
> -- 
> Regards, 
> Dmitry A. Kazakov 
> http://www.dmitry-kazakov.de

Hey Dmitry,

> Allocators, of course. I am using both allocators and memory-mapped 
> streams (though of a greater variety, e.g. for blocked exchange, 
> encryption, interporcess communication).

Could you show me an example of how I could do this with allocators?

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

* Re: Better way to fill Storage_IO?
  2021-05-17 20:20   ` Dmitry A. Kazakov
  2021-05-17 20:48     ` Michael Hardeman
@ 2021-05-18  9:08     ` J-P. Rosen
  2021-05-18 10:10       ` Jeffrey R. Carter
  1 sibling, 1 reply; 20+ messages in thread
From: J-P. Rosen @ 2021-05-18  9:08 UTC (permalink / raw)


Le 17/05/2021 à 22:20, Dmitry A. Kazakov a écrit :
> On 2021-05-17 21:14, Simon Wright wrote:
>> Michael Hardeman <mhardeman25@gmail.com> writes:
>>
>>> So I've been messing around with the new Ada 2020 package
>>> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
>>> correctly it allows you to treat your program's memory like a stream
>>> without having to open file descriptors (which should make it
>>> faster?). That seems like a powerful abstraction to me and a great
>>> addition to the language.
> 
> 1. It was always possible, since Ada 95, actually. So it is not that 
> great addition.
For example, you can get Storage_Stream from Adalog's components page:
https://www.adalog.fr/en/components.html#Storage_Stream

[...]
> And note another problem. Entries do not work with indefinite objects. 
> You cannot return String from an entry call.
True, but you can return an indefinite holder containing the string.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

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

* Re: Better way to fill Storage_IO?
  2021-05-18  9:08     ` J-P. Rosen
@ 2021-05-18 10:10       ` Jeffrey R. Carter
  0 siblings, 0 replies; 20+ messages in thread
From: Jeffrey R. Carter @ 2021-05-18 10:10 UTC (permalink / raw)


On 5/18/21 11:08 AM, J-P. Rosen wrote:
> 
> True, but you can return an indefinite holder containing the string.

Usually called Unbounded_String.

-- 
Jeff Carter
"Damn it, Jim, I'm an actor, not a doctor."
124

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

* Re: Better way to fill Storage_IO?
  2021-05-17 20:48     ` Michael Hardeman
@ 2021-05-18 14:00       ` Per Sandberg
  0 siblings, 0 replies; 20+ messages in thread
From: Per Sandberg @ 2021-05-18 14:00 UTC (permalink / raw)


To emulate a stream on "any" locatoion
https://github.com/persan/a-stream-tools
/P


On 17/05/2021 22:48, Michael Hardeman wrote:
> On Monday, May 17, 2021 at 4:20:14 PM UTC-4, Dmitry A. Kazakov wrote:
>> On 2021-05-17 21:14, Simon Wright wrote:
>>> Michael Hardeman <mhard...@gmail.com> writes:
>>>
>>>> So I've been messing around with the new Ada 2020 package
>>>> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
>>>> correctly it allows you to treat your program's memory like a stream
>>>> without having to open file descriptors (which should make it
>>>> faster?). That seems like a powerful abstraction to me and a great
>>>> addition to the language.
>> 1. It was always possible, since Ada 95, actually. So it is not that
>> great addition.
>>
>> 2. The package as described is not a replacement for I/O, because it
>> lacks blocking/synchronization and because it does not work between
>> processes. E.g. at the end of the stream Read must rather block for an
>> incoming Write. Both are quite possible to implement though.
>>
>> A great addition would be properly tagged protected objects and tasks. A
>> blocking stream cannot support timed entry call syntax like this:
>>
>> select
>> S := String'Input (Pipe'Access); -- This is not Ada!
>> or delay 1.0;
>> raise Timed_Out;
>> end select;
>>
>> And note another problem. Entries do not work with indefinite objects.
>> You cannot return String from an entry call.
>>
>> And yet another problem, you cannot use returned objects in many places,
>> like in an entry call above.
>>>> I was wondering if we could find a better way to fill the stream other
>>>> than writing the variables into it? Can anyone figure out a good way
>>>> to just stream a variable's bytes directly?
>> Allocators, of course. I am using both allocators and memory-mapped
>> streams (though of a greater variety, e.g. for blocked exchange,
>> encryption, interporcess communication).
>>> This *is* the way to just stream the variable's bytes directly. What
>>> sort of syntax were you hoping for?
>> Both allocators and streams require explicit specification of the type.
>> Clearly, that is a way around multiple dispatch, but it is way too
>> heavy. Access to stream is no more necessary in 'Input. It was not
>> necessary when it was introduced in Ada 95. The Rosen's trick allows
>> circumvent in- parameter modes, when necessary.
>>
>> -- 
>> Regards,
>> Dmitry A. Kazakov
>> http://www.dmitry-kazakov.de
> 
> Hey Dmitry,
> 
>> Allocators, of course. I am using both allocators and memory-mapped
>> streams (though of a greater variety, e.g. for blocked exchange,
>> encryption, interporcess communication).
> 
> Could you show me an example of how I could do this with allocators?
> 

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

* Re: Better way to fill Storage_IO?
  2021-05-17 18:44 Better way to fill Storage_IO? Michael Hardeman
  2021-05-17 19:14 ` Simon Wright
@ 2021-05-18 16:50 ` Shark8
  1 sibling, 0 replies; 20+ messages in thread
From: Shark8 @ 2021-05-18 16:50 UTC (permalink / raw)


On Monday, May 17, 2021 at 12:44:05 PM UTC-6, mhard wrote:
Here's an implementation of a string-as-a-stream: https://stackoverflow.com/a/66971547/608963
It was used in a JSON parser, so you certainly can use it for parsing... actually the idea here: to have a single production-method shared by stream and string [and file] is really quite nice maintenance-wise, even if you have to jump through a few hoops (like constructing this stream-string type) in order to obtain it.

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

* Re: Better way to fill Storage_IO?
  2021-05-17 19:23   ` Michael Hardeman
@ 2021-05-18 20:39     ` Simon Wright
  2021-05-19  6:24       ` Dmitry A. Kazakov
  2021-05-19  7:17       ` J-P. Rosen
  0 siblings, 2 replies; 20+ messages in thread
From: Simon Wright @ 2021-05-18 20:39 UTC (permalink / raw)


Michael Hardeman <mhardeman25@gmail.com> writes:

> I was kind of hoping there would be an interface like
> Ada.Text_IO.Text_Streams, where you could just directly stream from
> the variable's address or access without having to write the variable
> into the stream first. I'm not sure, but the writing part seems a bit
> like an extra step.
[...]
> I was kind of trying to show you could move through the stream like a
> parser instead of just consuming the whole thing. i.e. like if you
> wanted to parse the hex into an array of Unsigned_32 or Unsigned_64
> for some algorithm.

I don't understand the scenario.

  Source   >>   Stream   >>   Destination

If Source and Destination are in the same process, there's no need to
involve streams at all.

If Source and Destination are separated - different processes on the
same computer, different computers (possibly with different endianness),
different times - we have to agree on a protocol as to what's sent over
the stream. For a String Z, perhaps the first 4 bytes are the
little-endian Z'First, the next are Z'Last, then the actual bytes of Z.

That's what streams are for (and that's what String'Output does).

Once you have the stream, you can go through it in any way you need to;
you must know what to expect so as to make sense of it. In your example,
you have to know that the bytes in the stream are hex characters.

==========

As to creating the stream: I suppose there could be something like
'Image, where the attribute could originally only be applied to a type:
you used to have to say

   Integer'Image (An_Integer)

whereas now you can say just

   An_Integer'Image

so as well as the current ARM 13.13.2(4), for subtype S of type T

   procedure S'Write(
      Stream : not null access Ada.Streams.Root_Stream_Type'Class;
      Item : in T)

one could have for an object O

   procedure O'Write(
      Stream : not null access Ada.Streams.Root_Stream_Type'Class)

but we don't, not even in Ada 202x.

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

* Re: Better way to fill Storage_IO?
  2021-05-18 20:39     ` Simon Wright
@ 2021-05-19  6:24       ` Dmitry A. Kazakov
  2021-05-19  7:17       ` J-P. Rosen
  1 sibling, 0 replies; 20+ messages in thread
From: Dmitry A. Kazakov @ 2021-05-19  6:24 UTC (permalink / raw)


On 2021-05-18 22:39, Simon Wright wrote:
> Michael Hardeman <mhardeman25@gmail.com> writes:
> 
>> I was kind of hoping there would be an interface like
>> Ada.Text_IO.Text_Streams, where you could just directly stream from
>> the variable's address or access without having to write the variable
>> into the stream first. I'm not sure, but the writing part seems a bit
>> like an extra step.
> [...]
>> I was kind of trying to show you could move through the stream like a
>> parser instead of just consuming the whole thing. i.e. like if you
>> wanted to parse the hex into an array of Unsigned_32 or Unsigned_64
>> for some algorithm.
> 
> I don't understand the scenario.
> 
>    Source   >>   Stream   >>   Destination
> 
> If Source and Destination are in the same process, there's no need to
> involve streams at all.

The picture actually is:

    Producer -> Output stream = Input Stream -> Consumer

The producer could be a code generator, the consumer could be a parser.

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

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

* Re: Better way to fill Storage_IO?
  2021-05-18 20:39     ` Simon Wright
  2021-05-19  6:24       ` Dmitry A. Kazakov
@ 2021-05-19  7:17       ` J-P. Rosen
  2021-05-19  8:26         ` Björn Lundin
  2021-05-19 15:39         ` Simon Wright
  1 sibling, 2 replies; 20+ messages in thread
From: J-P. Rosen @ 2021-05-19  7:17 UTC (permalink / raw)


Le 18/05/2021 à 22:39, Simon Wright a écrit :
> so as well as the current ARM 13.13.2(4), for subtype S of type T
> 
>     procedure S'Write(
>        Stream : not null access Ada.Streams.Root_Stream_Type'Class;
>        Item : in T)
> 
> one could have for an object O
> 
>     procedure O'Write(
>        Stream : not null access Ada.Streams.Root_Stream_Type'Class)
> 
> but we don't, not even in Ada 202x.
For what benefit? Saving a few keystrokes?

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

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

* Re: Better way to fill Storage_IO?
  2021-05-19  7:17       ` J-P. Rosen
@ 2021-05-19  8:26         ` Björn Lundin
  2021-05-19 19:25           ` J-P. Rosen
  2021-05-19 15:39         ` Simon Wright
  1 sibling, 1 reply; 20+ messages in thread
From: Björn Lundin @ 2021-05-19  8:26 UTC (permalink / raw)


Den 2021-05-19 kl. 09:17, skrev J-P. Rosen:
> Le 18/05/2021 à 22:39, Simon Wright a écrit :
>> so as well as the current ARM 13.13.2(4), for subtype S of type T
>>
>>     procedure S'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class;
>>        Item : in T)
>>
>> one could have for an object O
>>
>>     procedure O'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class)
>>
>> but we don't, not even in Ada 202x.
> For what benefit? Saving a few keystrokes?
> 

The Integer'Image(An_Integer) changed to An_Integer'Image

the Verb(Object, Parameter) changed to Object.Verb(Parameter)


It does not have to save keystrokes, but it has to be more readable.
More readable is of course in the eye of the beholder.


package Coded_Values is

type WCS_Next_Location_Type_Type is (
   Reject_Position,
   Selection_Point,
   Transfer_Unit);

end Coded_Values;



with Coded_Values;
with Text_Io;

package Test is

   Next_Location : Coded_Values.WCS_Next_Location_Type_Type := 
Coded_Values.Selection_Point;


Given the above I do prefer


Text_IO.Put_Line ("Next is " & Next_Location'Image);

over

Text_IO.Put_Line ("Next is " & 
Coded_Values.WCS_Next_Location_Type_Type'Image(Next_Location));


or when a use clause is in effect
Text_IO.Put_Line ("Next is " & 
WCS_Next_Location_Type_Type'Image(Next_Location));


even with a use clause I prefer the 'image on the variable.
In my eyes

Text_IO.Put_Line ("Next is " & Next_Location'Image);

Is the better and more readable choice.


That is likely the case of the analog stream discussion above.


Syntax matter. If Ada is to grow it has to have a pleasant syntax,
that is not perceived as clumsy or overly wordy.


-- 
Björn

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

* Re: Better way to fill Storage_IO?
  2021-05-19  7:17       ` J-P. Rosen
  2021-05-19  8:26         ` Björn Lundin
@ 2021-05-19 15:39         ` Simon Wright
  1 sibling, 0 replies; 20+ messages in thread
From: Simon Wright @ 2021-05-19 15:39 UTC (permalink / raw)


"J-P. Rosen" <rosen@adalog.fr> writes:

> Le 18/05/2021 à 22:39, Simon Wright a écrit :
>> so as well as the current ARM 13.13.2(4), for subtype S of type T
>>     procedure S'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class;
>>        Item : in T)
>> one could have for an object O
>>     procedure O'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class)
>> but we don't, not even in Ada 202x.
> For what benefit? Saving a few keystrokes?

I was going to remark on the unlikelihood of ARG's accepting this
keystroke-saving change unless there was evidence of massive demand. In
the case of 'Image, there was the popularity of AdaCore's 'Img
extension.

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

* Re: Better way to fill Storage_IO?
  2021-05-19  8:26         ` Björn Lundin
@ 2021-05-19 19:25           ` J-P. Rosen
  2021-05-19 19:58             ` Dmitry A. Kazakov
  2021-05-19 20:18             ` Björn Lundin
  0 siblings, 2 replies; 20+ messages in thread
From: J-P. Rosen @ 2021-05-19 19:25 UTC (permalink / raw)


Le 19/05/2021 à 10:26, Björn Lundin a écrit :
> Given the above I do prefer
> 
> 
> Text_IO.Put_Line ("Next is " & Next_Location'Image);
> 
> over
> 
> Text_IO.Put_Line ("Next is " & 
> Coded_Values.WCS_Next_Location_Type_Type'Image(Next_Location));

Interesting example. When I define a type that I want to be able to 
print, I define also (in the same place) an instantiation of 
Integer_IO/Enumeration_IO, and I would write:
    Put ("Next is "); Put (Next_Location); New_Line;

'Image was not intended for regular IO.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

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

* Re: Better way to fill Storage_IO?
  2021-05-19 19:25           ` J-P. Rosen
@ 2021-05-19 19:58             ` Dmitry A. Kazakov
  2021-05-19 20:18             ` Björn Lundin
  1 sibling, 0 replies; 20+ messages in thread
From: Dmitry A. Kazakov @ 2021-05-19 19:58 UTC (permalink / raw)


On 2021-05-19 21:25, J-P. Rosen wrote:
> Le 19/05/2021 à 10:26, Björn Lundin a écrit :
>> Given the above I do prefer
>>
>>
>> Text_IO.Put_Line ("Next is " & Next_Location'Image);
>>
>> over
>>
>> Text_IO.Put_Line ("Next is " & 
>> Coded_Values.WCS_Next_Location_Type_Type'Image(Next_Location));
> 
> Interesting example. When I define a type that I want to be able to 
> print, I define also (in the same place) an instantiation of 
> Integer_IO/Enumeration_IO, and I would write:
>     Put ("Next is "); Put (Next_Location); New_Line;
> 
> 'Image was not intended for regular IO.

Maybe it was so in 1983. These days immediate I/O is impractical. Most 
of use cases is about formatting strings and very rarely writing the 
result into some file, usually stream. So 'Image is far more frequently 
used than Integer_IO, Enumeration_IO etc. I did not use any of that for 
decades. A programmer would not even care about them, because he will 
not suddenly change the programming technique universally used with GUI 
widgets, streams, database interfaces, for some obscure generic packages 
when Text_IO gets involved.

So let's modify the example to:

    Dialog.Message.Set_Text ("Next is " &
       Coded_Values.WCS_Next_Location_Type_Type'Image(Next_Location));

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

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

* Re: Better way to fill Storage_IO?
  2021-05-19 19:25           ` J-P. Rosen
  2021-05-19 19:58             ` Dmitry A. Kazakov
@ 2021-05-19 20:18             ` Björn Lundin
  2021-05-20  5:38               ` Niklas Holsti
  1 sibling, 1 reply; 20+ messages in thread
From: Björn Lundin @ 2021-05-19 20:18 UTC (permalink / raw)


Den 2021-05-19 kl. 21:25, skrev J-P. Rosen:
> Le 19/05/2021 à 10:26, Björn Lundin a écrit :
>> Given the above I do prefer
>>
>>
>> Text_IO.Put_Line ("Next is " & Next_Location'Image);
>>
>> over
>>
>> Text_IO.Put_Line ("Next is " & 
>> Coded_Values.WCS_Next_Location_Type_Type'Image(Next_Location));
> 
> Interesting example. When I define a type that I want to be able to 
> print, I define also (in the same place) an instantiation of 
> Integer_IO/Enumeration_IO, and I would write:
>     Put ("Next is "); Put (Next_Location); New_Line;
> 
> 'Image was not intended for regular IO.
> 

If a function/procedure is public, users will use them.
And very likely in ways 'not intended',
So there should be a clear statement in the RM making it clear
that using 'Image is not for regular IO.

We use tons of it for writing to log files
This is why I want 'image for record types.
It would save me from writing To_String functions dumping record values 
into the log. I think it made it into 202x but I am not sure.

And reasoning 'when I define a type I want to print...' does
not really appeal to  me. I'd like the language to provide a way to
create a string version of my variables - basically any of them -
for log file use. When I define a type I am not always thinking if this 
may or may not will be logged in the future, by someone else.
This leads to all types must define a Image/To_String function.

Why? Whats the point? What is the gain?

For records with nested lists I can see challenges,
but for scalar values? Floats? Fixed?

Why not have an easy-to-use AND readable solution?


-- 
Björn

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

* Re: Better way to fill Storage_IO?
  2021-05-19 20:18             ` Björn Lundin
@ 2021-05-20  5:38               ` Niklas Holsti
  2021-05-20  6:50                 ` J-P. Rosen
  0 siblings, 1 reply; 20+ messages in thread
From: Niklas Holsti @ 2021-05-20  5:38 UTC (permalink / raw)


On 2021-05-19 23:18, Björn Lundin wrote:
> Den 2021-05-19 kl. 21:25, skrev J-P. Rosen:
>> ....
>> 'Image was not intended for regular IO.
>>
> 
> If a function/procedure is public, users will use them.


I agree, and I use 'Image a lot.


> And very likely in ways 'not intended',
> So there should be a clear statement in the RM making it clear
> that using 'Image is not for regular IO.


What could the RM say, as motivation? Your karma will decrease 5 points 
every time you use 'Image for regular IO? Or every such use brings a 
1/10000 chance of aborting the program or producing wrong results? :-)


> We use tons of it for writing to log files
> This is why I want 'image for record types.
> It would save me from writing To_String functions dumping record values 
> into the log. I think it made it into 202x but I am not sure.


It is in the 202x proposal, RM 4.10 (32/5). See 
http://www.ada-auth.org/standards/2xaarm/html/AA-4-10.html.

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

* Re: Better way to fill Storage_IO?
  2021-05-20  5:38               ` Niklas Holsti
@ 2021-05-20  6:50                 ` J-P. Rosen
  2021-05-20 22:24                   ` Randy Brukardt
  0 siblings, 1 reply; 20+ messages in thread
From: J-P. Rosen @ 2021-05-20  6:50 UTC (permalink / raw)


Le 20/05/2021 à 07:38, Niklas Holsti a écrit :
> What could the RM say, as motivation? Your karma will decrease 5 points 
> every time you use 'Image for regular IO? Or every such use brings a 
> 1/10000 chance of aborting the program or producing wrong results? :-)
The concern I have with 'Image is that it provides no formatting.
Also for file IO, Put(I) (from Integer_IO) is better than 
Put(Integer'Image(I)), because the former will never break the value on 
two lines, while the latter can if the line length is bounded, making 
the value impossible to read later. Of course, uses other than file IO 
do not have this constraint.

The concern I have with Obj'Image is that there is no clean model of 
what it is. All other attributes are properly defined as predefined 
functions with a profile, they can be used to instantiate generics, etc.

"X'Image denotes the result of calling function S'Image with Arg being 
X, where S is the nominal subtype of X."

So, it's a special notation, like a kind of macro, with no proper 
definition. This hurts my purist's state of mind...

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

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

* Re: Better way to fill Storage_IO?
  2021-05-20  6:50                 ` J-P. Rosen
@ 2021-05-20 22:24                   ` Randy Brukardt
  0 siblings, 0 replies; 20+ messages in thread
From: Randy Brukardt @ 2021-05-20 22:24 UTC (permalink / raw)


"J-P. Rosen" <rosen@adalog.fr> wrote in message 
news:s850rr$mvm$1@dont-email.me...
...
> "X'Image denotes the result of calling function S'Image with Arg being X, 
> where S is the nominal subtype of X."
>
> So, it's a special notation, like a kind of macro, with no proper 
> definition. This hurts my purist's state of mind...

Naw, it's an attribute, just like 'Pos and 'First(N), neither of which 
correspond to anything you can write. Saying that attributes are subprograms 
(outside of the cases where redefinition is allowed, like 'Read) simply buys 
a vast amount of special-case work with virtually no benefit to the user. 
(In Janus/Ada, at least, we have to fake treating these things as functions, 
as we could not afford [back in the day, of course] the space to materialize 
all of these little-used functions. [Float types have some 20-odd of 
them!]).

If someone has to pay a price, it might as well be the language standard and 
not every implementer (and the users that actually try to use these things 
as functions and run into bugs in stuff no one ever tries).

Water under the dam in any case, since no one has any reason to change any 
of this.

                              Randy. 


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

end of thread, other threads:[~2021-05-20 22:24 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-17 18:44 Better way to fill Storage_IO? Michael Hardeman
2021-05-17 19:14 ` Simon Wright
2021-05-17 19:23   ` Michael Hardeman
2021-05-18 20:39     ` Simon Wright
2021-05-19  6:24       ` Dmitry A. Kazakov
2021-05-19  7:17       ` J-P. Rosen
2021-05-19  8:26         ` Björn Lundin
2021-05-19 19:25           ` J-P. Rosen
2021-05-19 19:58             ` Dmitry A. Kazakov
2021-05-19 20:18             ` Björn Lundin
2021-05-20  5:38               ` Niklas Holsti
2021-05-20  6:50                 ` J-P. Rosen
2021-05-20 22:24                   ` Randy Brukardt
2021-05-19 15:39         ` Simon Wright
2021-05-17 20:20   ` Dmitry A. Kazakov
2021-05-17 20:48     ` Michael Hardeman
2021-05-18 14:00       ` Per Sandberg
2021-05-18  9:08     ` J-P. Rosen
2021-05-18 10:10       ` Jeffrey R. Carter
2021-05-18 16:50 ` Shark8

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