Skip to content

Instantly share code, notes, and snippets.

@mfikes
Last active January 11, 2022 18:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mfikes/567c85c6473f2c4b511b to your computer and use it in GitHub Desktop.
Save mfikes/567c85c6473f2c4b511b to your computer and use it in GitHub Desktop.
Simplified ClojureScript macro :refers

This is a demo of investigation being done into further simplifying the use of macros in ClojureScript for the case when using a library namespace that offers a mix of functions and macros.

Here is an example:

src/foo/core.clj:

(ns foo.core)

(defmacro unless [pred a b]
  `(if (not ~pred) ~a ~b))

src/foo/core.cljs:

(ns foo.core
  (:require-macros foo.core))

(defn add [a b]
  (+ a b))

From an abstract point of view, foo.core provides add and unless, and it would be nice if you didn't have to explicitly be troubled with which is a macro vs. a function.

Here is an example of using this at a REPL:

$ java -cp cljs.jar:src clojure.main -m cljs.repl.node
ClojureScript Node.js REPL server listening on 56255
To quit, type: :cljs/quit
cljs.user=> (require 'foo.core)                        ;; Needed to work around an issue
nil
cljs.user=> (require '[foo.core :refer [add unless]])  ;; Note, we referred a fn and a macro!
nil
cljs.user=> (add 1 2)
3
cljs.user=> (unless true 3 4)
4
cljs.user=> (source add)
(defn add [a b]
  (+ a b))
nil
cljs.user=> (source unless)
(defmacro unless [pred a b]
  `(if (not ~pred) ~a ~b))
nil
cljs.user=> 

Here is the same working in a bootstrapped ClojureScript environment:

$ planck -c src
cljs.user=> (require 'foo.core)
nil
cljs.user=> (require '[foo.core :refer [add unless]])
nil
cljs.user=> (add 1 2)
3
cljs.user=> (unless true 3 4)
4
cljs.user=> 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment