comp.lang.ada
 help / color / mirror / Atom feed
* article on acces types and dynamic serialization in Ada (2003)
@ 2018-02-21 23:57 Mehdi Saada
  2018-02-22  9:16 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Mehdi Saada @ 2018-02-21 23:57 UTC (permalink / raw)


Hello everyone.
I already mailed you Simon Wright about it, but I've more info and questions, so it put it here. First the context:
I played with streams yesterday to learn more, and stumbled on something not really intuitive, at least. what means exactly Some_access_type'Write(Stream1, Some_Pointer) ?
I could figure out it's implementation defined, so you can't guess.
So that
Some_access_type'Write(stream(Stream_File), Pointer1);
...
Reset(Stream_File, IN_FILE);
Some_access_type'Read(stream(Stream_file), Pointer2);
doesn't work: reaching Pointer2.all raises "erroneous memory access", though Pointer2 isn't null.
Strange, since in my exemple, all happen in the same, hum, "scope of declaration" (apropriate term ?). Any address or whatever information the pointer is made of, should still be valid. Any pool pointed at still exists.
Doesn't feel like a "sane" legal behavior. I also saw a "normal" record object with a pool-specific pointer like this one
type FOO is record
  ...
  BAR: access INTEGER := new INTEGER'(15);
end record;
serializes well, I can read Bar.all. Funny, but where the difference since (according to Ada wikibook) a priori the default 'Write is called for each record component ?

Then I found today that https://infoscience.epfl.ch/record/54724/files/IC_TECH_REPORT_200363.pdf : Automatic Serialization of Dynamic Structures in Ada Technical Report

I was surprised I could read and understand it all with some concentration. And a bit proud, to be honnest ! I would have thought it to be like Chinese at my level.
It was 13 years ago, but I couldn't find a more recent papier on the subject of dynamic serialization, nor has new Dynamic_Stream aspects/attributes been added since then. I didn't read anything either in the stream or access types related sections.

I tried more, but can't write well yet that more complicated exemple:
with Ada.Streams.Stream_IO, Ada.Strings.Unbounded.Text_IO, Ada.Text_IO;
use Ada.Streams.Stream_IO, Ada.Streams, Ada.Strings.Unbounded, Ada.Strings.Unbounded.Text_IO;
procedure Main is
   subtype TSF is File_Type;
   FILE : TSF;
   type CHAMPS;
   type ACCESS_CHAMPS is access ALL CHAMPS;
   type CHAMPS (A: ACCESS_CHAMPS) is record
      NOTE : NATURAL range 0 .. 20 := 0;
   end record;
   
   C2, C1 , C3  :  aliased CHAMPS := (A => null, note => 5); 
begin
        
   C1 := (C2'Access, 14);
   C2 := (A => C1'Access, Note => 5 ); 
   Create (FILE, Append_File, Name => "tentative.stream");
   CHAMPS'Write (Stream (FILE), C2);
   Reset (File => FILE,
	  Mode => In_File );
   CHAMPS'Read(Stream(FILE), C3);
   ada.Text_IO.Put_line (INTEGER'Image (C3.A.all.Note));
   CLOSE(FILE);
end;

raises CONSTRAINT_ERROR : main.adb:15 discriminant check failed
I read as I could about access discrimant aliasing and autoreferencing types, but visibly lack practice ;-)  
Could you help me finish that exemple ? I would be delighted to see what happens by myself, since the former exemple (Some_Access'Write and 'Read) proves interesting.

Gosh, the pleasure these things give me...

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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-21 23:57 article on acces types and dynamic serialization in Ada (2003) Mehdi Saada
@ 2018-02-22  9:16 ` Dmitry A. Kazakov
  2018-02-22 12:08   ` guyclaude.burger
  2018-02-22 12:15 ` Mehdi Saada
  2018-02-23 10:30 ` Mehdi Saada
  2 siblings, 1 reply; 13+ messages in thread
From: Dmitry A. Kazakov @ 2018-02-22  9:16 UTC (permalink / raw)


On 22/02/2018 00:57, Mehdi Saada wrote:

> I already mailed you Simon Wright about it, but I've more info and questions, so it put it here. First the context:
> I played with streams yesterday to learn more, and stumbled on something not really intuitive, at least. what means exactly Some_access_type'Write(Stream1, Some_Pointer) ?

Bug, unless

1. 'Write is overridden, e.g. to flatten the pointer;

2. Stream is used for communication inside the same program, e.g. the 
pointer is simply marshaled.

Linked data serialization requires more work and is usually far less 
straightforward than mere writing pointers. There are many approaches to 
that, e.g. external reference counted objects etc. All this is not 
really related to streams.

P.S. You should simply follow the rule: never ever use predefined 
'Read/'Write/'Input/'Output, except for the case #2, which is probably 
well under 1%.

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

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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-22  9:16 ` Dmitry A. Kazakov
@ 2018-02-22 12:08   ` guyclaude.burger
  0 siblings, 0 replies; 13+ messages in thread
From: guyclaude.burger @ 2018-02-22 12:08 UTC (permalink / raw)


>> what means exactly Some_access_type'Write(Stream1, Some_Pointer) ?
> Bug, unless 
> 2. Stream is used for communication inside the same program, e.g. the 
pointer is simply marshaled. 

"Bug", then why is it allowed... Considering access types as elementary types also confuses me. First thing I learnt about them is you can't hardly ever assume they are simple addresses, or elementary. As for point 2, isn't it what I did in my first example ? I reset the file with mode IN, in immediate enclosing block, 'Read it but got an erroneous memory access.
There might be numerous ways around this linked data issue but having a sane default implementation, as we already have defaults everywhere you can still override. Maybe not enough requests, though it seems logical to me. I wouldn't want to bother with rewriting attributes if I want something as straightforward as "list references and identifiers, reconstruct by aliasing and taking access here, use the stack there". Generics procedures should really be provided in the standard libraries for that. Not enough demands maybe ?


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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-21 23:57 article on acces types and dynamic serialization in Ada (2003) Mehdi Saada
  2018-02-22  9:16 ` Dmitry A. Kazakov
@ 2018-02-22 12:15 ` Mehdi Saada
  2018-02-22 13:04   ` Dmitry A. Kazakov
  2018-02-22 23:49   ` Randy Brukardt
  2018-02-23 10:30 ` Mehdi Saada
  2 siblings, 2 replies; 13+ messages in thread
From: Mehdi Saada @ 2018-02-22 12:15 UTC (permalink / raw)


>> what means exactly Some_access_type'Write(Stream1, Some_Pointer) ?
> Bug, unless 
> 2. Stream is used for communication inside the same program, e.g. the 
> pointer is simply marshaled. 
"Bug", then why is it allowed... Considering access types as elementary types also confuses me. First thing I learnt about them is you can't hardly ever assume they are simple addresses, or elementary. As for point 2, isn't it what I did in my first example ? I reset the file with mode IN, in immediate enclosing block, 'Read it but got an erroneous memory access.
There might be numerous ways around this linked data issue but having a sane default implementation, as we already have defaults everywhere you can still override. At least for something as straightforward as "list references and identifiers, reconstruct by aliasing and taking access here, use the stack there". Generics subprograms could be provided in the standard libraries. 
Not enough requests maybe ?

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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-22 12:15 ` Mehdi Saada
@ 2018-02-22 13:04   ` Dmitry A. Kazakov
  2018-02-22 23:49   ` Randy Brukardt
  1 sibling, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2018-02-22 13:04 UTC (permalink / raw)


On 22/02/2018 13:15, Mehdi Saada wrote:
>>> what means exactly Some_access_type'Write(Stream1, Some_Pointer) ?
>> Bug, unless
>> 2. Stream is used for communication inside the same program, e.g. the
>> pointer is simply marshaled.
> "Bug", then why is it allowed...

It is an elementary operation. It could be abstract though.

> Considering access types as elementary types also confuses me. First
> thing I learnt about them is you can't hardly ever assume they are
> simple addresses,

Why would you assume that? It is an implementation detail that should 
not be your concern. Ada's approach in most cases is to specify the 
required semantics and let the compiler (or designer of the package) to 
choose an implementation.

> or elementary. As for point 2, isn't it what I did in
> my first example ? I reset the file with mode IN, in immediate enclosing
> block,

Marshaling is same as passing things by value. When you pass a pointer 
you are responsible to keep it valid all time it to live. If it lives in 
the file then the target object must outlive that file.

> There might be numerous ways around this linked data issue but having
> a sane default implementation, as we already have defaults everywhere
> you can still override.
None of them is sane, because the RM does not require sanity. Sanity 
here means that you can serialize and deserialize in a portable way. [I 
have some "sane" implementations in Simple Components for some 
elementary types.]

> Generics subprograms could be provided in the standard libraries.
> Not enough requests maybe ?

Serialization en large requires introspection Ada presently lacks.

[It is almost always so that features missing in Ada have deeply rooted 
reasons for being missed.]

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

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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-22 12:15 ` Mehdi Saada
  2018-02-22 13:04   ` Dmitry A. Kazakov
@ 2018-02-22 23:49   ` Randy Brukardt
  2018-02-23  3:40     ` Shark8
  1 sibling, 1 reply; 13+ messages in thread
From: Randy Brukardt @ 2018-02-22 23:49 UTC (permalink / raw)


"Mehdi Saada" <00120260a@gmail.com> wrote in message 
news:5d8580c2-b43d-4b2c-8a46-3a6ed33967aa@googlegroups.com...
...
>There might be numerous ways around this linked data issue but having a
>sane default implementation, as we already have defaults everywhere
>you can still override.

What default (read relatively cheap to read/write) implementation could 
possibly be sane?

As Dmitry points out, full serialization doesn't make sense for Ada -- for 
that matter, it doesn't make sense (as a default) for any language, since 
one has to deal with recursive data structures. Having P'Write go into an 
infinite loop is hardly sane!

To see this, imagine writing a doubly-linked list node with a serializing 
access definition:

                    type Node;
                    type Node_Ptr is access all Node;
                    type Node is record
                          Data : Natural;
                          Prev, Next : Node_Ptr;
                    end record;

For the Node_Ptrs to be written as anything useful, you'd have to dump the 
entire list -- but that then would be duplicative. One really has to write a 
custom solution for each such data structure --- there is no 
one-size-fits-most solution.

As to why it doesn't just raise Program_Error to 'Read/'Write an access 
value, I would say that it is because one can reliably test a read access 
value for null/not null. One then can use that information to determine 
whether or not do do more serialization. Doing that is a lot easier (for 
both the author and the compiler) than separating the record into separate 
components and having to deal with each individually.

OTOH, I once had an argument with Robert Dewar about this, he made the claim 
that one can't rely on that as "implementation-defined" doesn't necessarily 
mean "something trivially cheap". It's hard for me to imagine an 
implementation doing anything other than just dumping the access value 
binary, but argubly he was right. (In practice, I was right so far as I can 
tell.) But in that case, Ptr'Write should raise Program_Error because it can 
never have any useful portable meaning. (Too late now, though, there are 
lots of uses like mine out there.)

                                         Randy.



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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-22 23:49   ` Randy Brukardt
@ 2018-02-23  3:40     ` Shark8
  2018-02-23  7:23       ` Jacob Sparre Andersen
  0 siblings, 1 reply; 13+ messages in thread
From: Shark8 @ 2018-02-23  3:40 UTC (permalink / raw)


On Thursday, February 22, 2018 at 4:49:04 PM UTC-7, Randy Brukardt wrote:
> "Mehdi Saada" wrote in message 
> news:5d8580c2-b43d-4b2c-8a46-3a6ed33967aa
> ...
> >There might be numerous ways around this linked data issue but having a
> >sane default implementation, as we already have defaults everywhere
> >you can still override.
> 
> What default (read relatively cheap to read/write) implementation could 
> possibly be sane?

ASN.1 serialization/deserialization.

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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-23  3:40     ` Shark8
@ 2018-02-23  7:23       ` Jacob Sparre Andersen
  2018-02-23  8:38         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 13+ messages in thread
From: Jacob Sparre Andersen @ 2018-02-23  7:23 UTC (permalink / raw)


Shark8 <onewingedshark@gmail.com> writes:
> On Thursday, February 22, 2018 at 4:49:04 PM UTC-7, Randy Brukardt wrote:

>> What default (read relatively cheap to read/write) implementation
>> could possibly be sane?
>
> ASN.1 serialization/deserialization.

That doesn't solve the problem of the compiler having to figure out how
to interpret the access types.

Greetings,

Jacob
-- 
"All other languages praise themselves for what they allow to do;
 Ada is the only one which praises itself for what it prevents
 from doing" -- J-P. Rosen

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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-23  7:23       ` Jacob Sparre Andersen
@ 2018-02-23  8:38         ` Dmitry A. Kazakov
  2018-02-23 20:28           ` G. B.
  0 siblings, 1 reply; 13+ messages in thread
From: Dmitry A. Kazakov @ 2018-02-23  8:38 UTC (permalink / raw)


On 23/02/2018 08:23, Jacob Sparre Andersen wrote:
> Shark8 <onewingedshark@gmail.com> writes:
>> On Thursday, February 22, 2018 at 4:49:04 PM UTC-7, Randy Brukardt wrote:
> 
>>> What default (read relatively cheap to read/write) implementation
>>> could possibly be sane?
>>
>> ASN.1 serialization/deserialization.
> 
> That doesn't solve the problem of the compiler having to figure out how
> to interpret the access types.

It does not solve any problem, being an utter abomination and horror to 
anyone who must implement a protocol described in this form.

But even if, the point is that data /= type. ASN.1 describes 
representation, not the semantics of a typed object. For most types 
representation alone is not enough to store/restore objects of.

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


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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-21 23:57 article on acces types and dynamic serialization in Ada (2003) Mehdi Saada
  2018-02-22  9:16 ` Dmitry A. Kazakov
  2018-02-22 12:15 ` Mehdi Saada
@ 2018-02-23 10:30 ` Mehdi Saada
  2018-02-23 13:13   ` Dmitry A. Kazakov
  2 siblings, 1 reply; 13+ messages in thread
From: Mehdi Saada @ 2018-02-23 10:30 UTC (permalink / raw)


> full serialization doesn't make sense (as a default) for any language, since
one has to deal with recursive data structures. Having P'Write go into an
infinite loop is hardly sane!
It goes without saying. That's why the paper (and Dmitry also) talked about reference counting. It supposes a protocol and more informations than just data and bounds, to associate such node with another, in which way.
It could be I'm just too ignorant of data-structures, but besides (different types of) nodes and (different types of) pointers to represent arrows/links, I don't see why a reference counting strategy wouldn't work for all. That would use a (flat/binary, no json or whatever) uniform data-structures description protocol  protocol of data structures. The graph
(1)(A,_1_,_3_)(2)(B,_1_,_3_)(3)(C,_2_,_3_)
You would have to indicate how many such nodes are laid out, nodes or anything else, create as much (general) access values, and points the indicated nodes (_1_ being the first written). A bit of (lame) ASCI art; 
 .<--|
 |->(1,A)-->(2,B)
     ^       |
     |      `-'
     |----- -3->.  
             |<__] 

> For the Node_Ptrs to be written as anything useful, you'd have to dump the
entire list -- but that then would be duplicative.
Go through, not dump... hence the use of lists. I'll try contacting the guy, maybe he tried develop such a generic algorithm and failed. I'll learn something at least.

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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-23 10:30 ` Mehdi Saada
@ 2018-02-23 13:13   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2018-02-23 13:13 UTC (permalink / raw)


On 23/02/2018 11:30, Mehdi Saada wrote:

> It could be I'm just too ignorant of data-structures, but besides (different types of) nodes and (different types of) pointers to represent arrows/links, I don't see why a reference counting strategy wouldn't work for all.

Why it works, but requires a massive infrastructure. In general, you 
need external and internal reference counting. You will have external 
objects and memory-mapped proxies of. You will have to synchronize, 
commit, when proxy's internal reference count = 0, but the external 
reference count > 0. All this is beyond mere serialization and about 
object persistence. Note that persistent linked structures are not 
stored as blobs but as individual nodes, individually accessible with 
individual reference counts etc. It is complicated and not language 
business to meddle with.

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


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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-23  8:38         ` Dmitry A. Kazakov
@ 2018-02-23 20:28           ` G. B.
  2018-02-23 20:40             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 13+ messages in thread
From: G. B. @ 2018-02-23 20:28 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> On 23/02/2018 08:23, Jacob Sparre Andersen wrote:
>> Shark8 <onewingedshark@gmail.com> writes:
>>> On Thursday, February 22, 2018 at 4:49:04 PM UTC-7, Randy Brukardt wrote:
>> 
>>>> What default (read relatively cheap to read/write) implementation
>>>> could possibly be sane?
>>> 
>>> ASN.1 serialization/deserialization.
>> 
>> That doesn't solve the problem of the compiler having to figure out how
>> to interpret the access types.
> 
> It does not solve any problem, being an utter abomination and horror to 
> anyone who must implement a protocol described in this form.

Serialization isn‘t a protocol, though.




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

* Re: article on acces types and dynamic serialization in Ada (2003)
  2018-02-23 20:28           ` G. B.
@ 2018-02-23 20:40             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2018-02-23 20:40 UTC (permalink / raw)


On 2018-02-23 21:28, G. B. wrote:
> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> On 23/02/2018 08:23, Jacob Sparre Andersen wrote:
>>> Shark8 <onewingedshark@gmail.com> writes:
>>>> On Thursday, February 22, 2018 at 4:49:04 PM UTC-7, Randy Brukardt wrote:
>>>
>>>>> What default (read relatively cheap to read/write) implementation
>>>>> could possibly be sane?
>>>>
>>>> ASN.1 serialization/deserialization.
>>>
>>> That doesn't solve the problem of the compiler having to figure out how
>>> to interpret the access types.
>>
>> It does not solve any problem, being an utter abomination and horror to
>> anyone who must implement a protocol described in this form.
> 
> Serialization isn‘t a protocol, though.

Yes, but ASN.1 is a protocol definition language.

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

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

end of thread, other threads:[~2018-02-23 20:40 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-21 23:57 article on acces types and dynamic serialization in Ada (2003) Mehdi Saada
2018-02-22  9:16 ` Dmitry A. Kazakov
2018-02-22 12:08   ` guyclaude.burger
2018-02-22 12:15 ` Mehdi Saada
2018-02-22 13:04   ` Dmitry A. Kazakov
2018-02-22 23:49   ` Randy Brukardt
2018-02-23  3:40     ` Shark8
2018-02-23  7:23       ` Jacob Sparre Andersen
2018-02-23  8:38         ` Dmitry A. Kazakov
2018-02-23 20:28           ` G. B.
2018-02-23 20:40             ` Dmitry A. Kazakov
2018-02-23 10:30 ` Mehdi Saada
2018-02-23 13:13   ` Dmitry A. Kazakov

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