3 ms·
For your particular example, it seems you could use a dataflow approach, like the one in Cells (K. Tilton) (see tutorial: http://stefano.dissegna.me/cells-tuto
by junke 6y ago
For your particular example, it seems you could use a dataflow approach, like the one in Cells (K. Tilton)
(see tutorial: http://stefano.dissegna.me/cells-tutorial.html http://stefano.dissegna.me/cells-tutorial.html, and documentation: https://gitlab.common-lisp.net/cells/cells/-/tree/master/doc https://gitlab.common-lisp.net/cells/cells/-/tree/master/doc)
(ql:quickload :cells)
(defpackage :robot (:use :cl :cells))
(in-package :robot)
Define a robot model (class) where command in an input, and velocity is defined by an update rule:
(defmodel robot ()
((command :accessor command :initform (c-in nil))
(velocity :initform (c? (case (command self)
(:left -10)
(:right 10)
(t 0))))))
Whenever command is modified, velocity is updated accordingly. You can add observers for slot changes:
(defun log-change (what from to)
(print `(:change ,what :from ,from :to ,to)
*debug-io*))
(defobserver velocity ((model robot) new old boundp)
(when boundp
(log-change `(velocity ,model) old new)))
Then, if you instanciate the model, and mutate the command slot:
(let ((w (make-instance 'robot)))
(setf (command w) :right)
(setf (command w) :left)
(setf (command w) nil))
The following is logged:
(:CHANGE (VELOCITY #<ROBOT {1015D66783}>) :FROM 0 :TO 10)
(:CHANGE (VELOCITY #<ROBOT {1015D66783}>) :FROM 10 :TO -10)
(:CHANGE (VELOCITY #<ROBOT {1015D66783}>) :FROM -10 :TO 0)
Anyway, the book Common Lisp Recipes (E. Weitz) is good for solving actual, pratical problems with Lisp.