An object system for Arc.
(def make-meth (m) `(= (dispatch ',(m 0)) (fn ,(m 1) ,@(nthcdr 2 m))))
(def make-self (vars dispatch (o super '()))
(fn (meth . args)
(let v (dispatch meth) (if (isa v 'fn) (apply v args)
super (apply super (cons meth args))
(vars meth)))))
(mac class (spec . methods)
(withs (maker (coerce (string "make-" (string (spec 0))) 'sym)
super-maker (if (> (len spec) 1)
(coerce (string "make-" (string (spec 1))) 'sym)
'()))
`(do (def ,maker ()
(withs (dispatch (table)
super ,(if super-maker (list super-maker) '())
vars (table)
self (make-self vars dispatch super))
,(make-meth '(set (k v) (= (vars k) v)))
,@(map make-meth methods)
self)))))
Usage:
(class (person)
(first-name () (let v (vars 'first-name) (if v v "Jim")))
(last-name () (let v (vars 'last-name) (if v v "Rankin")))
(full-name () (string (self 'first-name) " " (self 'last-name))))
(class (employee person)
(salary () 100000))
(class (manager employee)
(salary () (* (super 'salary) 2))
(with-bonus (percent) (let s (self 'salary) (+ s (* s percent)))))
arc> (= p (make-person))
#<procedure>
arc> (p 'first-name)
"Jim"
arc> (p 'last-name)
"Rankin"
arc> (p 'full-name)
"Jim Rankin"
arc> (p 'set 'first-name "Paul")
"Paul"
arc> (p 'set 'last-name "Graham")
"Graham"
arc> (p 'full-name)
"Paul Graham"
arc> (= e (make-employee))
#<procedure>
arc> (e 'full-name)
"Jim Rankin"
arc> (e 'salary)
100000
arc> (= m (make-manager))
#<procedure>
arc> (m 'salary)
200000
arc> (m 'with-bonus 0.1)
220000.0
arc> (m 'with-bonus 0.2)
240000.0
arc> (m 'with-bonus 0.5)
300000.0
Basically, objects are hash tables with attached methods and inheritance. Use ‘set method to put values into the table. If there is no method with the same name, “sending” the key to the object will return the set value. I would like to override =, but haven’t figured that out yet. Can think of lots of other things to add, but this is a good start. I imagine there are a lot of buggy cases, too; I haven’t thoroughly tested.
A rudimentary object system in 21 lines of code. I would say this reflects well on the ability to write short programs in Arc.