lundi, septembre 8 2025

Type checking on Common Lisp Object System slots (updated)

In September I posted some code to add type checking to CLOS class slots that does not seem to be handled by LispWorks. The code below is simpler and was designed to run without errors and warnings with Steel Bank Common Lisp (SBCL). As the compiler directives show, most of the code is to make LispWorks behave like SBCL. Something to add, however, is having a warning or an error generated if a subclass of typed-slots, when defined with defclass, has slot types and initform values that do not match. 

(defclass typep-slots () ())

(defmethod typep-slot-value ((object typep-slots) (slot-name symbol))
  (slot-value object slot-name))

#+lispworks
(defun slot-type (standard-object slot-name)
  (let ((slot-definition (find slot-name (class-slots (class-of standard-object)) :key 'slot-definition-name)))
    (if slot-definition
        (slot-definition-type slot-definition)
      (error "Unknown slot name ~S in object ~S." slot-name standard-object))))

#+lispworks
(defmethod (setf typep-slot-value) (value (object typep-slots) (slot-name symbol))
  (if (typep value (slot-type object slot-name))
      (setf (slot-value object slot-name) value)
    (error "~S is not of type ~S for slot ~S in object ~S." 
           value (slot-type object slot-name) slot-name object)))
#+sbcl
(defmethod (setf typep-slot-value) (value (object typep-slots) (slot-name symbol))
  (setf (slot-value object slot-name) value))

(defun slots-macrolet (typep-slots-instance slot-names)
  (let (slots-macrolet)
    (dolist (slot-name slot-names slots-macrolet)
      (setf slots-macrolet 
            (append slots-macrolet
                    `((,slot-name (typep-slot-value ,typep-slots-instance (quote ,slot-name)))))))))
                  
(defmacro with-typep-slots ((&rest slot-names) typep-slots-instance &body body)
  (let ((objsym (gensym)))
    `(let ((,objsym ,typep-slots-instance))
       (declare (ignorable ,objsym))
       (symbol-macrolet ,(slots-macrolet objsym slot-names) ,@body))))

(defmethod initialize-instance :after ((object typep-slots) &rest initargs &key &allow-other-keys)
  (declare (ignore object initargs)))

#+lispworks
(defadvice ((method initialize-instance :after (typep-slots)) initialize-type-slots :after)
    (instance &rest initargs) 
  (declare (ignore initargs))
  (dolist (slot-definition (class-slots (class-of instance)) instance)
    (let* ((slot-name (slot-definition-name slot-definition))
           (type (slot-type instance slot-name))
           (boundp (slot-boundp instance slot-name)))
      (cond ((eq t type) t)
            ((and boundp (not (typep (slot-value instance slot-name) type)))
             (error "When initializing object, ~S is not of type ~S for slot ~S in object ~S." 
                    (slot-value instance slot-name) type slot-name instance))
            ((not boundp)
             (error "When initializing object, ~S is not of type ~S for slot ~S in object ~S." 
                    (make-condition 'unbound-slot) type slot-name instance))))))

;;; tests
(defclass test-type1 (typep-slots) ((a) (b :initform 'x :type symbol)))
(let ((instance (make-instance 'test-type1)))
  (with-typep-slots (a b) instance 
    (assert (setf a 23))
    (assert (setf a 'x))
    (assert (setf b 'y)))

  #+lispworks
  (progn 
    (assert (eq t (slot-type instance 'a)))
    (assert (eq 'symbol (slot-type instance 'b)))
    (assert (null (ignore-errors (setf (typep-slot-value instance 'b) 23)))))
  )

(defclass test-type2 (typep-slots) ((a :initarg :a) (b :initarg :b :type symbol) 
                                    (c :initarg :c :initform 'x :type symbol)))
#+lispwork
(assert (null (ignore-errors (make-instance 'test-type2 :c 23))))

(unintern 'test-type1)
(unintern 'test-type2)

dimanche, septembre 7 2025

Deuxième anniversaire

Début septembre 2025, c'est le deuxième anniversaire du blogue. Le moment se prête davantage au bilan qu'à la célébration. Je m'étais donné un objectif d'un billet par mois et j'accumule maintenant plusieurs mois de retard. Je redémarre le tout. Afin d’augmenter ma productivité, je compte rédiger de  […]

Lire la suite

samedi, mars 22 2025

Neuf mois d'apprentissage du piano

L'apprentissage d'un instrument de musique après un "certain" âge n'est pas toujours très rapide. Cependant, je suis relativement satisfait de mes progrès. Ce qui s'est révélé particulièrement difficile est l'apprentissage de pièce à partir de partition. Je dois avouer que mon objectif  […]

Lire la suite

jeudi, janvier 16 2025

Type checking on Common Lisp Object System slots

The Common Lisp standard specifies that "The consequences of attempting to store in a slot a value that does not satisfy the type of the slot are undefined.” CLHS: Macro DEFCLASS. However, type checking prevents making simple mistakes, makes code easier to understand, and ultimately leads to  […]

Lire la suite

vendredi, décembre 20 2024

Understanding the Complexity of Music Improvisation: Leveraging Cognitive Models to Inform Adaptive Instruction Design

Wolfgang Schoppek (University of Bayreuth, Germany) & Bruno Emond (2025). 7th International Conference on Adaptive Instructional Systems.  The study of adaptive instructional systems benefits from models that simulate complex cognitive and creative tasks. We present a model that simulates the  […]

Lire la suite

jeudi, septembre 12 2024

Comparing Visual Supports in Interactive Music Sheets: ACT-R Simulations for Piano Learning with Scaffold Fading

In progress (2025). 7th International Conference on Adaptive Instructional Systems.  Learning to play the piano is a cognitively demanding task that requires the integration of visual, auditory, and motor skills. Interactive music sheets have become a popular tool to aid in this process by offering  […]

Lire la suite

Simulated Learners as a Tool to Enhance Confidence in Learning Transfer for Marine Training Simulations

In progress.  Abstract for a presentation at the 2024 International Marine Simulation forum.  Effective skills transfer from maritime training simulations to real-world conditions is essential for ensuring mariner preparedness and safety. This presentation explores the use of simulated learners to  […]

Lire la suite

lundi, août 5 2024

Garmin en mode piano

Image

J'ai fait une découverte aujourd'hui. Comme la journée était grise et pluvieuse, j'ai passé une bonne partie de la journée à jouer du piano. Et bien, il semble que ma montre Garmin croit que je marche lorsque de joue du piano, un bon 5km à faire marcher mes doigts sur le clavier!    […]

Lire la suite

- page 1 de 4