Skip to main content
2 of 2
Typo
Toby Speight
  • 81.8k
  • 14
  • 101
  • 309

It's unusual to defun within a function. If you just want expat available while executing expand-pattern, you should use use letrec:

(defun expand-pattern (pattern)
  (letrec ((expat (lambda (parents expr)
                    (pcase expr
                      ((or (pred stringp)
                           (pred numberp))   (mapcar (lambda (parent)
                                                       (cons expr parent))
                           parents))
                      (`(and ,first)         (funcall expat parents first))
                      (`(and ,first . ,rest) (funcall expat (funcall expat parents first)
                                                      (cons 'and rest)))
                      (`(or . ,args)         (apply #'append 
                                                    (mapcar (lambda (arg)
                                                              (funcall expat parents arg))
                                                            args)))
                      (_                     (error "unknown %S" expr))))))
    (mapcar (lambda (tokens)
              (mapconcat (lambda (token)
                           (format "%s" token))
                         (reverse tokens)
                         ""))
            (funcall expat '(()) pattern))))

This way, the binding of expat doesn't live beyond the function.

It looks like what you're doing is a 'reduce' type of operation - you may find it worthwhile to look into cl-reduce and related functions.

Toby Speight
  • 81.8k
  • 14
  • 101
  • 309