[cello-devel] Unbound cells

Kenny Tilton ktilton at nyc.rr.com
Wed Apr 14 15:18:46 UTC 2004


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.

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?

kt

Kenny Tilton wrote:

>
>
> Thomas F. Burdick wrote:
>
>> I have a couple models where I'd like to have unbound slots that
>> normally have cv cells in them.  NIL is a valid value, so I can't just
>> say "nil is the invalid value."  What I'm doing is using a special
>> invalid-value object when I'd normally have an unbound slot:
>>
>>  (defconstant +unbound+ '+unbound+)
>>  (deftype %nil () '(or nil (eql +unbound+)))
>>
>>  (defmacro define-unbound-methods (&body slot-specs)
>>    (loop for (class slot opt-accessor) in slot-specs
>>          for accessor = (or opt-accessor slot)
>>          collect `(defmethod ,accessor :around ((object ,class))
>>                     (let ((value (call-next-method)))
>>                       (if (eq value +unbound+)
>>                           (error 'slot-unbound :instance object :name 
>> ',slot)
>>                           value)))
>>          into methods
>>          finally (return `(progn , at methods))))
>>
>>  (defun cv_ () (cv +unbound+))
>>
>>  (defmodel my-handler (araneida:handler)
>>    ((user-id :accessor user-id :initarg user-id :initform (cv_)
>>              :documentation
>>              "user id or NIL if the user didn't supply valid 
>> credentials")
>>     (homepage :accessor homepage :initarg homepage
>>               :initform (c?_ (aif (id (^user-id))
>>                                   (make-homepage-for-user id)
>>                                   (create-user-account))))))
>>
>>  (define-unbound-methods (my-handler userid))
>>
>>  (defmethod handle-request-authentication ((handler my-handler) 
>> method request)
>>    (setf (user-id h) ...))
>>
>> If user-id is unbound, it means that authentication hasn't been
>> performed yet, so it would be a program error to try to use its value
>> at that point.
>>
>> It seems like it wouldn't be too hard to put the concept of unbound
>> slots into Cells itself, so that storing the unbound-slot value would
>> work fine, but reading it would signal a slot-unbound error.  Add
>> cell-makunbound and cell-boundp, and it would be the normal CLOS
>> semantics again.
>>
>> Does this sound like a good idea?  Or is there a more idiomatically
>> Cells way of doing this, and I'm wandering too far down The Dark Path
>> of Lazyness?
>>
> 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.
>
> kt
>

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film 
Your Project Here! http://alu.cliki.net/Industry%20Application






More information about the cello-devel mailing list