• slot-value-using-class to remap "virtual" slots & closer-mop

    From Madhu@enometh@meer.net to comp.lang.lisp on Sat Apr 25 20:35:29 2026
    From Newsgroup: comp.lang.lisp


    I had occasion to want to have certain slot-value accesses "redirect" to
    other slots, so accessing one would seem to affect the other.

    (defclass foo ()
    ((slot-1 :initform 10))
    (#+lispworks :optimize-slot-access #+lispworks nil))

    this is the behaviour which is required

    (setq $f (make-instance 'foo))
    (slot-value $f 'slot-1) ; 30
    (setf (slot-value $f 'slot-3) 20)
    (slot-value $f 'slot-1) ; => 30

    here is the expanded boilerplate which maps 'slot-2' and 'slot-3' to
    'slot-1'

    (defmethod c2mop:slot-value-using-class
    ((class standard-class) (obj foo) slot)
    (let ((slot-name
    (etypecase slot
    (symbol slot)
    (c2mop:standard-effective-slot-definition
    (c2mop:slot-definition-name slot)))))
    (case slot-name
    (slot-2 (slot-value obj 'slot-1))
    (slot-3 (slot-value obj 'slot-2))
    (otherwise (call-next-method)))))

    (defmethod (setf c2mop:slot-value-using-class)
    (value (class standard-class) (obj foo) slot)
    (let ((slot-name
    (etypecase slot
    (symbol slot)
    (c2mop:standard-effective-slot-definition
    (c2mop:slot-definition-name slot)))))
    (case slot-name
    (slot-2 (setf (slot-value obj 'slot-1) value))
    (slot-3 (setf (slot-value obj 'slot-2) value))
    (otherwise (call-next-method)))))

    any pitfalls comments or alternative implementations

    i'm using standard-class but maybe i should be using
    c2mop:standard-class (and c2mop:defmethod) instead, i couldn't spot any documentation on closer-mop on how it is to be used, the objects are
    slightly different, and i'm not able to assess if there is an impact
    across implementaions.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From tfb@no_email@invalid.invalid to comp.lang.lisp on Sat Apr 25 18:27:25 2026
    From Newsgroup: comp.lang.lisp

    Madhu <enometh@meer.net> wrote:


    any pitfalls comments or alternative implementations

    You need a slot-boundp-using-class method at least.

    And to build a package so your code isn't full of package-qualified names, though I realise that's now a list cause. Indeed I am working on an implementation which will require all names to be of the form impl:thing-nobody-understands:version:package:actual-symbol-name. I feel
    this will be wildly successful.
    --
    www.tfeb.org/computer/
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Thu May 7 05:22:45 2026
    From Newsgroup: comp.lang.lisp

    * In <m3ldebnkqu.fsf@pison.robolove.meer.net> :
    I Wrote on Sat, 25 Apr 2026 20:35:29 +0530:

    I had occasion to want to have certain slot-value accesses "redirect" to other slots, so accessing one would seem to affect the other.

    (defclass foo ()
    ((slot-1 :initform 10))
    (#+lispworks :optimize-slot-access #+lispworks nil))

    this is the behaviour which is required

    (setq $f (make-instance 'foo))
    (slot-value $f 'slot-1) ; 30
    ;; should be 10


    (setf (slot-value $f 'slot-3) 20)

    Apparently this only works on lispworks. all other lisps I tried fail at
    this step i.e. accessing the "virtual slot" slot-3, saying the slot does
    not exist.

    since is not found in (class-slots (find-class 'foo)) and the suggested definition of slot-value involves finding the slot in class-slots before passing it to s-v-u-c

    but the goal was to have slot-3 be a "virtual" slot. So I'm back to
    square 1 in trying to implement these "virtual slot redirects"

    (slot-value $f 'slot-1) ; => 30

    here is the expanded boilerplate which maps 'slot-2' and 'slot-3' to
    'slot-1'

    (defmethod c2mop:slot-value-using-class
    ((class standard-class) (obj foo) slot)
    (let ((slot-name
    (etypecase slot
    (symbol slot)
    (c2mop:standard-effective-slot-definition
    (c2mop:slot-definition-name slot)))))
    (case slot-name
    (slot-2 (slot-value obj 'slot-1))
    (slot-3 (slot-value obj 'slot-2))
    (otherwise (call-next-method)))))

    (defmethod (setf c2mop:slot-value-using-class)
    (value (class standard-class) (obj foo) slot)
    (let ((slot-name
    (etypecase slot
    (symbol slot)
    (c2mop:standard-effective-slot-definition
    (c2mop:slot-definition-name slot)))))
    (case slot-name
    (slot-2 (setf (slot-value obj 'slot-1) value))
    (slot-3 (setf (slot-value obj 'slot-2) value))
    (otherwise (call-next-method)))))

    any pitfalls comments or alternative implementations

    i'm using standard-class but maybe i should be using
    c2mop:standard-class (and c2mop:defmethod) instead, i couldn't spot any documentation on closer-mop on how it is to be used, the objects are
    slightly different, and i'm not able to assess if there is an impact
    across implementaions.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Stefan Monnier@monnier@iro.umontreal.ca to comp.lang.lisp on Thu May 7 15:14:24 2026
    From Newsgroup: comp.lang.lisp

    Apparently this only works on lispworks. all other lisps I tried fail at
    this step i.e. accessing the "virtual slot" slot-3, saying the slot does
    not exist.

    I'm not sure I understand the details of what you're looking for (I get
    the impression that your original example had typos that made it too
    confusing for my little brain), but maybe you can use the
    `slot-missing` method?


    === Stefan
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Fri May 8 09:48:54 2026
    From Newsgroup: comp.lang.lisp

    * Stefan Monnier <jwvcxz7doj6.fsf-monnier+comp.lang.lisp@gnu.org> :
    Wrote on Thu, 07 May 2026 15:14:24 -0400:

    Apparently this only works on lispworks. all other lisps I tried fail at
    this step i.e. accessing the "virtual slot" slot-3, saying the slot does
    not exist.

    I'm not sure I understand the details of what you're looking for (I get
    the impression that your original example had typos that made it too confusing for my little brain), but maybe you can use the
    `slot-missing` method?

    Yes, I was able to replace all that slot-value-using-class machinery
    with slot-missing.

    (defclass foo ()
    ((slot-1 :initform 10 :initarg :slot-1)))

    (defmethod slot-missing ((class standard-class) (obj foo) slot operation
    &optional new-value)
    (let ((slot-name
    (etypecase slot
    (symbol slot)
    (ccl:standard-effective-slot-definition
    (ccl:slot-definition-name slot)))))
    (case slot-name
    (slot-2
    (ecase operation
    (setf (setf (slot-value obj 'slot-1) new-value))
    (slot-boundp (slot-boundp obj 'slot-1))
    (slot-makunbound (slot-makunbound obj 'slot-1))
    (slot-value (slot-value obj 'slot-1))))
    (slot-3
    (ecase operation
    (setf (setf (slot-value obj 'slot-1) new-value))
    (slot-boundp (slot-boundp obj 'slot-1))
    (slot-makunbound (slot-makunbound obj 'slot-1))
    (slot-value (slot-value obj 'slot-1))))
    (otherwise (call-next-method)))))


    This redirects or "forwards" slot-value operations on slot-3 and slot-2
    to slot-1.

    (setq $f (make-instance 'foo))
    (slot-value $f 'slot-1) ; 10
    (slot-value $f 'slot-2) ;10
    (setf (slot-value $f 'slot-3) 20) ;20

    I thought the only drawback is when slot-missing is signalled with the
    "setf" operation, that the spec specifies the setf operation doesn't
    return a value, but I think I misread it since it does
    --- Synchronet 3.22a-Linux NewsLink 1.2