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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham 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-7-bit Path: g2news1.google.com!news4.google.com!feeder.news-service.com!weretis.net!feeder4.news.weretis.net!news.tornevall.net!.POSTED!not-for-mail From: "Jeffrey R. Carter" Newsgroups: comp.lang.ada Subject: Re: S-expression I/O in Ada Date: Fri, 13 Aug 2010 15:53:31 -0700 Organization: TornevallNET - http://news.tornevall.net Message-ID: 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> <318d4041-eb01-4419-ae68-e6f3436c5b66@i31g2000yqm.googlegroups.com> <383ec00d-1f62-4d2f-b501-cedaeaa4b3c4@t2g2000yqe.googlegroups.com> NNTP-Posting-Host: 78d20b5526a657061a247a0a97f23ea8 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: 6cb873a13d2f227ffac0b1c0f2649460 X-Complaints-To: abuse@tornevall.net User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.11) Gecko/20100713 Thunderbird/3.0.6 X-Complaints-Language: Spoken language is english or swedish - NOT ITALIAN, FRENCH, GERMAN OR ANY OTHER LANGUAGE! In-Reply-To: <383ec00d-1f62-4d2f-b501-cedaeaa4b3c4@t2g2000yqe.googlegroups.com> X-UserIDNumber: 1738 X-Validate-Post: http://news.tornevall.net/validate.php?trace=6cb873a13d2f227ffac0b1c0f2649460 X-Complaints-Italiano: Non abbiamo padronanza della lingua italiana - se mandate una email scrivete solo in Inglese, grazie X-Posting-User: 0243687135df8c4b260dd4a9a93c79bd Xref: g2news1.google.com comp.lang.ada:13254 Date: 2010-08-13T15:53:31-07:00 List-Id: On 08/13/2010 02:32 AM, Natacha Kerensikova wrote: > > When I wrote this I couldn't think of any way to write clearer or > simpler code with any of the two proposed packages (stream or memory > based), because of the basic argument that 8 nodes have to be somehow > created anyway and couldn't think of any way of doing that except by > creating them one by one (be it with a sequence of procedure calls or > a bunch of nested function calls). So when complexity and readability > are equal, I go for the least amount of dependencies. > > Of course finding a way to make S-expression building much clearer > with a given interface would be a huge argument in favor of the > interface, no matter its level. > > Unless I missed something important, it looks like it only moves the > problem around. While a To_S_Expression function does make a > TCP_Info'Write simple and one-operation and all, complexity is only > transferred to To_S_Expression which will still have to do the dirty > job of creating 8 nodes. Sure, but it will be hidden and reused, rather than appearing frequently. Let's see if I can make what I'm talking about clear. We want to build an application that does something. It will need to manipulate widgets to do so, so we package the widget manipulation: with Ada.Text_IO; package Widgets is type Widget is ...; procedure Put (File : in Ada.Text_IO.File_Type; Item : in Widget); function Get (File : in Ada.Text_IO.File_Type) return Widget; end Widgets; Now we can go off and work on the rest of the application. Eventually we'll need to implement the body of Widgets. We decide that we want use S-expressions for the external storage syntax, so we'll need (or already have) a low-level S-expression pkg: with Ada.Text_IO; package Sexps is type Atom is private; -- Operations to convert things to/from Atoms. type Sexp is private; -- An Atom or a list of Sexp. function To_Sexp (From : in Atom); function Empty_List return Sexp; Not_A_List : exception; function Append (To : in Sexp; Item : in Sexp) return Sexp; -- Appends Item to the list To. Raises Not_A_List is To is not a list. procedure Put (File : in Ada.Text_IO.File_Type; Item : in Sexp); function Get (File : in Ada.Text_IO.File_Type) return Sexp; -- Operations to extract information from a Sexp. -- Other declarations as needed. end Sexps; I've only listed the operations to construct a Sexp and for I/O. This is low-level and somewhat messy to use, but would never be accessed directly from the code that implements the functionality of the application. Now we can implement the body of Widgets: with Sexps; package body Widgets is function To_Sexp (From : in Widget) return Sexps.Sexp is separate; function To_Widget (From : in Sexps.Sexp) return Widget is separate; -- These are left as an exercise for the reader :) procedure Put (File : in Ada.Text_IO.File_Type; Item : in Widget) is -- null; begin -- Put Sexps.Put (File => File, Item => To_Sexp (Item) ); end Put; function Get (File : in Ada.Text_IO.File_Type) return Widget is -- null; begin -- Get return To_Widget (Sexps.Get (File) ); end Get; end Widgets; The body of Sexps will be messy, but it will be written once and mostly ignored from then on. The bodies of To_Sexp and To_Widget will be sort of messy, but will be written once (for each type of interest) and mostly ignored from then on. The code that implements the functionality of the application will be clear. > Yes, I have not managed yet to get that habit. I try to use a > Underscore_And_Capitalization style (not sure whether it's the usual > Ada idiom or not), but sometimes in the heat of action I forgot to do > it (funny thing that identifier that slip end up to be camel cased, > while my C habit is underscore and lower case). Initial_Caps is the Ada convention. Your C convention would be better than CamelCase. > >>>> 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-expression. > > What I found tricky is the "single operation" part. Building 8 nodes > in a single operation does look very difficult, and while Ludovic's > trick of building them from an encoded string is nice, it makes we > wonder (again) about the point of building a S-expression object > before writing it while it's simpler and clearer to write strings > containing hand-encoded S-expressions. "Single operation" referred to output of an S-expression. If you can write this a sequence of low-level steps, then you can put those steps in a higher-level procedure which becomes a single operation to output an S-expression. Converting something into an S-expression is similar. Leaving aside considerations of limitedness, anything you can build up in a series of steps in Ada can be wrapped in a function that returns the thing after it has been built; this function is then a single operation. Using the Sexps pkg I sketched earlier, one can build an arbitrary S-expression in a single statement with lots of calls to Empty_List, To_Atom, and Append. But one could also build it up in steps using intermediaries. Either way would serve as an implementation of Widgets.To_Sexp; To_Sexp is a single operation to convert a Widget to an S-expression. HTH. -- Jeff Carter "Have you gone berserk? Can't you see that that man is a ni?" Blazing Saddles 38