| This is a reasonably simple abstraction over the common task of using redef to extend already-existing methods to accept new types. It's the same idea as generic methods: you specify types for one or more arguments, and your new function (rather than the old definition) is called if those types are given. The syntax is similar to optional arguments: (t arg typename). Here's the code (it's also in lib/defm.arc on Anarki): (def argmap (symf annf args)
(map (afn (arg)
(if (isa arg 'sym) (symf arg)
(atom (cadr arg)) (annf arg)
(annf `(,(car arg) ,(self (cadr arg)) ,@(cddr arg)))))
args))
(mac defm (name args . body)
`(redef ,name ,(argmap idfn [if (is (car _) 't) (cadr _) _]
args)
(if (and ,@(map (fn (decl) `(isa ,(car decl) ',(cadr decl)))
(trues (argmap [idfn nil]
[if (is (car _) 't) (cdr _) (cadr _)]
args))))
(do ,@body)
(old ,@(argmap idfn [cadr _] args)))))
As an example, here's last defined to work on strings: (defm last ((t str string))
(str (- (len str) 1)))
|