~subsetpark/fugue

1ee8fca58470dbaa8f9d85ff635b9fb1875855c2 — Zach Smith 2 months ago 9c7f430
Docstrings in defgeneric
2 files changed, 23 insertions(+), 6 deletions(-)

M fugue.janet
M test/fugue.janet
M fugue.janet => fugue.janet +14 -6
@@ 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)]

M test/fugue.janet => test/fugue.janet +9 -0
@@ 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)))