@@ 366,7 366,8 @@
(def- raise-sentinel (gensym))
(defn- defgeneric*
- [name args & body]
+ [name docstring args & body]
+ (default docstring "Generic function.")
(with-syms [wrapper-args]
(let [err-msg (string/format
"could not apply generic %s to args %%q"
@@ 378,7 379,7 @@
,wrapper-args)
~(fn ,args ,;body))]
~(defn ,name
- "Generic function."
+ ,docstring
[& ,wrapper-args]
(match (,first ,wrapper-args)
({,method-name f} (function? f)) (f ;,wrapper-args)
@@ 391,9 392,16 @@
function, call that object 's method with the arguments. Otherwise,
evaluate `body`.
```
- [name args &opt body]
- (default body raise-sentinel)
- (defgeneric* name args body))
+ [name & rest]
+ (let [[docstring args body]
+ (if (string? (first rest))
+ [(rest 0)
+ (rest 1)
+ (array/slice rest 2)]
+ [nil
+ (rest 0)
+ (array/slice rest 1)])]
+ (defgeneric* name docstring args ;(if (empty? body) [raise-sentinel] body))))
(defmacro defmethod
```
@@ 414,7 422,7 @@
(let [current-binding (dyn name)]
@[(unless (and current-binding (function? (current-binding :value)))
(print "Defining generic function for method " name "...")
- (defgeneric* name args raise-sentinel))
+ (defgeneric* name nil args raise-sentinel))
(let [method-name (keyword name)
full-method-name (symbol proto "-" name)]
@@ 205,6 205,15 @@
(is (= "hi!" (shout "hi")))
(is (= "Fido!" (shout shouting-Dog)))))
+(fugue/defgeneric informative-function
+ "gives you useful information"
+ [x]
+ (+ x 1))
+
+(deftest generic-docstrings
+ (is (= 2 (informative-function 1)))
+ (is (string/has-suffix? "gives you useful information" ((dyn 'informative-function) :doc))))
+
(fugue/defmethod speak Dog [self] (string "My name is " (self :name)))
(fugue/defmethod speak Pekingese [self] (string (__super self) " and I am " (self :size)))