* Ann: Little tutorial about streams @ 2011-02-28 17:00 mockturtle 2011-02-28 20:32 ` Ludovic Brenta 2011-03-01 3:48 ` Randy Brukardt 0 siblings, 2 replies; 10+ messages in thread From: mockturtle @ 2011-02-28 17:00 UTC (permalink / raw) Dear.all, remembering my initial difficulties with streams (I self-taught Ada, using few tutorials and lots of experiments before landing to the RM), I decided to write a page (my first one, so be patient :-) of the Wikibook with a little stream tutorial http://en.wikibooks.org/w/index.php?title=Ada_Programming/Input_Output/Stream_Tutorial As said in the page, the goal is to give to the reader an intuitive idea about how streams work so, in order to not hide the forest with too many leaves, some of the finest details have been omitted. A subpage of the above page has a fairly complex example that is not complete yet, but I plan to complete it soon. The page is not linked yet with the book body. I was thinking to add a link to it in the "Input Output" page as soon as the subpage with the example is in a good state. Any feedback [especially positive one :-) :-) :-) :-)] is appreciated. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Ann: Little tutorial about streams 2011-02-28 17:00 Ann: Little tutorial about streams mockturtle @ 2011-02-28 20:32 ` Ludovic Brenta 2011-03-01 3:48 ` Randy Brukardt 1 sibling, 0 replies; 10+ messages in thread From: Ludovic Brenta @ 2011-02-28 20:32 UTC (permalink / raw) mockturtle writes: > Dear.all, > remembering my initial difficulties with streams (I self-taught Ada, > using few tutorials and lots of experiments before landing to the RM), > I decided to write a page (my first one, so be patient :-) of the > Wikibook with a little stream tutorial > > http://en.wikibooks.org/w/index.php?title=Ada_Programming/Input_Output/Stream_Tutorial > > As said in the page, the goal is to give to the reader an intuitive > idea about how streams work so, in order to not hide the forest with > too many leaves, some of the finest details have been omitted. A > subpage of the above page has a fairly complex example that is not > complete yet, but I plan to complete it soon. > > The page is not linked yet with the book body. I was thinking to add > a link to it in the "Input Output" page as soon as the subpage with > the example is in a good state. > > Any feedback [especially positive one :-) :-) :-) :-)] is appreciated. Your page is great. How's that for positive criticism :) I've made a couple edits which you are, of course, free to revert. I (think I) have generally improved the style of the prose but not changed the basic structure of the tutorial. Now I have specific suggestions for further improvement: * Between the sections "Abstract streams" and "Serialization functions", it would be nice to have a section on "Predefined concrete streams" discussing, in particular Ada.Text_IO.Text_Stream, so that beginners can start writing to the console using streams. * In the section about Ada.Text_IO.Text_Streams, explain that this is much faster than Ada.Text_IO and why (hint: ARM A.10.4, A.12.2(7)) * Your first example of a serialization function, procedure Example.Print, seems too complicated. But that may be on purpose, so I have not changed it. Here is a simpler implementation: package body Example is procedure Print (Stream : not null access Ada.Streams.Root_Stream_Type'Class; Item : in Int) is -- Convert Item to String (with no trailing space) Value : String := Trim(Int'Image(Item), Left); -- Convert Value'Length to String (with no trailing space) Len : String := Trim(Integer'Image(Value'Length), Left); begin String'Write (Stream, Len & 'i' & Value); end Print; end Example; Thank you for taking the initiative writing this nice tutorial. I think it really helps lower the bar for novices. -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-02-28 17:00 Ann: Little tutorial about streams mockturtle 2011-02-28 20:32 ` Ludovic Brenta @ 2011-03-01 3:48 ` Randy Brukardt 2011-03-01 9:54 ` AdaMagica 2011-03-01 10:16 ` Dmitry A. Kazakov 1 sibling, 2 replies; 10+ messages in thread From: Randy Brukardt @ 2011-03-01 3:48 UTC (permalink / raw) "mockturtle" <framefritti@gmail.com> wrote in message news:f8e7ccbf-a966-4568-9f0d-8e9e38f37dc6@glegroupsg2000goo.googlegroups.com... >Dear.all, >remembering my initial difficulties with streams (I self-taught Ada, using >few tutorials and lots of experiments before >landing to the RM), I decided >to write a page (my first one, so be patient :-) of the Wikibook with a >little stream >tutorial > >http://en.wikibooks.org/w/index.php?title=Ada_Programming/Input_Output/Stream_Tutorial Looks generally good. The little table under "Serialization functions" seems confusing, since it uses "composite" for Input and Output. But of course you can use Read and Write for "composite" types. It seems the intent is to be more informal (since "simple" is used rather than "elementary", which is good as there are no elementary class-wide types); may I suggest that the other entries use "complex" rather than "composite"? (Or some word meaning the same, if the confusion with "complex" numbers is a concern.) In the text under "Write attribute", we have: Clearly, the default implementation, being dependent on the machine and compiler, can be useful only if the data is written and read by programs compiled with the same compiler. If the data, for example, is to be sent across the network and read by a program written in another language, running on an unknown architecture, it is important for the programmer to control the format of the data sent over the wire. Because of this exigence, Ada allows the programmer to override S'Write (and the other stream-related functions described in the following), using an attribute definition clause (RM 13.3): I had to get a dictionary to figure out what the word "exigence" means. Probably best to use a simpler word here; no need to make a tutorial harder to read than needed. I'd probably use "requirement" or "need" instead. (I didn't edit this as I think it is important for the author to consider their intention; I may have missed it altogether.) It might make sense to mention that you can also specify these subprograms with an aspect clause in Ada 2012 (and indeed this will be preferred for most uses to the older attribute definition clause). But perhaps that's out of bounds here. Finally, there might be some value to mentioning the use of Generic_Dispatching_Constructor to build user-defined class-wide Input routines. But maybe that is too advanced of a topic?? Randy. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-03-01 3:48 ` Randy Brukardt @ 2011-03-01 9:54 ` AdaMagica 2011-03-01 10:16 ` Dmitry A. Kazakov 1 sibling, 0 replies; 10+ messages in thread From: AdaMagica @ 2011-03-01 9:54 UTC (permalink / raw) On 1 Mrz., 04:48, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > The little table under "Serialization functions" seems confusing, since it > uses "composite" for Input and Output. But of course you can use Read and > Write for "composite" types. It seems the intent is to be more informal > (since "simple" is used rather than "elementary", which is good as there are > no elementary class-wide types); may I suggest that the other entries use > "complex" rather than "composite"? (Or some word meaning the same, if the > confusion with "complex" numbers is a concern.) I would propose "definite" for "simple" and "indefinite" for "composed". For definite types, the bounds and discriminants are known, so need not be put on the stream (Read/Write). For indefinite types, the bounds and discriminants are needed to construct the object, so they have to be put into the stream (Input/ Output). ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-03-01 3:48 ` Randy Brukardt 2011-03-01 9:54 ` AdaMagica @ 2011-03-01 10:16 ` Dmitry A. Kazakov 2011-03-01 13:56 ` Simon Wright 1 sibling, 1 reply; 10+ messages in thread From: Dmitry A. Kazakov @ 2011-03-01 10:16 UTC (permalink / raw) On Mon, 28 Feb 2011 21:48:19 -0600, Randy Brukardt wrote: > Clearly, the default implementation, being dependent on the machine and > compiler, can be useful only if the data is written and read by programs > compiled with the same compiler. If the data, for example, is to be sent > across the network and read by a program written in another language, > running on an unknown architecture, it is important for the programmer to > control the format of the data sent over the wire. Because of this exigence, > Ada allows the programmer to override S'Write (and the other stream-related > functions described in the following), using an attribute definition clause > (RM 13.3): You can also mention chain code as a technique to implement S'Read/Write in a platform independent way. Of course one problem remains: the type of the stream I/O unit. A good candidate might be Character'Read/Write. That should work in most cases. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-03-01 10:16 ` Dmitry A. Kazakov @ 2011-03-01 13:56 ` Simon Wright 2011-03-01 14:38 ` Dmitry A. Kazakov 0 siblings, 1 reply; 10+ messages in thread From: Simon Wright @ 2011-03-01 13:56 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > You can also mention chain code as a technique to implement > S'Read/Write in a platform independent way. ? Wikipedia says "A chain code is a lossless compression algorithm for monochrome images." ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-03-01 13:56 ` Simon Wright @ 2011-03-01 14:38 ` Dmitry A. Kazakov 2011-03-04 20:58 ` mockturtle 0 siblings, 1 reply; 10+ messages in thread From: Dmitry A. Kazakov @ 2011-03-01 14:38 UTC (permalink / raw) On Tue, 01 Mar 2011 13:56:40 +0000, Simon Wright wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> You can also mention chain code as a technique to implement >> S'Read/Write in a platform independent way. > > ? > > Wikipedia says "A chain code is a lossless compression algorithm for > monochrome images." I guess this is because chain codes were initially deployed for encoding pixels and directions (left, top-left etc) in image processing. But chain code is useful for any encoding of variable-length data without an explicit length count. E.g. UTF-8 is a chain code. Naturals of any length can be portably encoded using chain code like this: 0 = 16#00# 1 = 16#01# 127= 16#7F# 128= 16#80# 16#01# 129= 16#81# 16#01# ... (assuming that octets are atomic). The high order bit when 0 indicates end of the chain. The lower order bits encode the value. Signed integer is encoded as above multiplied by 2 using the lowest bit for the sign. Floating point numbers are encoded as integer fraction (normalized, multiplied by 2**p) followed by the integer normalized exponent - p. p is the required precision. Enumerations are encoded as E'Pos. Strings are as the length and the body. (Nobody uses wide-strings of course (:-)). That basically is. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-03-01 14:38 ` Dmitry A. Kazakov @ 2011-03-04 20:58 ` mockturtle 2011-03-05 1:08 ` Shark8 2011-03-05 1:35 ` Randy Brukardt 0 siblings, 2 replies; 10+ messages in thread From: mockturtle @ 2011-03-04 20:58 UTC (permalink / raw) Dear all, I'm back. First of all, thank you to everyone for your comments. Let me do a cumulative answer. I am afraid that this will make this post a bit long. ---- > ---- on Feb 28 2011 Ludovic Brenta wrote > > Your page is great. How's that for positive criticism :) It is great. :-) > ---- on Feb 28 2011 Ludovic Brenta wrote > > I've made a couple edits which you are, of course, free to revert. I > (think I) have generally improved the style of the prose but not changed > the basic structure of the tutorial. Thank you, I'll check, but I am sure that they are OK. English is not my native language and, although I feel quite confident with it, style improvements are welcome. > ---- on Feb 28 2011 Ludovic Brenta wrote > > Between the sections "Abstract streams" and "Serialization functions", > it would be nice to have a section on "Predefined concrete streams" > discussing, in particular Ada.Text_IO.Text_Stream, so that beginners > can start writing to the console using streams. Thank you for the suggestion. I will add the new section as soon as I can. > ---- on Feb 28 2011 Ludovic Brenta wrote > > Your first example of a serialization function, procedure > Example.Print, seems too complicated. But that may be on purpose, > ... No, it was not on purpose. I reused an old code and I did not notice that I could simplify it. > ---- on Mar 1 2011 Randy Brukardt wrote > > The little table under "Serialization functions" seems confusing, since it > uses "composite" for Input and Output. But of course you can use Read and > Write for "composite" types. > ... > ---- on Mar 1 2011 AdaMagica wrote > > I would propose "definite" for "simple" and "indefinite" for > "composed". To be honest, I do not like that choice of names too. I could not think anything better when I was writing it, so I went for the "least bad" choice, making a mental note to think something better. I'll take your suggestions into account. > ---- on Mar 1 2011 Randy Brukardt wrote > > I had to get a dictionary to figure out what the > word "exigence" means. Probably best to use a simpler > word here; no need to make a tutorial harder to read > than needed. > ... Juk! I could call this a "false false friend"... In Italian "esigenza" is a very common word and this made me to slip to "exigence"... I'll change it. > ---- on Mar 1 2011 Randy Brukardt wrote > > It might make sense to mention that you can also specify these subprograms > with an aspect clause in Ada 2012 I did not know about this. Do you have a reference? > ---- on Mar 1 2011 Dmitry A. Kazakov wrote > > You can also mention chain code as a technique to > implement S'Read/Write in a platform independent way. Thank you for your suggestion. One motivation for chosing the format used in the example was that I wanted to have something that could be printed on screen (also to debug the code before publishing it). ---- Here, I hope I did not forget anyone. Thank you again for your feedback. Riccardo ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-03-04 20:58 ` mockturtle @ 2011-03-05 1:08 ` Shark8 2011-03-05 1:35 ` Randy Brukardt 1 sibling, 0 replies; 10+ messages in thread From: Shark8 @ 2011-03-05 1:08 UTC (permalink / raw) I was debating on whether or not to submit to you a little 'toy' LISP interpreter I've started. I've only got the reading and writing here, no eval or special-forms like 'if', but since they're Stream-based it might be appropriate. --------------------------------- -- Lisp Interpreter in Ada. -- By Joey Fish --------------- -- LISP.ADS -- --------------- With Ada.Containers.Indefinite_Vectors, Ada.Streams; Package LISP is ----------------------------------------------------------------------- -- In LISP a List is defined as either a single element or an -- -- element followed by a lisr; as a consequence of this definition -- -- there is no such thing as an "Empty List." -- ----------------------------------------------------------------------- Type List is Private; -- ToDo: Add primitive functions for list construction/ manipulation. -- ToDo: Add primitive functions for determining if it is an executable list. Private -- Alias Ads.Streams.Root_Stream_Type for ease of use. SubType Stream_Root is Ada.Streams.Root_Stream_Type; -- Element_Type describes the possible types of an Atom -- Note: Empty_Type is the NULL-element. Type Element_Type is ( Empty_Type, Boolean_Type, Integer_Type, Real_Type, String_Type ); -- Type Atom is a record containing the type and value of an element. Type Atom( Element : Element_Type:= Empty_Type ) is record Case Element is When Empty_Type => Null; When Boolean_Type => Boolean_Value : Boolean:= False; When Integer_Type => Integer_Value : Integer:= 0; When Real_Type => Real_Value : Float := 0.0; When String_Type => Is_Name : Boolean:= False; String_Value : Not Null Access String; End Case; end record; Procedure Write_Atom( Stream : Not Null Access Stream_Root'Class; Item : In Atom ); For Atom'Write Use Write_Atom; Type Atom_Array is Array (Positive Range <>) of Atom; Type Elementry_List( Terminal : Boolean:= True ) is record Head : Atom:= ( Element => Empty_Type ); Case Terminal is When False => Tail : Not Null Access Elementry_List; When True => Null; End Case; end record; Procedure Append( Head : In Out Elementry_List; Tail : In Elementry_List ); Function Convert( List : Elementry_List ) Return Atom_Array; Function Convert( List : Atom_Array ) Return Elementry_List; Procedure Write_EList( Stream : Not Null Access Stream_Root'Class; Item : In Elementry_List ); Procedure Read_EList( Stream : Not Null Access Stream_Root'Class; Item : Out Elementry_List ); For Elementry_List'Read Use Read_EList; For Elementry_List'Write Use Write_EList; Type List_Element_Type is ( Atom_Element, EList_Type, Recursive_List ); Type List_Element( Element : List_Element_Type:= Atom_Element ) is record Case Element is When Atom_Element => Atom_Data : Atom; When EList_Type => EList_Data : Elementry_List; When Recursive_List => RList_Data : Not Null Access List; end case; end record; Function As_List( Input : in List_Element ) Return List; Package Elements is New Ada.Containers.Indefinite_Vectors ( Index_Type => Positive, Element_Type => List_Element ); Type List is Tagged record Data : Elements.Vector:= Elements.Empty_Vector; end record; Procedure Write_List( Stream : Not Null Access Stream_Root'Class; Item : In List ); Procedure Read_List( Stream : Not Null Access Stream_Root'Class; Item : Out List ); For List'Read Use Read_List; For List'Write Use Write_List; End LISP; --------------- -- LISP.ADB -- --------------- With Ada.Strings.Fixed; Package Body LISP is FALSE_Text : Constant String:= Boolean'Image( False ); TRUE_Text : Constant String:= Boolean'Image( True ); NULL_Text : Constant String:= "NULL"; Function Trim_Image( Input : In Float ) Return String is Use Ada.Strings, Ada.Strings.Fixed; Begin Return Result: String:= Trim( Side => Left, Source => Float'Image( Input ) ); End Trim_Image; ------------------ -- WRITE_ATOM -- ------------------ Procedure Write_Atom( Stream : Not Null Access Stream_Root'Class; Item : In Atom ) is Text : Access String; begin Case Item.Element is When Empty_Type => Text:= New String'( NULL_Text ); When Boolean_Type => Text:= New String'( Boolean'Image(Item.Boolean_Value) ); When Integer_Type => Text:= New String'( Integer'Image(Item.Integer_Value) ); When Real_Type => Text:= New String'( Float'Image( Item.Real_Value ) ); When String_Type => If Not Item.Is_Name then Text:= New String'( '"' & Item.String_Value.All & '"' ); else Text:= New String'( Item.String_Value.All ); end if; End Case; String'Write( Stream, Text.All ); end Write_Atom; -------------- -- Append -- -------------- Procedure Append( Head : In Out Elementry_List; Tail : In Elementry_List ) is begin If Head.Terminal then Declare Result : Elementry_List:= Elementry_List'( Terminal => False, Head => Head.Head, Tail => New Elementry_List'(Tail) ); For Result'Address Use Head'Address; Begin -- Here the initialization of Result changes the value Null; -- of Head because they are overlaid; further, we are End; -- guarenteed that the sizes are both the same because else -- Elementry_List is a simple varient record and cannot Declare -- be extended because it is not a tagged-type. This : Access Elementry_List:= Head.Tail; Begin While Not This.Terminal loop -- If Head is not terminal then This:= This.Tail; -- we must traverse the list end loop; -- until the end to append Tail. Append( This.All, Tail ); End; end if; end Append; Function Convert( List : Elementry_List ) Return Atom_Array is Function Get_Element( Item : Elementry_List ) Return Atom_Array is begin if Item.Terminal then Return Result : Atom_Array:= ( 1 => Item.Head ); else Return Result : Atom_Array:= Atom_Array'( 1 => Item.Head ) & Get_Element( Item.Tail.All ); end if; end Get_Element; begin Return Get_Element( List ); end Convert; Function Create( Input : Atom ) Return Elementry_List is begin Return Result: Elementry_List:= ( Terminal => True, Head => Input ); end; Function Convert( List : Atom_Array ) Return Elementry_List is begin if List'Length = 0 then Raise Program_Error; end if; Declare Working : Elementry_List:= Create( Input => List(List'First) ); Begin For Index in Positive'Succ(List'First)..List'Last loop Append( Head => Working, Tail => Create( List(Index) ) ); end loop; Return Working; End; end Convert; --------------------------------------------------- -- Elementry_List's 'Read & 'Write Attributes -- --------------------------------------------------- Procedure Write_EList( Stream : Not Null Access Stream_Root'Class; Item : In Elementry_List ) is begin Character'Write( Stream, '(' ); -- When saving to a Stream every Declare -- elementry-list begins with an This : Elementry_List:= Item; -- opening parenthisis, followed Begin -- by list of Atoms (whitespace List: -- separated), terminated by a loop -- closing parenthisis. Atom'Write( Stream, This.Head ); Exit List When This.Terminal; This:= This.Tail.All; Character'Write( Stream, ',' ); end loop List; Character'Write( Stream, ')' ); End; end Write_EList; Procedure Read_EList( Stream : Not Null Access Stream_Root'Class; Item : Out Elementry_List ) is Function Parse_Atom( S : String ) Return Atom is Function Get_Type_Indicator(Input : String) Return Element_Type is SubType Digit is Character Range '0'..'9'; begin Case Input(Input'First) is -- A floating-point numeric is When Digit => -- distinguished from an integer For Index in Input'Range loop -- by the decimal point or the Case Input(Index) is -- exponent notation. When 'e' | 'E' | '.' => Return Real_Type; When Others => null; End case; end loop; Return Integer_Type; When Others => if Input = NULL_Text then -- NULL, TRUE, & FALSE are texts Return Empty_Type; -- which are not String_Type. elsif Input = TRUE_Text or Input = FALSE_Text then Return Boolean_Type; else -- Everything else, however, is Return String_Type; -- either a String_Type or a end if; -- name. Strings start w/ '"'. end case; end Get_Type_Indicator; Use Ada.Strings, Ada.Strings.Fixed; -- Parse_Atom Input : String:= Ada.Strings.Fixed.Trim( S, Both ); -- starts here. begin Return Result : Atom(Get_Type_Indicator(Input)) do Case Result.Element is When Empty_Type => Null; When String_Type => Result.Is_Name:= Input(Input'First) = '"'; if Not Result.Is_Name then Result.String_Value:= New String'( Input(Positive'Succ(Input'First)..Positive'Pred(Input'Last)) ); else Result.String_Value:= New String'(Input); end if; When Integer_Type => Result.Integer_Value:= Integer'Value(Input); When Real_Type => Result.Real_Value:= Float'Value(Input); When Boolean_Type => Result.Boolean_Value:= Input = TRUE_Text; End case; End Return; end Parse_Atom; WhiteSpace : Constant Array(Character) Of Boolean:= ( ASCII.VT | ASCII.HT | ASCII.LF | ASCII.CR | ' ' => True, Others => False ); Type Index_Vector is Array (Positive Range <>) of Positive; Seperators : Not Null Access Index_Vector:= New Index_Vector'( 2..1 => 1 ); Working : Not Null Access String:= New String'( "" ); C : Character; Result : Elementry_List; In_String : Boolean:= False; Is_Terminated : Boolean:= False; begin Loop Character'Read( Stream, C ); Case C is When '"' => In_String:= Not In_String; Is_Terminated:= False; When ')' => Exit When Not In_String; When Others => If WhiteSpace(C) then if Is_Terminated then GoTo Bypass; else Is_Terminated:= True; end if; else Is_Terminated:= False; end if; End Case; Working:= New String'( Working.All & C ); -- We update "working." if WhiteSpace(C) then -- and delimit with whitespace. Seperators:= New Index_Vector'( Seperators.All & Working'Last ); end if; <<Bypass>> Null; End Loop; -- We simulate a terminating space by appending one more -- than the last index to Seperators. Seperators:= New Index_Vector'(Seperators.All & (Working'Last+1)); Declare -- We use one more than Working'First to ignore the '(' that starts -- this list, just like we terminated the string just before -- copying the trailing ')' into Working. Start : Positive:= Working'First+1; Stop : Positive; Begin for Index in Seperators'Range loop -- Here is where we create an Stop:= Seperators( Index )-1; -- atom from every interval we Append(Result, -- recorded in "seperators". (Terminal => True, Head => Parse_Atom(Working(Start..Stop))) ); Start:= Seperators( Index )+1; end loop; End; -- And we return everything we Item:= Result.Tail.All; -- previously appended to result. end Read_EList; --------------- -- As_List -- --------------- Function As_List( Input : in List_Element ) Return List is Begin Return Result : List do Case Input.Element is When Atom_Element => Result.Data.Append( New_Item => Input ); When Recursive_List => Result:= Input.RList_Data.All; When EList_Type => Declare Data : Elementry_List:= Input.EList_Data; Begin loop Result.Data.Append( New_Item => (Atom_Element, Data.Head) ); Exit When Data.Terminal; Data:= Data.Tail.All; end loop; End; End Case; End Return; End As_List; Procedure Write_List( Stream : Not Null Access Stream_Root'Class; Item : In List ) is SubType ELIST is Elementry_List; begin Character'Write( Stream, '(' ); Declare Procedure Process_Data( Position : Elements.Cursor ) is Item : List_Element Renames Elements.Element( Position ); begin Case Item.Element is When Atom_Element => Atom'Write( Stream, Item.Atom_Data ); When EList_Type => ELIST'Write(Stream, Item.EList_Data); When Recursive_List => List'Write( Stream, Item.RList_Data.All ); end case; end Process_Data; Begin Item.Data.Iterate( Process_Data'Access ); End; Character'Write( Stream, ')' ); end Write_List; Procedure Read_List( Stream : Not Null Access Stream_Root'Class; Item : Out List ) is begin null; end Read_List; End LISP; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Little tutorial about streams 2011-03-04 20:58 ` mockturtle 2011-03-05 1:08 ` Shark8 @ 2011-03-05 1:35 ` Randy Brukardt 1 sibling, 0 replies; 10+ messages in thread From: Randy Brukardt @ 2011-03-05 1:35 UTC (permalink / raw) "mockturtle" <framefritti@gmail.com> wrote in message news:fba7e41d-288d-419a-ae55-86c2fd954903@glegroupsg2000goo.googlegroups.com... > Dear all, > I'm back. First of all, thank you to everyone for your comments. Let me > do a cumulative answer. I am afraid that this will make this post a bit > long. ... >> ---- on Mar 1 2011 Randy Brukardt wrote >> >> It might make sense to mention that you can also specify these >> subprograms >> with an aspect clause in Ada 2012 > > I did not know about this. Do you have a reference? The draft standard and Rationale are the best references. But the rationale isn't close to done at this point (I've only seen a draft of Chapter 1 to date) and isn't public anyway. The current draft of the standard gives the syntax (see http://www.ada-auth.org/standards/ada12.html for the whole draft; specifically see http://www.ada-auth.org/standards/12rm/html/RM-13-3-1.html for the aspect syntax). The next draft will have essentially all of the details (probably available in April). Anyway, the basic idea is that aspect clauses can be given as part of declarations. The "definition" is not resolved or evaluated until the entity declared by the declaration is frozen (formally until the end of the enclosing declaration list), so these are automatically "forward" references. For instance, you could have: type A_Type is .... with Read => My_Read, Write => My_Write; procedure My_Read (Stream : not null access Ada.Streams.Root_Stream_Type'Class; Item : out A_Type); procedure My_Write (Stream : not null access Ada.Streams.Root_Stream_Type'Class; Item : in A_Type); This notation is most valuable for subprograms (since it sidesteps the problems of overloading that cause problems for pragmas and attribute definition clauses), but it is general and works on almost any declaration. (There are a few obscure things that are technically declarations -- like goto labels -- that don't allow aspect clauses.) Just one of the good things coming in Ada 2012. Randy. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-03-05 1:35 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-02-28 17:00 Ann: Little tutorial about streams mockturtle 2011-02-28 20:32 ` Ludovic Brenta 2011-03-01 3:48 ` Randy Brukardt 2011-03-01 9:54 ` AdaMagica 2011-03-01 10:16 ` Dmitry A. Kazakov 2011-03-01 13:56 ` Simon Wright 2011-03-01 14:38 ` Dmitry A. Kazakov 2011-03-04 20:58 ` mockturtle 2011-03-05 1:08 ` Shark8 2011-03-05 1:35 ` Randy Brukardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox