[comp.lang.eiffel] "retrieved" considered harmful; also question re Eiffel Conf.

jellinghaus-robert@CS.Yale.EDU (Rob Jellinghaus) (03/19/90)

First, the quick question:  what is the deadline for submitting papers
to the Eiffel Users' Group Conference which will be held before TOOLS '90?
I have already missed the TOOLS deadline by a couple of weeks (aargh), but
I'd like to get my paper to the Users' conference if possible... (or is it
the First Eiffel Consortium Conference now?)

Now, my beef.  The STORABLE class (which I've dumped on in previous postings)
defines an attribute
	
	retrieved: ANY

which gets inherited by any class inheriting from STORABLE.  This seems
wasteful.  Any object of a class which inherits from STORABLE will now have
an extra field, most of which will never be used.  Consider

class foo export
	repeat ANY, ...

inherit STORABLE

feature
	...
end -- class foo

If we create many instances of foo, each one will have a "retrieved" attribute
taking up space at runtime.  And when one considers that the "retrieved"
attribute only is used after a "retrieve" operation, and that such operations
are unlikely to occur on more than a handful of objects in the system, the
entire scheme seems even more wasteful.  Not to mention what happens if the
user has just done something like this:

class ACK export ...
inherit STORABLE, ...
feature ...
		retrieve_by_name(...);	-- retrieve some huge object and save
					-- in Current's "retrieved" feature
		store_by_name(...);	-- save Current object...
					-- AND the just-retrieved object!!!
... end -- class ACK

This means that any use of the STORABLE facilities on the current object runs
the risk of storing objects that you didn't want to store.  If I want to
retrieve an object and then store it again, I'd rather do it explicitly!

Why not use the once mechanism?  I have implemented things this way in my
store-to-memory class (actually, I didn't do things _exactly_ this way, but
you will get the idea):

class STORABLE_MEMORY export
	retrieved

feature
	retrieved_value: FIELD[ANY] is
		local
			tmp_field: FIELD[ANY]
		once
			tmp_field.Create;
			Result := tmp_field
		end;

	retrieved: ANY is
		do
			Result := retrieved_value.value
		end;

	-- the features that actually store and retrieve objects go here

end -- class STORABLE_MEMORY

class FIELD[T] export
	value {STORABLE_MEMORY}, set_value {STORABLE_MEMORY}

feature
	value: T;

	set_value(val: T) is
		do
			value := val
		end
end -- class FIELD[T]

So when my retrieve procedure in class STORED_MEMORY needs to save the object
that it just retrieved, it does

		retrieved.set_value(... retrieved object ...)

This scheme works just like the old scheme; it permits one to access the last
retrieved object through the "retrieved" attribute.  But it does NOT add an
unnecessary field to all objects inheriting from STORABLE_MEMORY.

I would suggest that ISE consider using this scheme in their STORABLE classes.
If inheritance is to be used as a means to add functionality to objects, the
classes which define that functionality should attempt, as much as possible,
to refrain from defining attributes which will burden all their descendants;
especially when Eiffel is powerful enough to make alternatives possible.

Rob Jellinghaus                | "Next time you see a lie being spread or a
jellinghaus-robert@CS.Yale.EDU |  bad decision being made out of sheer ignor-
ROBERTJ@{yalecs,yalevm}.BITNET |  ance, pause, and think of hypertext."
{everyone}!decvax!yale!robertj |     -- K. Eric Drexler, _Engines of Creation_