[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