[comp.lang.eiffel] Distributed application: solution in Eiffel

pjg@osf.org (Paulo Guedes) (04/11/90)

Some time ago (article 763 in comp.lang.eiffel) I posted a problem
posed by a distributed application, where the type returned by a
method could not be known when the class was written. In C++ this
could be solved with a cast, but I didn't know the solution in Eiffel.

Several people pointed me out the solution: "reverse assignment".

Many thanks to all who answered:
cwc@notecnirp.Princeton.EDU (Chris Clifton),
Francis Wai <fw%cs.glasgow.ac.uk@NSFNET-RELAY.AC.UK>
jwg1@gte.com (James W. Gish)
eiffel!Geneve!nosmo@uunet.UU.NET (Vincent Kraemer @ Interactive Software Engineering Inc.)
uunet!mailrus!uflorida!novavax!weiner (Bob Weiner)

Next follows the problem and one of the messages with the solution
(as they were all similar I only post one of them).

>Article 763 of comp.lang.eiffel:
>From: pjg@osf.org (Paulo Guedes)
>I have a distributed O-O application that poses a particular
>problem. I'm evaluating how it could (or could not) be solved in
>different O-O languages, so I can choose the best language for this
>class of problems. I know how to solve it in C++ and I'm hopping that
>someone in the net shows me a (better ?) solution in Eiffel.
> [...]
>
>There is a standard class Name that exports the method 'resolve'.
>This method receives as argument the string name of the object. It
>sends a message to the server, receives back the name of the class to
>be instantiated, creates the proxy and returns it (in fact the method
>is fairly complicated, but its details are not relevant here).
>Class Name does not have knowledge of the types of objects it may
>retrieve, as new types may be added long after this class was created.
>I assume that class Name cannot be recompiled every time a new class
>of objects is added to the system.
>
>Problem: What type should method 'resolve' return ?
>
>If 'resolve' returns a Base type (a type which has no knowledge of
>the "useful" types), I can't do anything useful with the returned
>object, as ilustraded below.
>
>	CLASS Base ...
>	CLASS Name EXPORT resolve
>	    FEATURE resolve(n: STRING): Base IS ...
>	END
>	CLASS Useful EXPORT do_something END  
>
>	... code of some class that uses Base, Name and Useful ...
>	
>	Name my_name_server; -- represents the Name Server, created elsewhere
>	Base f;
>	...
>	-- The object may be retrieved from the Name Server
>	f = my_name_server.resolve ("/foo/bar"); 
>	 -- But no "useful" methods may be invoked on variable f !
>	f.do_something; -- This is illegal

From: eiffel!Geneve!nosmo@uunet.UU.NET (Vincent Kraemer @ Interactive Software Engineering Inc.)
Message-Id: <9003221751.AA04254@Geneve.>
To: rome!pjg%osf.org@uunet.UU.NET
Cc: Geneve!eiffel@uunet.UU.NET
Subject: Casting in Eiffel
Reply-To: eiffel!!eiffel@uunet.UU.NET

Paulo,
	There is a facility in Eiffel for solving the problem you are
having.  It is called the reverse assignment.  The syntax is very
simple. The semantics aren't so bad either.

Given a class B which inherits from class A:

	v1: A; 
	v2: B;

	v2 ?= v1;  -- Reverse assignment attempt.

	if not v2.Void then
		-- v1 refers to an object with (dynamic) type B
	else
		-- v1 refers to an object with (dynamic) type other than B.
	end;


This will do what you want, in a type-safe fashion.  Notice, you cannot
"just do the cast" and continue from there.  If the cast is "illegal"
(not to the true dynamic type) the target is set to Void.  This seems
like a much saner behaviour than allowing you to segv at some later
time.

I hope this helps you in your evaluation of Eiffel as an alternative to
C++.

Vince Kraemer
ISE




---
Paulo Guedes     Open Software Foundation   11 Cambridge Center, Cambridge, MA
Email: pjg@osf.osf.org    Phone: (617) 621-8878