comp.lang.ada
 help / color / mirror / Atom feed
* Re: Generics?
@ 1992-09-09  1:34  Rob Allen
  0 siblings, 0 replies; 11+ messages in thread
From:  Rob Allen @ 1992-09-09  1:34 UTC (permalink / raw)


tp923021@jarrah.canberra.edu.au (Ben Elliston) writes:
>I've since moved onto making an array a generic type (such as this):
>GENERIC
>Type Index IS (<>);
>[..]
>Type Stack_Array IS Array(Index) of Character;

>Type Stack_Type IS RECORD
>  Data_Store: Stack_Array;
>  Pointer: Natural;
>END RECORD;

>As it stands now, it seems that since the "pointer" variable (which
>indicates the current "highwater" mark of the array) is a natural, that
>Ada won't allow a natural to access an array indexed by some unknown
>(generic) type.
>For example, if the array was instantiated using a subtype of naturals
>(0 .. 100), allowing a natural to access elements of the array could
>lead to errors (of course, stack.data_store(103) would cause problems).
>Basically, I need to be able to "look at" any element in the array
>regardless of how large an array is defined in the given procedure using
>this package.
>I'm not too familiar with generics, and if someone could shed some light
>on this, I would really appreciate it.
>------------------------------------------------------------------------------
Why not declare Pointer to be of type Index ?  You can use it directly as
a subscript, initiallize it to  Index'first  and check for full against
Index'last.  However if the store is allowed to be logically empty then
there is a classic problem: it is illegal to initiallise Pointer to the 
item before the first [Index'pred(Index'first)].  The easiest solution is
to waste the first array element.
If however you decide to keep Pointer as a Natural where 1 corresponds to
the first element then always use it as 
  X.Data_Store(Index'val(X.Pointer - 1 + Pos_1st))
where
  Pos_1st : constant := Index'pos(Index'first);
is to account for the likelihood that the actual Index is an arbitrary
subtype of a discrete type.  Using this approach the 'full' test is
X.Pointer = Index'length
Though none of the above code has been checked, I hope that helps.  rob
-- 
+---------------------------------------------------------------------+
| Robert K Allen                     email: rob@saturn.cs.swin.oz.au  |
| Computer Science,                  snail: PO Box 218, Hawthorn,     |
| Swinburne University of Technology,       VIC 3122 Australia        |

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics?
@ 1992-09-09  5:26 Andrew Dunstan
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Dunstan @ 1992-09-09  5:26 UTC (permalink / raw)


In article <6978@stan.xx.swin.oz.au>, rob@saturn.cs.swin.OZ.AU (Rob Allen) writ
es:
|> tp923021@jarrah.canberra.edu.au (Ben Elliston) writes:
|> >I've since moved onto making an array a generic type (such as this):
|> >GENERIC
|> >Type Index IS (<>);
|> >[..]
|> >Type Stack_Array IS Array(Index) of Character;
|> 
|> >Type Stack_Type IS RECORD
|> >  Data_Store: Stack_Array;
|> >  Pointer: Natural;
|> >END RECORD;
|> 
|> >As it stands now, it seems that since the "pointer" variable (which
|> >indicates the current "highwater" mark of the array) is a natural, that
|> >Ada won't allow a natural to access an array indexed by some unknown
|> >(generic) type.

[..]

|> If however you decide to keep Pointer as a Natural where 1 corresponds to
|> the first element then always use it as 
|>   X.Data_Store(Index'val(X.Pointer - 1 + Pos_1st))
|> where
|>   Pos_1st : constant := Index'pos(Index'first);
|> is to account for the likelihood that the actual Index is an arbitrary
|> subtype of a discrete type.  Using this approach the 'full' test is
|> X.Pointer = Index'length
|> Though none of the above code has been checked, I hope that helps.  rob


I'd like to see the code from which this is taken. If what is really wanted
is a stack, why is the index of the stack array a generic parameter? It
seems to me that the only generic type parameter for a stack type should
be the type stored - after all, the stack might not be implemented as an array
at all. I agree that Rob Allen's answer to the question is correct, but I
still want to know why the above is being attempted.

-- 
#######################################################################
#  Andrew Dunstan                   #   There's nothing good or bad   #
#  Department of Computer Science   #   but thinking makes it so.     #
#  University of Adelaide           #                                 #
#  South Australia                  #          - Shakespeare          #
#  net: andrewd@cs.adelaide.edu.au  #                                 #
#######################################################################

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics?
@ 1992-09-14 15:00 cis.ohio-state.edu!zaphod.mps.ohio-state.edu!darwin.sura.net!jvnc.net!net
  0 siblings, 0 replies; 11+ messages in thread
From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!darwin.sura.net!jvnc.net!net @ 1992-09-14 15:00 UTC (permalink / raw)


In article <tp923021.715953043@jarrah>, tp923021@jarrah.canberra.edu.au (Ben El
liston) writes:
|> Thanks to those regarding my problem with the case statement .. all
|> fixed now .. and much appreciated!
|> 
|> I've since moved onto making an array a generic type (such as this):
|> 
|> GENERIC
|> Type Index IS (<>);
|> 
|> [..]
|> 
|> Type Stack_Array IS Array(Index) of Character;
|> 
|> Type Stack_Type IS RECORD
|>   Data_Store: Stack_Array;
|>   Pointer: Natural;
|> END RECORD;
|> 

Something still  seems to be missing -- given the two other follow
ups to this article, I guess that I'm not the only one.  Let me add
my two cents.  My package spec. for this package is:

generic

   type Object_Type is private ; -- only one generic instantiation parm.

package Stack_Pt_Pt is

   Type Stack_Type (Max_Size : positive := 32) is private ;

     . . .
   -- Push, Pop, and other specs. here

private

   type Stack_Array_Type is array (positive range <>) of Object_Type ;

   type Stack_Type (Max_Size : positive := 32) is
      record
	 Top    : natural := 0 ;
	 Actual : Stack_Array_Type (1 .. Max_Size) ;
      end record ;

end Stack_Pt_Pt ;

By having Stack_Type declared with a discriminant, the client has
control over determining the max. size of each stack.

My convention for component package names is:

     Component_Xxx_Yyy

where "Component" is the component supportted by the package, 
"Xxx" is "Pt" or "Lpt" to indicate the type of instantiation 
parameter being supportted, and "Yyy" is either "Pt", "Lpt", 
or "En" to indicate the component visibility as either private,
limited private, or totally encapsulated (One copy) by the package.
-- 
+------------------------------------------------------------------+
|  John (Jack) Beidler				                   |
|  Prof. of Computer Science Internet: BEIDLER@JAGUAR.UOFS.ED      |
|  University of Scranton              beidler@guinness.cs.uofs.edu|
|  Scranton, PA 18510	      Bitnet : BEIDLER@SCRANTON            |
|                                                                  |
|          Phone: (717) 941-7446	 FAX:   (717) 941-4250     |
+------------------------------------------------------------------+

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics???
  2001-07-02 22:33 Generics??? Michael Andersson
@ 2001-07-02 17:48 ` James Rogers
  2001-07-02 18:54   ` Generics??? Ehud Lamm
  0 siblings, 1 reply; 11+ messages in thread
From: James Rogers @ 2001-07-02 17:48 UTC (permalink / raw)


Short answer: You can't. It would be a violation of Ada's strong
typing.

Integer types and float types are not implicitly convertable from one
to the other. The problem is specifically the arithmetic operators for
each type, as well as some of the attributes of each type.

If you only want to compare values for equality, or assign one value
to another, then you can specify the generic formal parameter to be
private. If you want to perform arithmetic you must be specific about
whether the type is a floating point type, a fixed point type, an
integer type, or a modular type. Each type has its own definition of
the arithmetic operators. The LRM does not require compilers to
support ambiguity in the arithmetic operators for numeric types.

In a language such as C++ the compiler would simply
promote all integer types to doubles, perform the calculations, 
then (possibly) convert back to the template parameter's actual
type. This is possible because C++ allows implicit conversion of
all integer types to any floating point type. C++ also does not
have an equivalent to Ada attributes. Many attributes of floating
point types are not shared by integer types. 

Jim Rogers
Colorado Springs, Colorado USA

Michael Andersson wrote:
> 
> Hi!
> How do I specify that the generic parameter is a integer or a float. I
> know that you can use
> type T is range <> to specify that T is any Integer-type and that you
> can use type T is digit <> to specify that T is any type of float. But
> how can I use both at the same time?
> I've tried to use type T is private but then I can't use any of the
> +,-,*,/ operators.
> 
> Need your help, please!
> /Michael Andersson



^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: Generics???
@ 2001-07-02 18:42 Beard, Frank
  2001-07-03 10:32 ` Generics??? Anders Wirzenius
  0 siblings, 1 reply; 11+ messages in thread
From: Beard, Frank @ 2001-07-02 18:42 UTC (permalink / raw)
  To: 'comp.lang.ada@ada.eu.org'

[-- Attachment #1: Type: text/plain, Size: 793 bytes --]

You can do it as a private, but you have to pass in the operations.
Attached is an example of what I'm talking about.  Is this what
you're after?

Frank


-----Original Message-----
From: Michael Andersson [mailto:a98mican@ida.his.se]

Hi!
How do I specify that the generic parameter is a integer or a float. I
know that you can use 
type T is range <> to specify that T is any Integer-type and that you
can use type T is digit <> to specify that T is any type of float. But
how can I use both at the same time?
I've tried to use type T is private but then I can't use any of the
+,-,*,/ operators.

Need your help, please!
/Michael Andersson
_______________________________________________
comp.lang.ada mailing list
comp.lang.ada@ada.eu.org
http://ada.eu.org/mailman/listinfo/comp.lang.ada


[-- Attachment #2: GenericOperations.ads --]
[-- Type: application/octet-stream, Size: 802 bytes --]

generic
 
   type Item is private;
   
   with function "+" (the_Left, the_Right : Item) return Item;
   with function "-" (the_Left, the_Right : Item) return Item;
   with function "*" (the_Left, the_Right : Item) return Item;
   with function "/" (the_Left, the_Right : Item) return Item;
   
package GenericOperations is

   function Add (the_Left  : Item;
                 the_Right : Item) return Item;
                       
   function Subtract (the_Left  : Item;
                      the_Right : Item) return Item;
                       
   function Multiply (the_Left  : Item;
                      the_Right : Item) return Item;
                       
   function Divide (the_Left  : Item;
                    the_Right : Item) return Item;
                       
end GenericOperations;

[-- Attachment #3: GenericOperations.adb --]
[-- Type: application/octet-stream, Size: 835 bytes --]

package body GenericOperations is

 
   function Add (the_Left  : Item;
                 the_Right : Item) return Item is
   begin
      return the_Left + the_Right;
   end Add;

                          
   function Subtract (the_Left  : Item;
                      the_Right : Item) return Item is
   begin
      return the_Left - the_Right;
   end Subtract;
                       
                       
   function Multiply (the_Left  : Item;
                      the_Right : Item) return Item is
   begin
      return the_Left * the_Right;
   end Multiply;
                       
                       
   function Divide (the_Left  : Item;
                    the_Right : Item) return Item is
   begin
      return the_Left / the_Right;
   end Divide;
                       
                       
end GenericOperations;

[-- Attachment #4: GenericOperationsTest.ada --]
[-- Type: application/octet-stream, Size: 907 bytes --]

with Ada.Text_Io;
with GenericOperations;

procedure GenericOperationsTest is
 
   package FloatOperations is new
       GenericOperations(Item => float,
                         "+"  => "+",
                         "-"  => "-",
                         "*"  => "*",
                         "/"  => "/");

   x : float := 10.0;
   y : float :=  2.0;
   
   char : character := ' ';
   
begin
 
   Ada.Text_Io.New_Line(2);
   
   Ada.Text_Io.Put_Line("Add      => " & float'image(FloatOperations.Add(x,y)));
   Ada.Text_Io.Put_Line("Subtract => " & float'image(FloatOperations.Subtract(x,y)));
   Ada.Text_Io.Put_Line("Multiply => " & float'image(FloatOperations.Multiply(x,y)));
   Ada.Text_Io.Put_Line("Divide   => " & float'image(FloatOperations.Divide(x,y)));

   Ada.Text_Io.New_Line(2);
   
   Ada.Text_Io.Put("Hit any key ...");
   Ada.Text_Io.Get_Immediate(char);
      
end GenericOperationsTest;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics???
  2001-07-02 17:48 ` Generics??? James Rogers
@ 2001-07-02 18:54   ` Ehud Lamm
  0 siblings, 0 replies; 11+ messages in thread
From: Ehud Lamm @ 2001-07-02 18:54 UTC (permalink / raw)



James Rogers <jimmaureenrogers@worldnet.att.net> wrote in message
news:3B40B485.F9E4074B@worldnet.att.net...
> Short answer: You can't. It would be a violation of Ada's strong
> typing.
>

True enough.
However, you can decalre the type "private" and import operations:
generic
   type T is private;
  with function "+"(A,B:T) return T is <>;


and than pass the correct routines when instantiating. With the "is <>"
syntax you don't even have to explicitly pass the routines.

Another solution  would be to use a generic signature package.


--
Ehud Lamm   mslamm@mscc.huji.ac.il
http://purl.oclc.org/NET/ehudlamm <==  Me!








^ permalink raw reply	[flat|nested] 11+ messages in thread

* Generics???
@ 2001-07-02 22:33 Michael Andersson
  2001-07-02 17:48 ` Generics??? James Rogers
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Andersson @ 2001-07-02 22:33 UTC (permalink / raw)


Hi!
How do I specify that the generic parameter is a integer or a float. I
know that you can use 
type T is range <> to specify that T is any Integer-type and that you
can use type T is digit <> to specify that T is any type of float. But
how can I use both at the same time?
I've tried to use type T is private but then I can't use any of the
+,-,*,/ operators.

Need your help, please!
/Michael Andersson



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics???
  2001-07-02 18:42 Generics??? Beard, Frank
@ 2001-07-03 10:32 ` Anders Wirzenius
  2001-07-03 17:31   ` Generics??? Stephen Leake
  2001-07-03 19:09   ` Generics??? tmoran
  0 siblings, 2 replies; 11+ messages in thread
From: Anders Wirzenius @ 2001-07-03 10:32 UTC (permalink / raw)



Beard, Frank wrote in message ...
>You can do it as a private, but you have to pass in the operations.
>Attached is an example of what I'm talking about.  Is this what
>you're after?
>
>Frank
>
>
>-----Original Message-----
>From: Michael Andersson [mailto:a98mican@ida.his.se]
>
>Hi!
>How do I specify that the generic parameter is a integer or a float. I
>know that you can use
>type T is range <> to specify that T is any Integer-type and that you
>can use type T is digit <> to specify that T is any type of float. But
>how can I use both at the same time?
>I've tried to use type T is private but then I can't use any of the
>+,-,*,/ operators.
>
>Need your help, please!
>/Michael Andersson
>_______________________________________________
>comp.lang.ada mailing list
>comp.lang.ada@ada.eu.org
>http://ada.eu.org/mailman/listinfo/comp.lang.ada
>
>

May I join the thread with an additional question:
Suppose I use the example provided by Frank Beard and want to round up the
result when the type is an integer.
How do I test which type the parameter (in the example: Item) is?
Something like the pseudocode:

   function Divide (the_Left  : Item;
                    the_Right : Item) return Item is
   begin
      case Item is
         when  integer =>
            round up;
         when  float =>
            just divide ;
         when others =>
            null;
      end case;
      return result of division;
   end Divide;

Anders Wirzenius





^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics???
  2001-07-03 10:32 ` Generics??? Anders Wirzenius
@ 2001-07-03 17:31   ` Stephen Leake
  2001-07-03 19:09   ` Generics??? tmoran
  1 sibling, 0 replies; 11+ messages in thread
From: Stephen Leake @ 2001-07-03 17:31 UTC (permalink / raw)


"Anders Wirzenius" <anders.wirzenius@pp.qnet.fi> writes:

> May I join the thread with an additional question:
> Suppose I use the example provided by Frank Beard and want to round up the
> result when the type is an integer.

You'll have to have another generic parameter operation "Round_Up",
that could be null for floats.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics???
  2001-07-03 10:32 ` Generics??? Anders Wirzenius
  2001-07-03 17:31   ` Generics??? Stephen Leake
@ 2001-07-03 19:09   ` tmoran
  2001-07-04  5:30     ` Generics??? Anders Wirzenius
  1 sibling, 1 reply; 11+ messages in thread
From: tmoran @ 2001-07-03 19:09 UTC (permalink / raw)


>Suppose I use the example provided by Frank Beard and want to round up the
>result when the type is an integer.
>How do I test which type the parameter (in the example: Item) is?
>Something like the pseudocode:
>
>   function Divide (the_Left  : Item;
>                    the_Right : Item) return Item is
  If you are passing in the operations as generic parameters, you will
have passed in a "/", either an integer one that does rounding, or a
floating point one that doesn't.  If you want a special "rounded_divide"
operation, you'll pass one in and the floating point one will not
actually do any rounding.
  If someone calls your package asking for integer arithmetic, doesn't
that indicate they don't care too much about accuracy in things like
a divide, anyway?



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generics???
  2001-07-03 19:09   ` Generics??? tmoran
@ 2001-07-04  5:30     ` Anders Wirzenius
  0 siblings, 0 replies; 11+ messages in thread
From: Anders Wirzenius @ 2001-07-04  5:30 UTC (permalink / raw)



tmoran@acm.org wrote in message ...
>>Suppose I use the example provided by Frank Beard and want to round up the
>>result when the type is an integer.
>>How do I test which type the parameter (in the example: Item) is?
>>Something like the pseudocode:
>>
>>   function Divide (the_Left  : Item;
>>                    the_Right : Item) return Item is
>  If you are passing in the operations as generic parameters, you will
>have passed in a "/", either an integer one that does rounding, or a
>floating point one that doesn't.  If you want a special "rounded_divide"
>operation, you'll pass one in and the floating point one will not
>actually do any rounding.
>  If someone calls your package asking for integer arithmetic, doesn't
>that indicate they don't care too much about accuracy in things like
>a divide, anyway?

Maybe they don't care. My question was about the testing and the example was
just an (academic) example.
Thanks anyway.

Anders





^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2001-07-04  5:30 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-07-02 18:42 Generics??? Beard, Frank
2001-07-03 10:32 ` Generics??? Anders Wirzenius
2001-07-03 17:31   ` Generics??? Stephen Leake
2001-07-03 19:09   ` Generics??? tmoran
2001-07-04  5:30     ` Generics??? Anders Wirzenius
  -- strict thread matches above, loose matches on Subject: below --
2001-07-02 22:33 Generics??? Michael Andersson
2001-07-02 17:48 ` Generics??? James Rogers
2001-07-02 18:54   ` Generics??? Ehud Lamm
1992-09-14 15:00 Generics? cis.ohio-state.edu!zaphod.mps.ohio-state.edu!darwin.sura.net!jvnc.net!net
1992-09-09  5:26 Generics? Andrew Dunstan
1992-09-09  1:34 Generics?  Rob Allen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox