noprompt / meander

Tools for transparent data transformation
MIT License
921 stars 55 forks source link

Syntax Extensions must be qualified when using in another ns #145

Closed lucywang000 closed 3 years ago

lucywang000 commented 3 years ago

I was debugging some code that involves custom defsyntax, just to find that the culprit is, if I have a custom syntax foo-syntax defined in ns foo, and want to use it in bar, I have to always use foo/foo-syntax (or foo-alias/foo-syntax if I'm aliasing the foo ns name), even if I have :require [foo :refer [foo-syntax]] in bar's ns declaration.

Is this expected behavior? If so we shall document it explicitly.

foo.clj

(ns foo
  (:require [meander.epsilon :as me]))

(me/defsyntax gen-map
  "Shorthand for the map spread syntax

   (gen-map !k !v) would expand to:

   {& ([!k !v] ...)}

   (me/rewrite [1 2 3 4]
   [!xs !ys ...]
   (gen-map !xs !ys))
   ;; => {1 2, 3 4}"
  [!k !v]
  `{~'& ([~!k ~!v] ~'...)})

bar.clj

(ns bar
  (:require [meander.epsilon :as me]
            [foo :refer [gen-map]]))

(me/rewrite [1 2 3 4]
  [!xs !ys ...]
  (gen-map !xs !ys))
;; => (gen-map 1 2)

(me/rewrite [1 2 3 4]
  [!xs !ys ...]
  (foo/gen-map !xs !ys))
;; => {1 2, 3 4}

(me/rewrite [1 2 3 4]
  [!xs !ys ...]
  (~gen-map !xs !ys))
;; => (#function[foo/gen-map] 1 2)
noprompt commented 3 years ago

@lucywang000 The symbol resolution for syntax extensions relies on meander.util.epsilon/expand-symbol. I think the Clojure resolution could probably be changed to use clojure.core/resolve and then get the symbol from the var if it exists, otherwise leave the symbol untouched. I'm a little busy at the moment and won't be able to look at this until later today. If you're able to find a patch, don't hesitate to open a pull request.

lucywang000 commented 3 years ago

the Clojure resolution could probably be changed to use clojure.core/resolve and then get the symbol from the var if it exists, otherwise leave the symbol untouched.

That sounds brilliant! what about the cljs side? Is there a way to check whether a symbol has an alias in the current ns?

noprompt commented 3 years ago

@lucywang000 I've patched this and will now make a release. See #146 for the code details.