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 Path: g2news1.google.com!news4.google.com!feeder3.cambriumusenet.nl!feed.tweaknews.nl!87.79.20.105.MISMATCH!news.netcologne.de!ramfeed1.netcologne.de!newsfeed.arcor.de!newsspool2.arcor-online.net!news.arcor.de.POSTED!not-for-mail Date: Wed, 25 Aug 2010 10:06:42 +0200 From: Georg Bauhaus User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.8) Gecko/20100802 Thunderbird/3.1.2 MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: S-expression I/O in Ada References: <547afa6b-731e-475f-a7f2-eaefefb25861@k8g2000prh.googlegroups.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Message-ID: <4c74cf12$0$6892$9b4e6d93@newsspool2.arcor-online.net> Organization: Arcor NNTP-Posting-Date: 25 Aug 2010 10:06:42 CEST NNTP-Posting-Host: 90163476.newsspool2.arcor-online.net X-Trace: DXC=ejVX9O5mUkGODI[;CX`eR`5iL] X-Complaints-To: usenet-abuse@arcor.de Xref: g2news1.google.com comp.lang.ada:13715 Date: 2010-08-25T10:06:42+02:00 List-Id: On 8/24/10 1:41 PM, Natasha Kerensikova wrote: > Using the Append procedure implemented here, I can insert a List as a > node at the end of an existing List, but that makes a deep copy of the > inserted List. So using this interface, if we imagine more and more > complex objects containing less complex object, it means making a simple > list, deep-copying into a large list, itself deep-copied into a larger > list, itself deep-copied into an even larger list, and so-on. While it's > bounded by the application rather than as user input, which is less bad, > it seems sounds horribly inefficient. > > Does anybody have an idea about how to solve this issue? Part of the issue (if it should be one) can be addressed by by looking at S-Expressions as the treesthey are. To store data, keep the List type, but store objects inside a map. Conceptually, _________________________________________ | ... | atom_1 atom_2 � list_1 � atom 3 | | ... | atom_4 � list_2 � ... | such that � list_1 � is really a key, not the list itself. Thus, key_X -> atom_1 atom_2 key_Y atom 3 key_Y -> atom_4 key_Z ... This structure replace pointers and memory management of your original package with the use of a Map in the implementation. (Some) copying is avoided. The programming task will be to hide this structure and continue to expose S-Expression subprograms as in your latest package. If you'd have a package that was build around a list type that uses pointers to connect atom nodes and list nodes, would you provide subprograms that either insert copies of lists or just connect the existing list to the new list? If there was only the latter and no copying, clients would have to be very careful not to touch the data structures, since they are shared between your implementation and the client programs. > Another thing I noticed with this relatively large package is Ada > verbosity. Now I see the difference between using words versus {}. The > problem I see with words for everything is that identifiers don't come > out as well (even with syntax highlighting, differently-colored words > have less contrast than words and punctuation). I hope it's only because > I'm still misusing whitespace. (ASCII symbols work well as long as they aren't overloaded; when you work with a few languages, the sparse symbolism of languages that use punctuation for essential things gets in the way. ASCII punctuation also triggers compiler diagnostics that non-experts in ;,: parsing find startling.) > Last point, I had trouble finding names. [...] > > Does it become easier with practice? Good names really help. My goal is to read a name and then know a fair bit about the named thing. A fair bit is when I don't have to consult lots of comments, or try to remember what this object was about, and why it was here. A few quick remarks: > --------------------- > -- List inspection -- > --------------------- These could be in another package, if all they need in their bodies is the iteration subprograms and Kind. Makes the S_Expression package smaller and separates concerns. > procedure Counts(sexp : in List; Atom_Count, List_Count : out Count_Type); > function Atom_Count(sexp : in List) return Count_Type; > function List_Count(sexp : in List) return Count_Type; > function Node_Count(sexp : in List) return Count_Type; > I'd use a type test here, not 'Tag, function Is_Atom(N : in Node'Class) return Boolean is begin --return Ada.Tags."="(N'Tag, Atom'Tag); return N in Atom; end; and here: > function Is_List(N : in Node'Class) return Boolean is > begin > return Ada.Tags."="(N'Tag, List'Tag); > end; The new DbC-like facilities of Ada use identifier Result when referring to a function result. I'd use Result in place of "ret". > function To_Atom(S : in String) return Atom_Data is > ret : Atom_Data(1 .. S'Length); > begin > String_To_Atom(S, ret); > return ret; > end To_Atom; Just to mention a possibility, a renaming of "ret" might or might not clarify its two roles, being both set in Record_Size, and returned. function Atom_Size(Element : in Cursor) return Natural is size : Natural; procedure Record_Size(Element : in Node'Class) is begin size := Atom(Element).Size; end Record_Size; ret : Natural renames size; begin Lists.Query_Element(Element.Internal, Record_Size'Access); return ret; end Atom_Size; Georg