Lisp Programming Trick #2

December 22, 2008

Recursive Condition

This little trick hit me when I was perusing PCL. Specifically, the when selector.

(defun rec-cond (key)
  (cond
    ((eq key :before) (format nil "executing before" ))
    ((eq key :during) (format nil "executing during" ))
    ((eq key :after) (format nil "executing after" ))

    ((eq key :set-up) (rec-cond :before))
    ((eq key :init) (rec-cond :before))

    ((eq key :teardown) (rec-cond :after))

    (t (error (format nil "unknown command: ~A" key))))

This overloads keyword symbols so that you more than one keyword can execute the same code. Read the rest of this entry »

Advertisements

Lisp Programming Trick #1

December 7, 2008

Getter/Setters

How many times have you created two function for setting a specific value and then getting the value?

(let ((value ""))
  (defun property (&key is)
    (cond
      (is (setf value is))
      (t value)))
  ;;; here is getter and setter functions
  (defun get-property ()
    value)
  (defun set-property (data)
    (setf value data)))

(define-test get_set-property
  (assert-equal "" (get-property))
  (assert-equal "property" (set-property "property"))
  (assert-equal "property" (get-property))
  (assert-equal "" (set-property "")))

(define-test property
  (assert-equal "" (property))
  (assert-equal "property" (property :is "property"))
  (assert-equal "property" (property))
  (assert-equal "" (property :is ""))

Using a &key keyword parameter adds syntatic sugar to setting properties. It also means less typing.

It is done with a conditional. Another benefit is that behavior for the property is located in only one function instead of two functions.

New Use Case

(Zach Beane’s Request)

Need to be able to set the property to nil. Added the test to my unit tests. It failed. Modified the code and now it passes.

You just need to add a supplied-p parameter.

(let ((value ""))
  (defun property (&key (is nil is-p))
    (cond
      (is-p (setf value is))
      (t value))))

(define-test property
  (assert-equal "" (property))
  (assert-equal "property" (property :is "property"))
  (assert-equal "property" (property))
  (assert-equal "" (property :is ""))
  (assert-equal nil (property :is nil)))

Happy Lisp Cargo-Culting!