> >
> > You can also use symbol-macros like CLOS does for instance variables.

;; compare how to access the instance variable in abbreviated form

;; first solution (standard) is unabbreviated
;; second solution (manually) does a manual encapsulation
;; third solution (pcl-style) defines a frontend macro


(defstruct foo
  a b c)

;; aux function, ignore
(defun do-some-fancy-stuff-with (p1 p2)
  (print (+ p1 p2)))

(defun standard (instance-of-foo)
  (do-some-fancy-stuff-with (foo-a instance-of-foo) (foo-b instance-of-foo))
  (print (+ (foo-a instance-of-foo) (foo-b instance-of-foo) 1)))

(defun manually (instance-of-foo)
  (symbol-macrolet ((a (foo-a instance-of-foo))
                    (b (foo-b instance-of-foo)))
    (do-some-fancy-stuff-with a b)
    (print (+ a b 2))))

;; And now for the nice stuff.
;; With best wishes to jrm - are you on this list?
(defmacro with-struct-abbrev ((varname structname &rest members) &rest body)
  (let (let-bindings)
    (dolist (member members)
      (push (list member
                  (list
                   (intern (format nil "~a-~a" structname member))
                   varname))
            let-bindings))
    `(let ,let-bindings
      ,@body)))

(defun pcl-style (instance-of-foo)
  (with-struct-abbrev (instance-of-foo foo a b)
    (do-some-fancy-stuff-with a b)
    (print (+ a b 3))))

(defun main ()
  (let ((instance-of-foo (make-foo :a 42 :b 43 :c 44)))
    (standard instance-of-foo)
    (manually instance-of-foo)
    (pcl-style instance-of-foo)))

Reply via email to