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.4 required=5.0 tests=AC_FROM_MANY_DOTS,BAYES_00, XPRIO autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,b5ab7c96b188b59e,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2004-01-12 09:53:29 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!crtntx1-snh1.gtei.net!news.gtei.net!newsfeed1.easynews.com!easynews.com!easynews!cyclone1.gnilink.net!spamkiller2.gnilink.net!nwrdny01.gnilink.net.POSTED!0f19ed38!not-for-mail From: "Frank J. Lhota" Newsgroups: comp.lang.ada Subject: The "()" operator revisited. X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 Message-ID: Date: Mon, 12 Jan 2004 17:53:27 GMT NNTP-Posting-Host: 141.154.226.152 X-Complaints-To: abuse@verizon.net X-Trace: nwrdny01.gnilink.net 1073930007 141.154.226.152 (Mon, 12 Jan 2004 12:53:27 EST) NNTP-Posting-Date: Mon, 12 Jan 2004 12:53:27 EST Xref: archiver1.google.com comp.lang.ada:4355 Date: 2004-01-12T17:53:27+00:00 List-Id: Last June, I proposed that in order to provide an abstract array capability, Ada 0y should support user-defined "()" and "():="operators. Since this issue has come up again, I would like to summarize and expand on this proposal. Note: the following discussion probably has an insufficient amount of legalese to satisfy language lawyers. Once we've thrashed out these ideas, I'll be happy to work with anyone with formalizing this proposal. The idea is that container libraries, such as the Booch components, Charles and PragMark, often include collection objects that can be viewed as generalized arrays. Undoubtedly, the next standard will have some variation of these container libraries. In support of these generalized arrays, Ada should allow the array notation to be used for these object. To this end, I propose adding two operators Ada. The "()" operator, used for reading a component of an abstract array, has the form: function "()" ( Source : in Abstract_Array_Type; Index_1 : in Index_Type_1; Index_2 : in Index_Type_2; ... Index_N : in Index_Type_N ) return Component_Type; Used to write a component of an abstract array, the "():=" operator has the form procedure "():=" ( Source : in out Abstract_Array_Type; Index_1 : in Index_Type_1; Index_2 : in Index_Type_2; ... Index_N : in Index_Type_N; Value : in Component_Type ); For a standard array type of the form type An_Array is array ( Index_Type_1 range <>, Index_Type_2 range <>, ... ) of Component_Type; the "()" and "():=" operators are predefined. The predefined versions of these operators are implicit. For packed arrays, the predefined versions of "()" and "():="does the usual mask and shift operations to unpack or pack the given component. When the "()" function is defined and visible for the type Abstract_Array_Ty pe, and A is a (possibly constant) object of type Abstract_Array_Type, then the expression A( Index_1, Index_2, ... Index_N ) evaluates to "()"( A, Index_1, Index_2, ... Index_N ) Note that the "()" also provides support for an abstract function call facility. The "()" operator suffices for presenting a read-only view of a component of an abstract array type. The "():=" is used in conjunction with "()" to provide a variable view of an abstract array component. When "():=" operator is defined and visible for Abstract_Array_Type, and A is a non-constant object of type Abstract_Array_Type, then the expression A( Index_1, Index_2, ... Index_N ) can be assigned a Value of type Component_Type. This assignment is done by performing the call "():="( A, Index_1, Index_2, ... Index_N, Value ); This "():=" call would also be used if A( Index_1, Index_2, ... Index_N ) is used as an actual parameter for a parameter of mode "out" When both "()" and "():=" operators are visible for Abstract_Array_Type, then the expression A( Index_1, Index_2, ... Index_N ) can be used as an "in out" parameter. If we have the subprogram procedure Fiddle( Item : in out Component_Type ); Then the call Fiddle( A( I_1, I_2, ... I_N ) ); is basically equivalent to declare Temp_Comp : Component_Type := A( I_1, I_2, ... I_N ); begin Fiddle( Temp_Comp ); A( I_1, I_2, ... I_N ) := Temp_Comp; end; except that the indices are evaluated only once. Note: something like this is done in Ada95, when dealing with packed arrays. We can easily define these operators for abstract arrays in Ada95. In the string package Ada.Strings.Unbounded, we could add function "()" (Source : in Unbounded_String; Index : in Positive) return Character renames Element; procedure "():=" (Source : in out Unbounded_String; Index : in Positive; By : in Character) renames Replace_Element; Similar declarations can be added to Ada.Strings.Bounded. This would permit the higher-level Ada string types to use the same notation as the low-level standard String type. Also, one can easily view a Direct I/O file as an abstract array. The package Ada.Direct_Io can inline the following versions of "()" and "():=" for File_Type: function "()" (File : in File_Type; Index : in Positive_Count) return Element_Type is Result : Element_Type; begin Read( File, Result, From => Index ); return Result end "()"; procedure "():=" (File : in File_Type; Index : in Positive_Count; Item : in Element_Type) is begin Write( File, Item, To => Index ); end "():="; A controversial idea: when "()" and "():=" is visible for Abstract_Array_Type, and A is a non-constant object of type Abstract_Array_Type, should we allow a declaration like this: An_Object : Component_Type renames A( I_1, I_2, I_3, ... I_N ); The idea is that this is a "virtual" object of type Component_Type, where calls to "()" and "():=" are used to read and write the values of this object. I'm not entirely sure that this type of "renames" declaration is a good idea, but I'm interested in what others in this NG think of this.