guicho271828 / trivia

Pattern Matcher Compatible with Optima
Other
335 stars 22 forks source link

Feature request: docstring support for `defun-match` #66

Closed sjl closed 7 years ago

sjl commented 7 years ago

It would be nice if defun-match could optionally take a docstring and pass it along into the underlying defun. Right now it tries to parse the string as a match clause and errors.

According to the docs the clauses in the body are always lists, so it should be possible to distinguish a bare string and treat it separately.

If this is something you're interested in I can make a PR for it.

guicho271828 commented 7 years ago

Nice point, please send a PR.

PuercoPop commented 7 years ago

@guicho271828 So defun-match would look something like this

(defmacro defun-match (name (arg) &body clauses)
  (multiple-value-bind (clauses declarations docstring)
      (parse-body clauses :documentation t)
    `(defun ,name (,arg)
       ,@(when docstring
           (list docstring))
       ,@declarations
       (match ,arg
         ,@clauses))))

The repetition in the definitions of defun-* point to a macrolet to reduce the code repetition, what do you think?

guicho271828 commented 7 years ago

A function is better, since it works inside the macro definition and is traceable. Easier to debug, too.

guicho271828 commented 7 years ago

*compared to macrolet

sjl commented 7 years ago

The macrolet style would be concise, but does get a bit hairy because you need to handle the different arglists for the vanilla/* versions:

(macrolet ((define-matcher (macro-name macro-arglist matcher-arglist matcher matcher-form)
             `(defmacro ,macro-name (name ,macro-arglist &body body)
               (multiple-value-bind (clauses declarations docstring)
                   (parse-body body :documentation t)
                 `(defun ,name ,,matcher-arglist
                   ,@(when docstring `(,docstring))
                   ,@declarations
                   (,',matcher ,,matcher-form ,@clauses))))))
  (define-matcher defun-match (arg) (list arg) match arg)
  (define-matcher defun-ematch (arg) (list arg) ematch arg)
  (define-matcher defun-cmatch (arg) (list arg) cmatch arg)
  (define-matcher defun-match* args args match* args)
  (define-matcher defun-ematch* args args ematch* args)
  (define-matcher defun-cmatch* args args cmatch* args))
guicho271828 commented 7 years ago

send me a pr anyways

guicho271828 commented 7 years ago

thanks for your work