Regarding 2: The article punts on the question of how to implement such a system, because I think it's a hard question. I could have been clearer about that, and maybe in future I'll write an article speculating on some ways one could approach the problem. But I think it's an underappreciated problem, and I hope this article will spur other people to consider it.
Re 1:
In a.clj:
(ns a (:refer-clojure))
(defmulti if-match*
(fn [pat _ _ _] (if (list? pat) (first pat) (type pat))))
(defmacro if-match [pat expr then else]
(if-match* pat expr then else))
(defmethod if-match* clojure.lang.Symbol
[pat expr then else]
`(let [~pat ~expr] ~then))
In b.clj:
(ns b (:refer-clojure) (:require a))
;; a 'foo pattern-macro that does negation
(defmethod a/if-match* 'foo [pat expr then else]
`(a/if-match ~(second pat) ~expr ~else ~then))
In c.clj:
(ns c (:refer-clojure) (:require a))
;; a 'foo pattern-macro that is the identity pattern
(defmethod a/if-match* 'foo [pat expr then else]
`(a/if-match ~(second pat) ~expr ~then ~else))
Now, at the repl:
user=> (use 'a)
nil
user=> (require 'b)
nil
user=> (if-match (foo x) 'yes x 'no)
no
user=> (require 'c)
nil
user=> (if-match (foo x) 'yes x 'no)
yes
Note that 'require doesn't actually import the symbols defined by b.clj or c.clj, and despite that we're able to use the pattern-macro 'foo they define, because they're modifying if-match's dispatch-table. So our pattern-macros aren't being scoped the same way our regular macros are. I think this is wrong. Moreover, our pattern-macros have a single namespace, so we get collisions between what b.clj defines 'foo to mean and what c.clj defines it to mean, which is why (if-match (foo x) 'yes x 'no) changes behavior after the (require 'c).
Re 1:
In a.clj:
In b.clj: In c.clj: Now, at the repl: Note that 'require doesn't actually import the symbols defined by b.clj or c.clj, and despite that we're able to use the pattern-macro 'foo they define, because they're modifying if-match's dispatch-table. So our pattern-macros aren't being scoped the same way our regular macros are. I think this is wrong. Moreover, our pattern-macros have a single namespace, so we get collisions between what b.clj defines 'foo to mean and what c.clj defines it to mean, which is why (if-match (foo x) 'yes x 'no) changes behavior after the (require 'c).