[cells-devel] Re: [cello-devel] Unbound cells

Thomas F. Burdick tfb at OCF.Berkeley.EDU
Wed Apr 14 19:18:48 UTC 2004


Kenny Tilton writes:

 > It might be the Dark Path of a long, well-respected, misbegotten 
 > tradition of collapsing two attributes into one, creating /extra/ work 
 > to save a slot. The first of the two slots is 'sign-in-status", with 
 > three values: not-yet, failed, or succeeded. Then there is another slot, 
 > which indicates who signed in (iff successful). We programmers have a 
 > long heritage and habit of collapsing two values into one to save memory 
 > or disk space (remember those?) by using some trick such as "use nil for 
 > failure, unbounditude for not-yet, non-nil bound for the user", but my 
 > experience has been that life gets a lot easier if I just let the diff 
 > attributes be diff slots.
 > 
 > It is certainly tempting to "save one slot", but, again, my experience 
 > has been that the consequent overloading saves a slot at the expense of 
 > forever complexifying the code. I can't just say (ecase (sign-in-status 
 > self) (:not-yet..)(:failed..)(:cool...))... I have to detect one 
 > expected value with 'cell-unboundp and the other two with ecase, every 
 > place in the code I need to access the user.

My hesitation to do this is that I don't want worry about
authentication outside of the authentication phase.  Having an unbound
slot seems a nice way to deal with it because it expresses the idea
that asking for a user-id is not a valid question right now.  It's
perfectly legitimate for a user to not be logged in, but I want to
make sure this has been checked.

I guess I could do something like this:

  (defmodel my-handler ()
    ((auth-status :accessor auth-status :initarg auth-status
                  :initform (cv :not-authenticated))
     (%user-id :accessor %user-id :initarg %user-id
               :initform (cv nil))
     (user-id :accessor user-id :initarg user-id
              :initform (c? (assert (eql (^auth-status) :authenticated))
                            (^%user-id)))))

  (defmethod authenticate ((request my-handler))
    (let ((user-id ...))
      (setf (auth-status request) :authenticated
            (%user-id request) user-id)))

However ...

Kenny Tilton writes:
 > On the other hand, Cells should not change Lisp unnecessarily.
 > 
 > It would be easy enough to do something such as (cv +unbound+) or just 
 > (cv) and then have the internal sm-install function invoke 
 > slot-makunbound instead of forcing the slot to be bound. Then one does 
 > not need a special test for cell-boundp (which sounds wrong anyway in re 
 > transparency).
 > 
 > But what about a rule that runs across an unbound cell/slot? I should 
 > think that does not generate an unbound error, rather the slot mediated 
 > by the rule should in turn be made unbound.
 > 
 > I guess echoing works OK, tho anyway doing this on the GUI slots will 
 > not get far since existing echos are not testing for unbounditude.

... I like this, because if you have rules that ultimately depend on
an uncalculated value, you'll get an error when you try to ask for it.

 > The big hole is that slot-makunbound does not go through (setf 
 > /accessor/), and slot-makunbound-using-class is not portable, so we 
 > would need to lose some transparency and have an exported 
 > c-slot-makunbound function to make the slot unbound and kick off 
 > propagation (and confirm that the slot is c-variable mediated).
 > 
 > thoughts?

This is actually why I stopped at the cheesy hack level with what I
had (that, and I wanted to get back to work).  c-slot-makunbound could
just dtrt if it's given an object that doesn't use cells; then it
wouldn't be so bad to use it, you could just use it everywhere.  You
definately end out with a transperancy problem wrt CLOS one way or the
other, unless you use the MOP.




More information about the cello-devel mailing list