* Adding "()" operator to Ada 200X @ 2003-06-02 16:35 Frank J. Lhota 2003-06-02 23:42 ` Matthew Heaney 2003-06-03 2:56 ` Fionn mac Cuimhaill 0 siblings, 2 replies; 21+ messages in thread From: Frank J. Lhota @ 2003-06-02 16:35 UTC (permalink / raw) There appears to be wide agreement that Ada 200X should include some sort of standard container library like Charles and PragMark. This library will probably include generic packages for creating and operating with dynamic lists and maps. One can view these kinds of collections as generalized arrays, and as such, it would be nice to use array notation for accessing a member of one of these collections. In other words, one should be able to define the "()" operator for array-like types, as follows: function "()" ( Source : in Array_Like_Type; Index : in Index_Type ) return Component_Type; For example, if the object Roster is a list of objects of type Player_Type, it would be quite desirable to be able to access the second player in Roster as Roster(2) For that matter, we could use the "()" operator to improve some existing Ada packages. The Ada.Strings.Bounded and Ada.Strings.Unbounded packages define the types Bounded_String and Unbounded_String that are enhanced versions of the String type. If Item is of type Bounded_String / Unbounded_String, we now access the third character of Item using the expression Element( Item, 3 ) Again, why not use the same notation that we would use if Item were declared as Standard.String (assuming that Item'First = 1 ), i.e. Item(3) If Ada 200X had an "()" operator, we could add the following declaration to Ada.Strings.Unbounded function "()" (Source : in Unbounded_String; Index : in Positive) return Character renames Element; With this declaration, we could use either "Element( Item, 3 )" or "Item(3)" to get the third element of Item. Of course, an array component can also be assigned a value, as in Item(3) := 'A': For that reason, we may also want to add an "():=" operator that is used to update a component of an array-like object, e.g. procedure "():=" ( Source : in out Array_Like_Type; Index : in Index_Type; Value : in Component_Type ); Again, we could enhance packages such as Ada.Strings.Bounded and Ada.Strings.Unbounded by declaring a "():=" operator that could be used in place of the Replace_Element procedures. I cannot help but think that this would be of tremendous help with whatever standard container library is added to Ada 200X. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-02 16:35 Adding "()" operator to Ada 200X Frank J. Lhota @ 2003-06-02 23:42 ` Matthew Heaney 2003-06-03 14:59 ` Frank J. Lhota 2003-06-03 19:52 ` Francisco Javier Loma Daza 2003-06-03 2:56 ` Fionn mac Cuimhaill 1 sibling, 2 replies; 21+ messages in thread From: Matthew Heaney @ 2003-06-02 23:42 UTC (permalink / raw) "Frank J. Lhota" <NOSPAM.lhota.adarose@verizon.net> wrote in message news:<V0LCa.32473$ca5.11277@nwrdny02.gnilink.net>... > There appears to be wide agreement that Ada 200X should include some sort of > standard container library like Charles and PragMark. This library will > probably include generic packages for creating and operating with dynamic > lists and maps. One can view these kinds of collections as generalized > arrays, and as such, it would be nice to use array notation for accessing a > member of one of these collections. > [snip] > I cannot help but think that this would be of tremendous help with whatever > standard container library is added to Ada 200X. But all you've done is change the syntax. None of your suggestions allow you to do more than is already provided by the library. To get a constant view of an element object, then all you have to do is: procedure Op (I : Iterator_Type) is E : ET := Element (I); begin To get an element object reference, you have to use an intermediate access type. To query do this: procedure Op (I : Iterator_Type) is X : ET := To_Access (I).all; begin To modify do this: procedure Op (I : Iterator_Type) is begin To_Access (I).all := Y; If you prefer, you can rename the element object. procedure Op (I : Iterator_Type) is E : ET renames To_Access (I).all; begin X := E; --query E := Y; --modify end; Alternatively, if you don't want to mess around with access types, then you can use Replace_Element instead: Replace_Element (I, E); If this is a set or a map, you can always unconditionally modify an element using Insert: Insert (Set, E); --sort of like Set (Get_Key (E)) := E; Insert (Map, Key, E); --sort of like Map (Key) := E; If you're going to make a change in the syntax of the language, then it has be because it allows you to do something you can't do already. For example, there's no way to declare an access subtype right now that means "all the access values except null." A useful language change would be to allow the declaration: type Element_Access_Base is access all Element_Type; subtype Element_Access is Element_Access_Base range not null; ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-02 23:42 ` Matthew Heaney @ 2003-06-03 14:59 ` Frank J. Lhota 2003-06-03 15:09 ` Frank J. Lhota ` (2 more replies) 2003-06-03 19:52 ` Francisco Javier Loma Daza 1 sibling, 3 replies; 21+ messages in thread From: Frank J. Lhota @ 2003-06-03 14:59 UTC (permalink / raw) "Matthew Heaney" <mheaney@on2.com> wrote in message news:1ec946d1.0306021542.58714996@posting.google.com... > But all you've done is change the syntax. None of your suggestions > allow you to do more than is already provided by the library. But isn't the same thing true of all operators? Instead of defining "+" for my types, I could define a function named Sum. It would have the same functionality as the "+", it would just read differently. OTOH, how an expression reads is very important! One of Ada's strengths is its readability, and I would consider D := B * B - 4 * A * C; to be more readable than D := Difference( Product( B, B ), Product( Product( 4, A ), C ) ); Part of why the former expression is clearer is that it uses the standard arithmetic notation that one uses for numeric types. Thus, even if A, B, C and D are not a numberic type (they could be matrices, for example), we understand the author's intentions here. From the very beginning, Ada has allowed programmers to define operators such as "+", "*", "and", etc. for user defined types, so that the user types can use the same notation as the predefined types. By analogy, why not do the same for a user type that is analgous to an array? Isn't B( I ) := A( P( I ) ) + C( I ); clearer than Replace_Element( B, I, Element( A, Element( P, I ) ) + Element( C, I ) ); > If you're going to make a change in the syntax of the language, then > it has be because it allows you to do something you can't do already. > For example, there's no way to declare an access subtype right now > that means "all the access values except null." A useful language > change would be to allow the declaration: > > type Element_Access_Base is access all Element_Type; > > subtype Element_Access is Element_Access_Base range not null; This is an interesting idea, and we should probably pursue it further in another. Constraint checking has always been tremendously helpful. There is one potential (but not insurmountable) problem with this proposal: in the absence of explicit initializations, an access variable is initialized to null. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-03 14:59 ` Frank J. Lhota @ 2003-06-03 15:09 ` Frank J. Lhota 2003-06-03 16:04 ` Martin Krischik 2003-06-03 20:24 ` Randy Brukardt 2 siblings, 0 replies; 21+ messages in thread From: Frank J. Lhota @ 2003-06-03 15:09 UTC (permalink / raw) "Frank J. Lhota" <NOSPAM.lhota.adarose@verizon.net> wrote in message news:AJ2Da.34247$ca5.13684@nwrdny02.gnilink.net... > This is an interesting idea, and we should probably pursue it further in > another. Constraint ... Whoops! I meant to say "... and we should probably pursue it further in another thread". ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-03 14:59 ` Frank J. Lhota 2003-06-03 15:09 ` Frank J. Lhota @ 2003-06-03 16:04 ` Martin Krischik 2003-06-04 17:28 ` Matthew Heaney 2003-06-03 20:24 ` Randy Brukardt 2 siblings, 1 reply; 21+ messages in thread From: Martin Krischik @ 2003-06-03 16:04 UTC (permalink / raw) Frank J. Lhota wrote: > But isn't the same thing true of all operators? Instead of defining "+" > for my types, I could define a function named Sum. It would have the same > functionality as the "+", it would just read differently. I agree with your point and put my vote in favour of the O.P.: An array operator would make collection classes much nicer. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-03 16:04 ` Martin Krischik @ 2003-06-04 17:28 ` Matthew Heaney 2003-06-04 18:21 ` Frank J. Lhota 0 siblings, 1 reply; 21+ messages in thread From: Matthew Heaney @ 2003-06-04 17:28 UTC (permalink / raw) Martin Krischik <krischik@users.sourceforge.net> wrote in message news:<1325634.ddflWlv0t0@linux1.krischik.com>... > > I agree with your point and put my vote in favour of the O.P.: An array > operator would make collection classes much nicer. The problem is what type to return. In C++ I do this: T& operator[](); const T& operator[]() const; The operator returns a reference to T. There are no reference types in Ada, so it's not obvious how the language would be able to provide it. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-04 17:28 ` Matthew Heaney @ 2003-06-04 18:21 ` Frank J. Lhota 2003-06-05 1:15 ` Robert I. Eachus 0 siblings, 1 reply; 21+ messages in thread From: Frank J. Lhota @ 2003-06-04 18:21 UTC (permalink / raw) "Matthew Heaney" <mheaney@on2.com> wrote in message news:1ec946d1.0306040928.6eb47667@posting.google.com... > The problem is what type to return. In C++ I do this: > > T& operator[](); > const T& operator[]() const; > > The operator returns a reference to T. There are no reference types > in Ada, so it's not obvious how the language would be able to provide > it. I debated whether the right solution was to introduce some notion of reference types to Ada, so that the "()" functions would be declared something like this: function "()" ( Source : in Array_Like_Type; Index : in Index_Type ) return access Component_Type; This would parallel the C++ approach, and has worked very well in that realm. It occurred to me, however, that the reference type approach is assumes that in an object of a array-like type, each component is represented as an aliased section of memory of type Component_Type. One can easily think of many situations where this would not be the case: - the components might be stored in the array-like object in a packed format, so that they cannot be aliased; - the array-like object may be implemented using a file or database, so that the components are not in memory; - the components may be stored in some alternate representation; The reference type approach breaks down in these cases. As an alternative, I proposed separate "()" and "():=" for retrieving and assigning components in an array-like object. -- Function used to evaluate Source( Index ) function "()" ( Source : in Array_Like_Type; Index : in Index_Type ) return Component_Type; -- Procedure for assigning Value to Source( Index ) procedure "():=" ( Source : in out Array_Like_Type; Index : in Index_Type; Value : in Component_Type ); This approach makes very minimal assumptions about our array-like types: that we can retrieve a component from such an object given an index value, and that we can assign a component value at a given index. These assumptions would hold for virtually any type for which one would care to use the array notation. Moreover, the "()" and "():=" proposal does not require adding reference types to Ada. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-04 18:21 ` Frank J. Lhota @ 2003-06-05 1:15 ` Robert I. Eachus 2003-06-05 14:59 ` Frank J. Lhota 2003-06-05 17:25 ` Matthew Heaney 0 siblings, 2 replies; 21+ messages in thread From: Robert I. Eachus @ 2003-06-05 1:15 UTC (permalink / raw) Frank J. Lhota wrote: > The reference type approach breaks down in these cases. As an alternative, I > proposed separate "()" and "():=" for retrieving and assigning components in > an array-like object. > > -- Function used to evaluate Source( Index ) > function "()" ( Source : in Array_Like_Type; > Index : in Index_Type ) > return Component_Type; > > -- Procedure for assigning Value to Source( Index ) > procedure "():=" ( Source : in out Array_Like_Type; > Index : in Index_Type; > Value : in Component_Type ); > > This approach makes very minimal assumptions about our array-like types: > that we can retrieve a component from such an object given an index value, > and that we can assign a component value at a given index. These assumptions > would hold for virtually any type for which one would care to use the array > notation. Moreover, the "()" and "():=" proposal does not require adding > reference types to Ada. I like the idea, but there are some practical problems. First, a property of arrays in Ada, is that several attributes are currently predefined. For Foo(Foo'First) to work correctly, you need user defined attributes. Fortunately, the syntax is already "in there," but the attributes that can be defined would have to be extended, and there would probably be a rule required that when you defined an "()" function, the 'First, 'Last, 'Length, and 'Range attributes would become abstract and need to be overridden befor you could use the type. Also, I think that procedure "()" makes more sense, but that is just nomenclature. What is not nomenclature is that Ada already allows functions as prefixes on the left-hand side of assignment statements! (The function has to return an access type, but from there on everything works like you would expect.) So I recommend instead: -- Function used to evaluate Source( Index ) function "()" ( Source : in Array_Like_Type; Index : in Index_Type ) return Component_Type; for Source'First use My_First; for Source'Last use My_Last; -- I think that allowing a definition of 'Range other than -- Source'First..Source'Last would require too much invention. -- Given that, Source'Length can be defined as -- Index_Type'Pos(Source'Last) - Index_Type'Pos(Source'First) + 1. -- function for assigning Value to Source( Index ) function "()" ( Source : in out Array_Like_Type; Index : in Index_Type) return Component_Type'Access; Yes, that does though have the effect that for some types with packed representations you are not going to be able to define the second operation, so you must still use a procedure call to do the modification. But it should work fine for sparse array implementations. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-05 1:15 ` Robert I. Eachus @ 2003-06-05 14:59 ` Frank J. Lhota 2003-06-05 17:25 ` Matthew Heaney 1 sibling, 0 replies; 21+ messages in thread From: Frank J. Lhota @ 2003-06-05 14:59 UTC (permalink / raw) "Robert I. Eachus" <rieachus@attbi.com> wrote in message news:3EDE998D.3060701@attbi.com... > I like the idea, but there are some practical problems. First, a > property of arrays in Ada, is that several attributes are currently > predefined. For Foo(Foo'First) to work correctly, you need user defined > attributes. Fortunately, the syntax is already "in there," but the > attributes that can be defined would have to be extended, and there > would probably be a rule required that when you defined an "()" > function, the 'First, 'Last, 'Length, and 'Range attributes would become > abstract and need to be overridden befor you could use the type. In other words, why not allow the programmer to specify, in a standard fashion, an iteration sheme (similar to the C++ iterators) for visiting each index in a container object? Ada already has a lot of the intrasturcture there, with the 'First, 'Last, 'Succ and 'Pred attributes. This idea has a lot of merit, and should be explored further. It would be very nice if Ada0x was designed so that a programmer could write for I in Foo'Range loop ... end loop; for a user-defined array-like type. > Also, I think that procedure "()" makes more sense, but that is just > nomenclature. What is not nomenclature is that Ada already allows > functions as prefixes on the left-hand side of assignment statements! > (The function has to return an access type, but from there on everything > works like you would expect.) So I recommend instead: > > -- Function used to evaluate Source( Index ) > function "()" ( Source : in Array_Like_Type; > Index : in Index_Type ) > return Component_Type; > > for Source'First use My_First; > for Source'Last use My_Last; > -- I think that allowing a definition of 'Range other than > -- Source'First..Source'Last would require too much invention. > -- Given that, Source'Length can be defined as > -- Index_Type'Pos(Source'Last) - Index_Type'Pos(Source'First) + 1. > > -- function for assigning Value to Source( Index ) > function "()" ( Source : in out Array_Like_Type; > Index : in Index_Type) > return Component_Type'Access; > > Yes, that does though have the effect that for some types with packed > representations you are not going to be able to define the second > operation, so you must still use a procedure call to do the > modification. But it should work fine for sparse array implementations. Granted, the function returning Component_Type'Access would work in many cases, but I still think that the most general and powerful approach is to have the "()" function and "():=" procedure. Consider an instantiation of Ada.Direct_Io: type Element_Type is record ... end record; package Element_Io is new Ada.Direct_Io( Element_Type ); use Element_Io; My_File : Element_Io.File_Type; An open file of type Element_Io.File_Type can be thought of as an array of objects of type Element_Type. In fact, one could view such a file as an array of Element_Type objects that are stored in a random access file instead of memory. Given this view, why not use array notation for the handling the contents of this file? With the "()" and "():=" operators, we could extend Ada.Direct_Io so that Read( File => My_File, Item => My_Element, From => Index ); could also be written (using the "()" function) as My_Element := My_File( Index ); Conversely, the "():=" procedure can be used to write to the file, i.e. instead of writing Write( File => My_File, Item => My_Element, To => Index ); the programmer would be able to write My_File( Index ) := My_Element; ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-05 1:15 ` Robert I. Eachus 2003-06-05 14:59 ` Frank J. Lhota @ 2003-06-05 17:25 ` Matthew Heaney 1 sibling, 0 replies; 21+ messages in thread From: Matthew Heaney @ 2003-06-05 17:25 UTC (permalink / raw) "Robert I. Eachus" <rieachus@attbi.com> wrote in message news:<3EDE998D.3060701@attbi.com>... > > Also, I think that procedure "()" makes more sense, but that is just > nomenclature. What is not nomenclature is that Ada already allows > functions as prefixes on the left-hand side of assignment statements! > (The function has to return an access type, but from there on everything > works like you would expect.) So I recommend instead: That's essentially why you don't really need this change in the language. I gave the example: To_Access (I).all := X; which does almost what you want. Instead of dereferencing a named iterator object, you could do this (ignoring the fact that Find can fail): To_Access (Find (Map, Key)).all := X; Of course, you could have Find return an access type directly: Find (Map, Key).all := X; No, this is not as simple as: Map [Key] := X; but it's pretty close. One thing I would like, in lieu of proper reference types, is to limit what a user is allowed to do with an access type, e.g. type Element_Access is limited access all Element_Type; or better yet type Element_Access (<>) is limited access all Element_Type; This would prevent the user from hanging on to the access object returned by Find. The C++ index operator can modify the map, to implicitly insert the key and construct the associated element with its default value; this allows you to do this (because scalars are initialized to 0): ++map[key]; To provide this feature in Ada you'll have to pass the map as an access parameter: Set (Map'Access, Key).all := X; This inserts the key into the map if it wasn't already in the map. To implement this using Charles, it's simple enough: function Set (Map : access Map_Subtype; Key : in Key_Subtype) return Element_Access is I : Iterator_Type; B : Boolean; begin Insert (Map.all, Key, I, B); return To_Access (I); end; Of course, if the map object is visible at the point of declaration of Set, then you can get rid of the map parameter, reducing the syntax to: Set (Key).all := X; http://home.earthlink.net/~matthewjheaney/charles/ I have a new release almost ready to go, containing new set and map containers that allow you to store elements that have a limited type. For example, this would allow you to create a set of files, with the file name as the key: package File_Sets is new Charles.Sets.Sorted.Limited_Unbounded (Key_Type => String, Element_Type => Ada.Text_IO.File_Type); [There's also a hashed version.] procedure Open (Set : in out File_Sets.Container_Type; Name : in String) is I : Iterator_Type; B : Boolean; begin Insert (Set, Name, I, B); if B then declare F : File_Type renames To_Access (I).all; begin Open (F, In_File, Name); end; else declare F : File_Type renames To_Access (I).all; begin if not Is_Open (F) then Open (F, In_File, Name); end if; end; end if; end Open; In you're interested, drop me a line. -Matt ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-03 14:59 ` Frank J. Lhota 2003-06-03 15:09 ` Frank J. Lhota 2003-06-03 16:04 ` Martin Krischik @ 2003-06-03 20:24 ` Randy Brukardt 2 siblings, 0 replies; 21+ messages in thread From: Randy Brukardt @ 2003-06-03 20:24 UTC (permalink / raw) Frank J. Lhota wrote in message ... >"Matthew Heaney" <mheaney@on2.com> wrote in message >news:1ec946d1.0306021542.58714996@posting.google.com... >> If you're going to make a change in the syntax of the language, then >> it has be because it allows you to do something you can't do already. >> For example, there's no way to declare an access subtype right now >> that means "all the access values except null." A useful language >> change would be to allow the declaration: >> >> type Element_Access_Base is access all Element_Type; >> >> subtype Element_Access is Element_Access_Base range not null; > >This is an interesting idea, and we should probably pursue it further in >another. Constraint checking has always been tremendously helpful. There is >one potential (but not insurmountable) problem with this proposal: in the >absence of explicit initializations, an access variable is initialized to >null. Already done. See AI-00231. (But there are some problems with doubly constrained subtypes, so it is not yet finished.) Randy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-02 23:42 ` Matthew Heaney 2003-06-03 14:59 ` Frank J. Lhota @ 2003-06-03 19:52 ` Francisco Javier Loma Daza 1 sibling, 0 replies; 21+ messages in thread From: Francisco Javier Loma Daza @ 2003-06-03 19:52 UTC (permalink / raw) mheaney@on2.com (Matthew Heaney) wrote in message news:<1ec946d1.0306021542.58714996@posting.google.com>... > "Frank J. Lhota" <NOSPAM.lhota.adarose@verizon.net> wrote in message news:<V0LCa.32473$ca5.11277@nwrdny02.gnilink.net>... > > There appears to be wide agreement that Ada 200X should include some sort of > > standard container library like Charles and PragMark. This library will > > probably include generic packages for creating and operating with dynamic > > lists and maps. One can view these kinds of collections as generalized > > arrays, and as such, it would be nice to use array notation for accessing a > > member of one of these collections. > > > [snip] > > I cannot help but think that this would be of tremendous help with whatever > > standard container library is added to Ada 200X. > > But all you've done is change the syntax. None of your suggestions > allow you to do more than is already provided by the library. > Yes, I can first make a prototype using arrays, and when a more dynamic structure is needed switch to a Single_List. If Single_List have the same syntax of an array (operator (), and some attributes), I have not to change a line of code. The same example with Unbounded_String and String .... I know that I can do generics for that purpouse, but then loosing all the syntactic richness/sugar. Providing a consistent notation/syntax for arrays and user defined containers would make the code look like better, isn't readability an Ada goal? Ada have very good support for basic types, why not have the same support for user defined types? > [snip] [snip] > If you're going to make a change in the syntax of the language, then > it has be because it allows you to do something you can't do already. Yes, I can live without that ... but then I will have to rewrite (and retest) a lot of lines of code. Having that will make more readable my code by not to worry about how every particular collection is defined. [snip] > For example, there's no way to declare an access subtype right now > that means "all the access values except null." A useful language > change would be to allow the declaration: > > type Element_Access_Base is access all Element_Type; > > subtype Element_Access is Element_Access_Base range not null; I like your proposal very much!!! ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-02 16:35 Adding "()" operator to Ada 200X Frank J. Lhota 2003-06-02 23:42 ` Matthew Heaney @ 2003-06-03 2:56 ` Fionn mac Cuimhaill 2003-06-03 14:02 ` Matthew Heaney 2003-06-03 16:23 ` Mário Amado Alves 1 sibling, 2 replies; 21+ messages in thread From: Fionn mac Cuimhaill @ 2003-06-03 2:56 UTC (permalink / raw) On Mon, 02 Jun 2003 16:35:01 GMT, "Frank J. Lhota" <NOSPAM.lhota.adarose@verizon.net> wrote: >There appears to be wide agreement that Ada 200X should include some sort of >standard container library like Charles and PragMark. This library will >probably include generic packages for creating and operating with dynamic >lists and maps. One can view these kinds of collections as generalized >arrays, and as such, it would be nice to use array notation for accessing a >member of one of these collections. In other words, one should be able to >define the "()" operator for array-like types, as follows: > > function "()" ( Source : in Array_Like_Type; > Index : in Index_Type ) > return Component_Type; > > To go along with this, a way to define a slice of of an Array_Like_Type would be nice. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-03 2:56 ` Fionn mac Cuimhaill @ 2003-06-03 14:02 ` Matthew Heaney 2003-06-03 16:23 ` Mário Amado Alves 1 sibling, 0 replies; 21+ messages in thread From: Matthew Heaney @ 2003-06-03 14:02 UTC (permalink / raw) Fionn mac Cuimhaill <invisible@hiding.from.spam> wrote in message news:<s53odv46kst9rb73a8tsuqmgft6d7ap105@4ax.com>... > On Mon, 02 Jun 2003 16:35:01 GMT, "Frank J. Lhota" > <NOSPAM.lhota.adarose@verizon.net> wrote: > > To go along with this, a way to define a slice of of an > Array_Like_Type would be nice. But you already can do that using iterators, e.g. declare I, J : Iterator_Type; begin Equal_Range (Multimap, Key, I, J); --... end; Here the range [I, J) designates the contiguous range of items having key value Key. You can use Find and Generic_Find to generalize this to elements (instead of just keys), and to other kinds of containers such as a List. Once you have the iterator pair that designates the range, then you can iterate over the range: while I /= J loop declare E : Element_Type renames To_Access (I).all; begin --... end; I := Succ (I); end loop; You could also use a passive iterator. For example, if you wanted to copy a range of items (kind of like what a traditional slice does), then you do something like: declare Another_List : List_Subtype; procedure Process (I : Iterator_Type) is E : constant Element_Type := Element (I); --or E : Element_Type renames To_Access (I).all; begin Push_Back (Another_List, E); end; procedure Iterate is new Generic_Select_Elements (Process); begin Iterate (I, J); --now Another_List has a copy of the elements --from List in the range [I, J) end; ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-03 2:56 ` Fionn mac Cuimhaill 2003-06-03 14:02 ` Matthew Heaney @ 2003-06-03 16:23 ` Mário Amado Alves 2003-06-05 19:02 ` Dmitry A. Kazakov 1 sibling, 1 reply; 21+ messages in thread From: Mário Amado Alves @ 2003-06-03 16:23 UTC (permalink / raw) > > function "()" ( Source : in Array_Like_Type; > > Index : in Index_Type ) > > return Component_Type; > > To go along with this, a way to define a slice of an > Array_Like_Type would be nice. Great idea! function "()" (Source : in Array_Like_Type; From : in Index_Type; To : in Index_Type) return Array_Like_Type; Or "(..)". Yes, Matthew, it's just syntax. So are the (already) redefineable operators. But it's really useful, no? Compare e.g. ... +"Marius", +"Matthew", ... to ... new String' ("Marius"), new String' ("Matthew"), ... Actually the fact that it's just syntax might facilitate getting it approved :-) BTW, I think that if a standard containers library is included in 200X then Ada.Strings.Unbounded and the like should be revised in terms of it. It would drastically reduce the size of the specs. It would suffice to say something like Unbounded_String is equivalent to the container type of an instantiation of Ada.Containers.Arrays.Unbounded with the type Character. --Marius ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-03 16:23 ` Mário Amado Alves @ 2003-06-05 19:02 ` Dmitry A. Kazakov 2003-06-06 10:56 ` Mário Amado Alves 0 siblings, 1 reply; 21+ messages in thread From: Dmitry A. Kazakov @ 2003-06-05 19:02 UTC (permalink / raw) Mário Amado Alves wrote: >> > function "()" ( Source : in Array_Like_Type; >> > Index : in Index_Type ) >> > return Component_Type; >> >> To go along with this, a way to define a slice of an >> Array_Like_Type would be nice. > > Great idea! > > function "()" > (Source : in Array_Like_Type; > From : in Index_Type; > To : in Index_Type) > return Array_Like_Type; > > Or "(..)". IMO one should first add a new set of types: "index" types. With some set of predefined operations. Then you define sets over index types. "range" is an example of such a set. More interesting would be "column", "row" for a multi-dimensional index. (Ada does not have slices of multi-dimensional arrays). Then a square subset (specifies submatrix). Then a diagonal set ... ad infinum. (:-)) Only when you have proper index types, you can start to play with operations like slices and enumeration (in for-statement). If you have true index types and objects, you will need only one ()! function "()" ( Source : in Array_Like_Type; Index : Index_Like_Type ) return ? The problem is that, what the function returns, depends on how the index argument is constrained. This brings back a very important point of dealing with type constraints in a more general way than Ada presently does. For instance to allow () described above, one should treat: type Element is ... type Vector is array (Index_1) of Element; type Matrix is array (Index_1, Index_2) of Element; as differenty constrained subtypes of the same type Matrix. Both discriminants and tags can be considered type constraints. Then there are two major problems: 1. There has to be a way to remove statically known constraints. 2. There has to be a way to evaluate constraints in an independent body (from the original procedure body). > Yes, Matthew, it's just syntax. So are the (already) redefineable > operators. But it's really useful, no? Compare e.g. > ... > +"Marius", > +"Matthew", > ... > to > ... > new String' ("Marius"), > new String' ("Matthew"), > ... > > Actually the fact that it's just syntax might facilitate getting it > approved :-) > > BTW, I think that if a standard containers library is included in 200X > then Ada.Strings.Unbounded and the like should be revised in terms of > it. It would drastically reduce the size of the specs. It would > suffice to say something like > > Unbounded_String is equivalent to the container type > of an instantiation of Ada.Containers.Arrays.Unbounded > with the type Character. Oh that's for sure. For example: type X is tagged something; is an equivalent to type X is something; pragma Embedded_Tag (X); --- type X is limited something; is an equivalent to type X is something; procedure ":=" (L : in out X; R : Y) is null; --- ... -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-05 19:02 ` Dmitry A. Kazakov @ 2003-06-06 10:56 ` Mário Amado Alves 2003-06-06 16:55 ` Chad R. Meiners ` (2 more replies) 0 siblings, 3 replies; 21+ messages in thread From: Mário Amado Alves @ 2003-06-06 10:56 UTC (permalink / raw) > IMO one should first add a new set of types: "index" types. (Dmitry) Maybe *every* 'conceptual' type should be in the type system. A la Smalltalk. This includes exceptions (cf. AE'2001) and, yes, ranges. It always bugged me what is the 'return type' of the Range attribute. I think it's the only attribute that does not return a type proper. Even exceptions and tags have their 'surrogates' in the type system. I can see "I .. J" as sugar for "Range (From => I, To => J)". ".." as an operator! But this be too much to prepare for Ada 200Y :-( Ada 20XX maybe, if we're still around :-) ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-06 10:56 ` Mário Amado Alves @ 2003-06-06 16:55 ` Chad R. Meiners 2003-06-06 19:01 ` Frank J. Lhota 2003-06-07 8:36 ` Dmitry A. Kazakov 2 siblings, 0 replies; 21+ messages in thread From: Chad R. Meiners @ 2003-06-06 16:55 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 264 bytes --] "M�rio Amado Alves" <maa@liacc.up.pt> wrote in message news:4a4de33a.0306060256.52b12d70@posting.google.com... > It always bugged me what is the 'return type' of the Range attribute. You're not the only one ;) http://www.cse.msu.edu/~meinersc/ranges.html ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-06 10:56 ` Mário Amado Alves 2003-06-06 16:55 ` Chad R. Meiners @ 2003-06-06 19:01 ` Frank J. Lhota 2003-06-09 14:15 ` Matthew Heaney 2003-06-07 8:36 ` Dmitry A. Kazakov 2 siblings, 1 reply; 21+ messages in thread From: Frank J. Lhota @ 2003-06-06 19:01 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1679 bytes --] "M�rio Amado Alves" <maa@liacc.up.pt> wrote in message news:4a4de33a.0306060256.52b12d70@posting.google.com... > > IMO one should first add a new set of types: "index" types. (Dmitry) > > Maybe *every* 'conceptual' type should be in the type system. > A la Smalltalk. > This includes exceptions (cf. AE'2001) and, yes, ranges. > It always bugged me what is the 'return type' of the Range attribute. > I think it's the only attribute that does not return a type proper. > Even exceptions and tags have their 'surrogates' in the type system. > I can see "I .. J" as sugar for "Range (From => I, To => J)". > ".." as an operator! This would dovetail nicely with the idea of an Ada iterator schemes. The "range" object could encapsulate the notion of an oredered list of values. Each Range object would a 'First element and a 'Last element, as well as the 'Succ / 'Pred functions to move forward / backward through the values in the range. If Ada 200X had a range object, it would be nice to be able to define the "in" operator for it. Moreover, it would be great if the "for" loop could work with range objects, i.e. for I in Range_Object loop ... end loop; would execute the loop body with I set to each value in Range_Object, visited in Forward order, starting at 'First and ending with 'Last. Similarly for I in reverse Range_Object loop ... end loop; would visit the values in Range_Objec in reverse order, i.e. starting with 'Last, then moving towards 'First using the 'Pred function. > But this be too much to prepare for Ada 200Y :-( > Ada 20XX maybe, if we're still around :-) I plan to live to be 100, although I might not be programming at that time. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-06 19:01 ` Frank J. Lhota @ 2003-06-09 14:15 ` Matthew Heaney 0 siblings, 0 replies; 21+ messages in thread From: Matthew Heaney @ 2003-06-09 14:15 UTC (permalink / raw) "Frank J. Lhota" <NOSPAM.lhota.adarose@verizon.net> wrote in message news:<uy5Ea.14478$b8.437@nwrdny03.gnilink.net>... > > This would dovetail nicely with the idea of an Ada iterator schemes. The > "range" object could encapsulate the notion of an oredered list of values. > Each Range object would a 'First element and a 'Last element, as well as the > 'Succ / 'Pred functions to move forward / backward through the values in the > range. You can already do this. In the Charles library, every container is indeed "an ordered list of values," which you can navigate using either active or passive iterators. Each container has selector functions that return iterator objects designating the first and last elements in the container (and keys, if this is a map), as well as the nonce elements immediately after the last element and immediately before the first element. > If Ada 200X had a range object, it would be nice to be able to define > the "in" operator for it. Moreover, it would be great if the "for" loop > could work with range objects, i.e. > > for I in Range_Object loop ... end loop; > > would execute the loop body with I set to each value in Range_Object, > visited in Forward order, starting at 'First and ending with 'Last. Just do this: procedure Op (C : Container_Subtype) is I : Iterator_Type := First (C); J : constant Iterator_Type := Back (C); begin while I /= J loop declare E : constant Element_Type := Element (I); begin Do_Someting (E); end; I := Succ (I); end loop; end Op; --or this: procedure Op (C : Container_Subtype) is procedure Iterate is new Generic_Select_Elements (Do_Something); begin Iterate (First (C), Back (C)); end Op; > Similarly > > for I in reverse Range_Object loop ... end loop; > > would visit the values in Range_Objec in reverse order, i.e. starting with > 'Last, then moving towards 'First using the 'Pred function. Just do this: procedure Op (C : Container_Subtype) is I : Iterator_Type := Last (C); J : constant Iterator_Type := Front (C); begin while I /= J loop declare E : constant Element_Type := Element (I); begin Do_Someting (E); end; I := Pred (I); end loop; end Op; --or this: procedure Op (C : Container_Subtype) is procedure Iterate is new Generic_Reverse_Select_Elements (Do_Something); begin Iterate (Last (C), Front (C)); end Op; No change in Ada language syntax is necessary. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Adding "()" operator to Ada 200X 2003-06-06 10:56 ` Mário Amado Alves 2003-06-06 16:55 ` Chad R. Meiners 2003-06-06 19:01 ` Frank J. Lhota @ 2003-06-07 8:36 ` Dmitry A. Kazakov 2 siblings, 0 replies; 21+ messages in thread From: Dmitry A. Kazakov @ 2003-06-07 8:36 UTC (permalink / raw) Mário Amado Alves wrote: >> IMO one should first add a new set of types: "index" types. (Dmitry) > > Maybe *every* 'conceptual' type should be in the type system. > A la Smalltalk. Every conceptual type a programmer might imagine. That's the difference between ADT and non-ADT. Alas, there is no ADT for 2nd-order types (type sets like (<>), range (<>), mod (<>) etc) in Ada. That has to be changed. Another weakness is absense of supertypes. It is impossible to develop a type hierarchy before coding in a project of real size. Especially it is true for Ada as opposed to "run-once" languages. So if I want to mix String and Unbounded_String let me do it. > This includes exceptions (cf. AE'2001) and, I am not sure that exceptions should be of different types. To have classes of exceptions one just need them to be ordered in some way. Type hierarchy brings an order, but other, undesirable effects, as well. I would prefer an ordered set of exceptions of same (index) type. With index types one could do something like: IO_Errors : exception'Set := End_Error..Use_Error; ... exception when IO_Errors => > yes, ranges. > It always bugged me what is the 'return type' of the Range attribute. > I think it's the only attribute that does not return a type proper. > Even exceptions and tags have their 'surrogates' in the type system. > I can see "I .. J" as sugar for "Range (From => I, To => J)". > ".." as an operator! And "|" as an operator! Then somebody (me?) whould ask for: Prime_Numbers : Integer'Set := 1 | 3 | 5 | 7 | 11 | 13; type Primes is Integer Prime_Numbers; -- (:-)) > But this be too much to prepare for Ada 200Y :-( > Ada 20XX maybe, if we're still around :-) -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2003-06-09 14:15 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-06-02 16:35 Adding "()" operator to Ada 200X Frank J. Lhota 2003-06-02 23:42 ` Matthew Heaney 2003-06-03 14:59 ` Frank J. Lhota 2003-06-03 15:09 ` Frank J. Lhota 2003-06-03 16:04 ` Martin Krischik 2003-06-04 17:28 ` Matthew Heaney 2003-06-04 18:21 ` Frank J. Lhota 2003-06-05 1:15 ` Robert I. Eachus 2003-06-05 14:59 ` Frank J. Lhota 2003-06-05 17:25 ` Matthew Heaney 2003-06-03 20:24 ` Randy Brukardt 2003-06-03 19:52 ` Francisco Javier Loma Daza 2003-06-03 2:56 ` Fionn mac Cuimhaill 2003-06-03 14:02 ` Matthew Heaney 2003-06-03 16:23 ` Mário Amado Alves 2003-06-05 19:02 ` Dmitry A. Kazakov 2003-06-06 10:56 ` Mário Amado Alves 2003-06-06 16:55 ` Chad R. Meiners 2003-06-06 19:01 ` Frank J. Lhota 2003-06-09 14:15 ` Matthew Heaney 2003-06-07 8:36 ` 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