[comp.lang.eiffel] constrained generic problem

dbl@alice.UUCP (David Levine, for Kim Bruce) (03/24/89)

	I have been having problems with constrained generics.  Can anyone
give me some advice.  I have a class called SIMPLE_NODE which handles
requests of the form: get_info and print_node  (all it does is package
up a variable name and simple operations on it).  I also have a subclass of 
SIMPLE_NODE called COMPLEX_NODE (what else!) which adds an attribute
phone_number and modifies get_info and print_node to include getting
and printing phone_number as well as name.  NAME_TREE[T] inherits from
BIN_SRCHTREE[T], redefining node_action to call print_node.
	I also have a class tree_menu[T -> SIMPLE_NODE] (see below) which is
constrained generic, and which also has a local variable new_node : T.
---------------------------------------

class tree_menu[T -> SIMPLE_NODE]

inherit
	STD_FILES

feature
	...;
	my_tree : NAME_TREE[T] ;

	create is
	local
		new_node : T
	do
		from done:=false
		until done
		loop
			if .. then...;
			elsif cmd='a' then
				new_node.create;
				next_line ;
				new_node.get_info;
				if my_tree.void then
					my_tree.create(new_node)
				else
					my_tree.insert(new_node)
				end;
			elsif ...;
			else ...;
			end
		end; 
	end;

	getcommand : CHARACTER is
	do ...
	end ;

end --tree_menu

----------------------------------
The problem is that no matter how I instantiate the T, I always get the
operations in SIMPLE_NODE on new_node.  E.g. the call new_node.getinfo
above always calls the operation defined in SIMPLE_NODE even if I define
a variable, complex_menu : TREE_MENU[COMPLEX_NODE], and then write:
	complex_menu.Create
Interestingly if I remove the generics from TREE_MENU and just replace
T everywhere by COMPLEX_NODE, it works fine.  So the problem clearly
has to do with the use of generics.
	Can anyone help me on this?  Is this a compiler error that has
arisen since constrained generics are so new?  
	I have found a work-around based on eliminating the use of 
constrained generics (basically write TREE_MENU using SIMPLE_NODE, 
including a dummy anchor, and then declaring my tree to be of 
class NAME_TREE[like dummy_anchor], and then defining a new
subclass of tree_menu that redefines the class of dummy_anchor to be 
COMPLEX_NODE.  However, I consider this to be a much less elegant
solution to the problem.  The notion of constrained genericity (really
the "bounded quantification" of Cardelli and Wegner) is a much better
way of retaining control of the types of variables than the rather
ad hoc techniques of using anchors.
	Kim Bruce
	Williams College
	kim@cs.williams.edu

P.S.  Is anyone else having the problem of getting '5's all over the place
when trying to use the interactive debugger?

jimp@cognos.uucp (Jim Patterson) (03/26/89)

In article <9091@alice.UUCP> dbl@alice.UUCP (David Levine, for Kim Bruce) writes:
>	I have been having problems with constrained generics.  
>class tree_menu[T -> SIMPLE_NODE]
>	create is
>	local	new_node : T
>	do	    new_node.create;
>The problem is that no matter how I instantiate the T, I always get the
>operations in SIMPLE_NODE on new_node.

The problem is that, in the tree_menu class of your example the
class-type which T is instantiated with isn't really known so in fact
new_node is always created as a SIMPLE_NODE (as you have described).

We have used the following workaround; an instance of the class to
which T is bound is created, and passed to any procedures which need
to create the complex type. Then, that instance can be used to clone a
new instance of that type.  In your example, this would be as follows:

   create(model : T) is
   local new_node : T;
   do 
     new_node.clone(model);
   end;
 -- in client
   a : COMPLEX_NODE;
   t : TREE_MENU[COMPLEX_NODE];
   a.create;
   t.create(a);

>P.S.  Is anyone else having the problem of getting '5's all over the place
>when trying to use the interactive debugger?

We had this problem; it seems to be related to a failure by the viewer 
to recognize timing data in the TERMCAP entries used by Curses. If you
remove this information from the TERMCAP entry for your terminal, it
should go away. (You may actually need the time delay however, in which
case you will have another problem). For example, your vt100 entry likely
looks something like this (I've left most of it out):

d1|vt100|dec vt100:\
	:am:co#80:li#24:cl=50\E[;H\E[2J:bs:cm=5\E[%i%2;%2H:nd=2\E[C:up=2\E[A:\
	:ce=3\E[K:cd=50\E[J:so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m

The timing information is any numeric data immediately following an equal
sign (=), so with this information stripped the entry will look as follows.

d1|vt100|dec vt100:\
	:am:co#80:li#24:cl=\E[;H\E[2J:bs:cm=\E[%i%2;%2H:nd=\E[C:up=\E[A:\
	:ce=\E[K:cd=\E[J:so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m

This problem might be fixed in the next Eiffel release; I really
don't know.

-- 
Jim Patterson                              Cognos Incorporated
UUCP:decvax!utzoo!dciem!nrcaer!cognos!jimp P.O. BOX 9707    
PHONE:(613)738-1440                        3755 Riverside Drive
                                           Ottawa, Ont  K1G 3Z4