Need help with macrovich?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

cgrand
154 Stars 6 Forks Eclipse Public License 1.0 17 Commits 5 Opened issues

Description

A set of three macros to ease writing `*.cljc` supporting Clojure, Clojurescript and self-hosted Clojurescript.

Services available

!
?

Need anything else?

Contributors list

# 68,564
Clojure
repl
Apache ...
Clojure...
15 commits
# 55,437
Clojure
Clojure...
clojure...
Objecti...
1 commit
# 117,231
Clojure
Clojure...
repl
cljs
1 commit

Macrovich

Because any macros problem can be solved by another level of macros, Macrovich is a set of four macros to ease writing

*.cljc
supporting Clojure, Clojurescript and self-hosted Clojurescript. (Especially when porting Clojure codebases where macros are not segregated.)

Excerpt from Being John Macrovich script:

Girl Macrovich
Macrovich Macrovich Macrovich Macrovich...
(Macrovich looks confused. The Macrovich waiter approaches, pen and pad in hand, ready to take their orders.)
Waiter Macrovich
Macrovich Macrovich Macrovich?
Girl Macrovich
Macrovich Macrovich Macrovich Macrovich.
Waiter Macrovich
Macrovich Macrovich. (Turning to Macrovich) Macrovich?

Usage

Clojurescript >= 1.9.293 is required. This means Planck 2.0.0 or later is required. Lumo 1.0.0 is ok.

Add

[net.cgrand/macrovich "0.2.1"]
to your dependencies.

Macrovich exposes four macros:

  • macros/deftime
    and
    macros/usetime
    to clearly demarcate regions of code that should be run in the macro-definition stage or in the macro-usage stage. (In Clojure there's no distinction; in pure Clojurescript it's easy: just wrap the first stage in
    #?(:clj ...)
    and the latter one in
    #?(:cljs ...)
    ; in self-hosted Clojurescript it's messy or everything gets evaluated twice; supporting the three at the same time is Macrovich's raison d'être.)
  • macros/case
    is a macro to use instead of reader conditionals in macros or macros-supporting fns. This solves a problem with regular Clojurescript where macros are Clojure code and thus are read by taking the
    :clj
    branch of conditionals. So
    macros/case
    is like reader conditionals except the branch is picked at expansion time and not at definition time.
  • macros/replace
    is a macro to avoid repeating similar reader conditionals, see https://github.com/cgrand/xforms/blob/d4f0280bb50d8cc53c3a5dfe24b17fe7701b4e43/src/net/cgrand/xforms.cljc#L276 for an example.

Sample

Below is a sample

being/john.cljc
file:
(ns being.john
  #?(:clj
     (:require [net.cgrand.macrovich :as macros])
     :cljs
     (:require-macros [net.cgrand.macrovich :as macros]
        [being.john :refer [add]]))) ; cljs must self refer macros

(macros/deftime ; anything inside a deftime block will only appear at the macro compilation stage.

(defmacro add [a b] `(+ ~a ~b)))

(macros/usetime ; anything inside a usetime block will not appear at the macro compilation stage.

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

; anything outside these block is always visible as usual

case
allows to select which form to emit in a macro based on the target language rather than the macro language. Consider these two macros:
(defmacro broken []
  #?(:clj "clojure" :cljs "clojurescript"))

(defmacro correct [] (macros/case :clj "clojure" :cljs "clojurescript"))

; or (defmacro correct [] `(macros/case :clj "clojure" :cljs "clojurescript")) ; this works too, so no need to unquote in the middle of a syntax quotation and mess with gensyms

In regular (Clojure-hosted) Clojurescript

(broken)
expands to
"clojure"
while
(correct)
expands to
"clojurescript"
.

Example

The xforms lib has been converted to cljc:

  • https://github.com/cgrand/xforms/blob/cljc/src/net/cgrand/xforms.cljc
  • https://github.com/cgrand/xforms/blob/cljc/src/net/cgrand/xforms/rfs.cljc
  • https://github.com/cgrand/xforms/blob/cljc/test/net/cgrand/xforms_test.clj

License

Copyright © 2016-2017 Christophe Grand

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.