Attributes

Fare Rideau rideau@nef.ens.fr
Tue, 16 Sep 1997 19:56:34 +0200 (MET DST)


>>>: dem
>>: Fare [May 7]
>: dem [Sept 14]

> (Also since the archive isn't being updated)
Oops. I'll try to fix that tomorrow morning.

>>An attribute can be conceptually thought of as a memoized function:
>>you have a function that associates some abstract value to some objects,
>>but want to remember that value permanently without having to recompute it.
>
> The caching of a function result is a separate topic; and is an
> implementation detail.
>
look at the following Scheme definition:
(define (memoize fun)
   (let ((table (make-hash)))
	(lambda args
	   (if (memoized? table args)
	       (memoized-value table args)
	       (let ((value (apply fun args)))
		  (memoize! table args value)
		  value)))))
Well, then
* for any pure deterministic function f, f and (memoize f) are equivalent.
* for most (impure) functions f, (memoize f) is different from f
* memoize is idempotent (i.e. (== (memoize f) (memoize (memoize f))))
* the image set of functions returned by memoize is strictly contained
 in that of all functions.
* a memoized function might still do observable side-effects,
 but only when first called with a given argument.

Note that:
* a pure function is one that does no observable side-effect,
 whether read or write.
* what's observable depends on the level of abstraction you consider;
 surely, a pure function's *implementation* may do things that are
 observable at the *implementation* level,
 like reading/writing memory and registers.
* by modifying the way hashes are implemented, and/or taking into account
 function-dependent properties, different implementations of memoization
 can be achieved.
* using a hash-table in a traditional language is an excellent way
 to leak memory, least you have weak pointers: not to leak memory,
 hashed values should be forgotten when an object is GCed (see below).

Well, by definition, I call attribute a function a such that
(== (memoize a) a)

Attributes are most often what hash tables are used implement.
Another way to implement them is with lazily (or futurely)
initialized tables. Any particular attribute might have
properties that help optimize its implementation
(so that part of it may be recomputed, or multiple attributes
may share a hash table, etc).
Attributes may also be viewed as future structures
(see HBaker's article on Futures).

Attributes are most useful for parsing and unparsing,
for holding the decisions of dynamically triggered heuristics
(as in adaptative user interfaces). For instance,
see position information of a graphical elements
in a window system, pretty printed text or typesetter layout:
it involves some calculations in a dynamically decided order,
then it doesn't change (considering given options/context/whatever).

You can't modify the result of an attribute's computation,
but you can have functions that are not attributes,
or attributes that constantly return a same mutable reference cell (doh!).

I do believe that adding compiler support for attributes is important.

> I was under the impression that attributes were a special case.
Somehow they are. An important one, I think.

>>* If the attribute gets garbage collected,
>> then all the individual memoized information gets garbage collected;
>> if an object gets garbage collected, its attribute disappears, too.
>
> Are you sure?  If I specify how to display my object, and I destroy the
> particular instance of the object, what if I had a backup compressed in
> another module and I wanted to retain the display settings in case I ever
> looked at the object again?
>
If "another module" holds a reference to your object,
then it will not have been garbage collected, and its attributes will have
been conserved. Of course, if the attributes were not the object's but its
instance's, they will be lost. Or perhaps the attribute manager will
not garbage collect the instance's attribute at all, and/or integrate
some of their data to improve its heuristics, in which case a new instance
might still reuse the forgotten old one's attributes.

>>* If you want to be able to associate varying values to objects,
>> then use a reference as the attribute;
>> that's the ML way of making side-effects orthogonal to other computations.
> Still, adding a reference makes the object impure; it no longer just
> contains data relevant to its meaning.  The information is perhaps relevant
> to this specific occurence of the object, but it should be stored separately.
An attribute is not forced to be pure,
only to be observably equivalent to its memoized self.

>>Let's take some usual examples [...]
>>* the system has a concept of "user", built in some module.
>> You want to add some accounting/logging information about users.
>> No need to rewrite the module that define users.
>> Just define a new attribute of users.
>> Same goes with password systems, etc.
>>* you want to type a program. Give each node a type attribute.
>> [Note: programs are stored abstract structures, not ASCII]
> I'm assuming also after you've typed it, that you would want to prove it
> secure, and that once it is proven, you want the type to remain part of the
> final object definition.  At this point the attribute becomes part of the
> object, and no longer is known as an attribute.
>
Well, the attribute is just as much "part of the object"
as any other "field" of it. Actually, the other "parts" of the objects
will have been defined as attributes themselves.


>>* you are not satisfied with the way the pretty printer manages
>> parts of your program; you ask it to remember the layout,
>> or particular layout tactic to use for such parts of the program.
>>* you want to comment a program.
>> Annotate its structure with comments in french, german, chinese, martian.
>>* you want to translate a program.
>> Annotate each node with all the meanings you could find about it,
>> before you can understand it and synthetize a translation.
>
> You seem to be speaking of Attributes as the same thing as Annotations.  Is
> it true that you use the two terms synonymously in all cases?
>
Ahem. Lemme see. Well, looks like so.
Maybe I should choose one term once and for all, ain't it?

> Is an attribute a vital part of an object, for its purpose, or is it just
> extraneous information that is useful elsewhere
> when talking about the object?
> Are you getting the two mixed up?
> Might you try to use an attribute for either purpose?
> The concepts, I believe, are incompatible and should remain separated.
The answer is that "vital" depends on the "context".
In any context where an attribute is observable,
then its (actual or future) value on any observable object
is as "vital" part of the object as any former existing attribute.
But of course, if you consider a "stripped" context,
where the attribute is no more observable,
then its value on objects is no more observable either,
and seems no more vital.
   For instance, if it can be proven that "car" will never be used
anymore on a class of lists and their recursive tail,
then you can forget the contents of these list,
and only remember their length
(some people are known to have "optimized" GCs in such ways).
So you see that even "normal" attributes of objects can be no more vital
after some while.

This is known to be very problematic in distributed systems:
when you want to migrate an object, you must be sure that
this is done consistently with all attributes, including remote ones.
Ouch. Also, this limits the dumpability of objects.
What if dump an object, then it gets restored at several places and times,
and a "same" attribute gets computed several times, with different results
on each of the restored objects?
   To conserve identity accross restorations,
the dump must include an ID that has a broader scope than any attribute
that will have to be shared among all restored instances,
while such attributes will have to check a global registry.
Use of unshared local attributes not accessible from global scopes
limit the need of such global transactions.
   But the only way to usefully dump objects when global transactions
are not possible (e.g. when distributing software for computers
not connected to the internet) is to use some kind of dump-in-context
function, or reify-contextual-semantics, that does not dump the
"whole" of an object's semantics, but only the parts of it observable
from a given context.

> OK, I guess what I am confused about is whether attributes go in the
> instance of an object.
They might or not. That's an implementation dependency.
Hence, when defining a CD database, and adding a new attribute
for CDs, the way instances of the "CD class" are internally represented
may change or not; most likely, the change will be delayed until
the new attribute is confirmed as persistent, and/or enough entries
are using it. For rapidly changing classes, every instance might have some
personal implementation. Or instances could come with a "class subversion"
number, indicating at what stage of the class' history the instance
was last updated. Again, as long as the user doesn't explicitly
mess with the implementation, the system should be free
to do whatever it wants.
Of course, when dumping and restoring whole databases
so as to transmit/save them, or when explicitly asked to do so,
it should somehow "optimize" and compress the result.
   This should preferrably be done at times when there is no user interaction,
so as to keep real-time response from the system
[Tunes, the only OS that dynamically schedules useful work for
when you're away] [Unlike inconsistent cron jobs that horribly clobber /var]

> If you have a large number of instances, and you add
> supplementary (commentary) information to a few of them, but not all,
> clearly the information added should not go in as part of the definition of
> that object, since that would add a field to every instance (And in many
> instances, it would be blank, and therefure wasted).  However, supplementary
> information should not, in my opinion, be stored in the object it is
> supplementing.  Nor should a pointer to the supplement be present in the
> object being described.
> It should be stored separately, in the context of view.
For sparse and/or short-lived attributes, sure.
For dense and persistent attributes, sure not.

> My point is that I see the definition of Attributes as the second item on
> the HLL Semantics.  This tells me that Attributes must be an important part
> of the HLL.
Indeed. I view the head and tail of a list as particular attributes of it.

> However, from what I have been told about Attributes, they seem
> like a part of the system that could be added in *after* the HLL was fully
> founded; in other words, not a requisite part of the HLL, but just a feature
> of the system.
I do believe that "Attribute" is a way to subsume "fields" of an object,
with a nicer semantics (What's an initialized field for an object?
Why specify the implementational details of memory layout of all objects?).

> Please help me understand Attributes, so I can know if they are a vital part
> of the system or not.  It seems to me the functionality you describe as
> belonging to Attributes could be implemented in the system within the
> definitions of "Object" and "Context".
Surely, the "kernel" of any particular implementation need not implement
attributes; however, I do think that requiring Attributes to be
systematically user-implemented is an abstraction inversion
(grep -i hbaker's articles about that, too).

Regards,
	-- #f

PS: I'm pleased to tell you that after succeeding my "DEA" (master thesis?),
I've been confirmed my being employed by France Telecom as a searcher
in the CNET, during the writing of my PhD thesis,
with the subject of studying Static Typing in Reflective Languages.
   This might or not pose problems with my directly contributing code
to Tunes, depending on FT's policy (which is said to be ok, but on a
case-per-case basis; happily; they don't *sell* the OSes they develop
on a living; they *use* them, so I might convince them of the utility
of freely releasing what I write), and french laws (does what I write
outside of working hours belong to them; anyone knows?). We'll see.

== Faré -=- (FR) François-René Rideau -=- (VN) Уng-Vû Bân -=- rideau@ens.fr ==
Join a project for a free reflective computing system! | 6 rue Augustin Thierry
TUNES is a Useful, Not Expedient System.               | 75019 PARIS     FRANCE
http://www.eleves.ens.fr:8080/home/rideau/Tunes/ -=- Reflection&Cybernethics ==