[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


    Date: 21 Apr 1985  22:24 EST (Sun)
    From: Bill Rozas <JINX%MIT-OZ at MIT-MC.ARPA>

    Instead of hash-object and unhash-object, why don't we include
    populations?  The implementation can be done in terms of hash and
    unhash object or more primitively, and they seem to constitute the
    most common use of these procedures.

I don't think populations are much easier to implement than hash/unhash,
and they aren't as general.  T started out having populations, and a
year or two later acquired OBJECT-HASH, which was applicable in many
situations where populations wouldn't do.  (I think you might be able
to implement hash/unhash in terms of populations, but it's much less
natural than vice versa.)

Uses for hash/unhash include populations, weak tables, and file closing,
as well as the following interesting hack, which has tremendous
popularity with users:  PRINT calls OBJECT-HASH when it comes across an
object with no standard external representation, a procedure for
example, and prints the hash number along with any other type and
identification info it can find: e.g.

    > cadr				;User's typein
    #{Procedure 31 CADR}		;System's typeout
    > (lambda (x) (* x 3))
    #{Procedure 32}

Although the syntax #{...} isn't readable (that could cause very bizarre
results for READ's done in processes different from the one which
printed the object), you can evaluate (OBJECT-UNHASH 32) and, if the
garbage collector hasn't done away with it, get the procedure back.
This is vaguely like "D-lines" in Macsyma, except that it permits

Note that hash is called only when PRINT is called, so there is no
evaluator overhead involved.  (One user was at first baffled by the
following interaction:

    > (lambda () 1)
    #{Procedure 33}
    > (lambda () 2)
    #{Procedure 34}
    > (do ((i 0 (1+ i))
	   (p nil (lambda () i)))
	  ((= i 100) p))
    #{Procedure 35}

and then figured out that PRINT was generating the numbers.)