From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,24d7acf9b853aac8 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!postnews.google.com!i31g2000yqm.googlegroups.com!not-for-mail From: Natacha Kerensikova Newsgroups: comp.lang.ada Subject: Re: S-expression I/O in Ada Date: Thu, 12 Aug 2010 02:26:20 -0700 (PDT) Organization: http://groups.google.com Message-ID: <318d4041-eb01-4419-ae68-e6f3436c5b66@i31g2000yqm.googlegroups.com> References: <547afa6b-731e-475f-a7f2-eaefefb25861@k8g2000prh.googlegroups.com> <87aap6wcdx.fsf@ludovic-brenta.org> <87vd7jliyi.fsf@ludovic-brenta.org> <699464f5-7f04-4ced-bc09-6ffc42c5322a@w30g2000yqw.googlegroups.com> <87ocdbl41u.fsf@ludovic-brenta.org> NNTP-Posting-Host: 178.83.214.115 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1281605180 15152 127.0.0.1 (12 Aug 2010 09:26:20 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 12 Aug 2010 09:26:20 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: i31g2000yqm.googlegroups.com; posting-host=178.83.214.115; posting-account=aMKgaAoAAAAoW4eaAiNFNP4PjiOifrN6 User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.2.3) Gecko/20100524 Firefox/3.6.3,gzip(gfe) Xref: g2news1.google.com comp.lang.ada:13165 Date: 2010-08-12T02:26:20-07:00 List-Id: On Aug 10, 8:13=A0pm, Jeffrey Carter wrote: > On 08/09/2010 11:47 PM, Natacha Kerensikova wrote: > I was commenting on your ideas about writing an S-expression to a stream,= which > included operations to open and close a list, and put an atom. I thought = this > was how you expected a client to output an S-expression. You thought right, except that due to my discussion with Dmitry I ended up considering the possibility of splitting my first idea into two different packages. Sexp_Stream is supposed to perform S-expression I/O over streams, without ever constructing a S-expression into memory. It is supposed to do only the encoding and decoding of S-expression format, to expose its clients only atoms and relations. A further unnamed yet package would handle the memory representation of S-expressions, which involve object creation, memory management and things like that. It would be a client of Sexp_Stream for I/O, so the parsing would only be done at one place (namely Sexp_Stream). As I said Ludovic Brenta's code might take this place. There are situations when a memory representation of S-expressions is not needed, and the tcp-connect example here seems to be such a case. That's why I imagined TCP_Info as a client of Sexp_Stream instead of a client of the second package. The stuff with operations to put an atom and open and close a list is indeed how I think a client of Sexp_Stream should behave. And if I want Sexp_Stream to have no in-memory representation of a S- expression, I can't imagine another way of specifying it. However I'm still undecided whether it's a good thing to have a Sexp_Stream without memory representation, and whether packages like TCP_Info should be a client of Sexp_Strean or of the in-memory S- expression package. > I think the client should just do > > S : S_Expression :=3D Some_Initialization; > > Put (File =3D> F, Expression =3D> S); To achieve such an interface, the client has to build an in-memory S- expression object. In the tcp-connect example, there are eight nodes (five atoms and three lists). They have to be somehow built, and it doesn't look like a simple initialization. The second interface I proposed, with a lot of nested calls, builds the S-expression object with functions looking like: function NewList(Contents, Next: S_node_access) return S_node_access; function AtomFromWhatever(Contents: whatever, Next: S_node_access) return S_node_access; However, unless I'm building other higher-level functions, to build 8 nodes I need 8 function calls, exactly like the second example. That 8-function-call example looks very C-ish to me, and honestly I don't like it, I prefer the sequence of procedure calls from Sexp_Stream example, but that's just a personal taste. The problem is that I don't see how to do it otherwise. Any idea would be welcome. For the TCP_info stuff particular case, the only simplification I can imagine is leveraging the fact that only 2 among the 8 nodes change. So one could construct a global S-expression skeleton with the 6 constant nodes, and when actually writing data append to the "host" and "port" atoms the relevant variable atoms. However that means having a read/write global variable, which is bad for tasking, so one might prefer a constant 6-node skeleton, duplicated in the declarative part of the writing procedure, and then appending the variable nodes. However that appending would probably end up with lines like: root_sexp.FirstChild.Next.FirstChild.Append(host_node); root_Sexp.FirstChild.Next.Next.FirstChild.Append(port_node); which looks very ugly to me. > Your TCP_Info-handling pkg would convert the record into an S-expression,= and > call a single operation from your S-expression pkg to output the S-expres= sion. That's the tricky part. At least so tricky that I can't imagine how to do it properly. > Your S-expression library would implement the writing of the expression a= s a > series of steps. Indeed, as a series of calls similar to my Sexp_Stream example. I'm glad to have at least that part right. Thanks for your comments, Natacha