Samstag, August 19, 2006

Closures in Common Lisp

Martin Fowler published an online article about closures. He used the Ruby programming language for the examples. There are translations of the examples to Python and a language called Boo.

As a programming task for myself I did the examples in Common Lisp, which supported Closured already decades ago. A real lisper might be able to write the code in a more elegant way but I think the principle should become clear.

I didn't use the Common Lisp Object System (CLOS) since for this simple example an ad-hoc modeling with hashes is simpler.


;; Ruby
; def managers(emps)
; return emps.select {|e| e.isManager}
; end

;; Common Lisp
(defun is-manager (emp) (getf emp :is-manager))

(defun managers (emps)
(remove-if-not (lambda (emp)
(when (is-manager emp) emp))
emps))


;; Ruby
; def highPaid(emps)
; threshold = 150
; return emps.select {|e| e.salary > threshold}
; end

;; Common Lisp
(defun high-paid (emps)
(let ((threshold 150))
(remove-if-not (lambda (emp)
(when (> (getf emp :salary) threshold) emp))
emps)))


;; Ruby
; def paidMore(amount)
; return Proc.new {|e| e.salary > amount}
; end

;; Common Lisp
(defun paid-more (amount)
(lambda (emp) (when (> (getf emp :salary) amount) emp)))

;; Ruby
; highPaid = paidMore(150)
; john = Employee.new
; john.salary = 200
; print highPaid.call(john)

;; Common Lisp
(let ((high-paid (paid-more 150))
(john '(:name John :is-manager nil :salary 200)))
(princ (funcall high-paid john)))


;; Tests
(defparameter manager-list
'((:name Stefan :is-manager nil :salary 150)
(:name Henning :is-manager t :salary 151)
(:name Martin :is-manager nil :salary 120)
(:name Christian :is-manager t :salary 200)))

(princ #\newline)
(princ "Test function managers")
(princ #\newline)
(princ (managers manager-list))
(princ #\newline)

(princ #\newline)
(princ "Test function high-paid")
(princ #\newline)
(princ (high-paid manager-list))
(princ #\newline)

Post bewerten

Keine Kommentare: