I would like to define my own reader macro in clojure:
(read-string "ßfoo")
=> (some_func :foo)
Is it possible?
It is possible to create tagged literals by having a reader map in data_readers.clj at the top of your classpath.
This must be in data_readers.clj at the top of your classpath (usually src directory).
{ß reader-demo.core/read-fn}
This goes into reader-demo.core
(defn some-func
[arg]
(str "some-func invoked with " arg))
(defn read-fn
[arg]
(-> arg
keyword
some-func))
Invoking
#ß foo
will return
"some-func invoked with :foo"
This technique is described here: The reader: Tagged literals
Notice that in practice you should namespace your tagged literals as all non-namespaced ones are reserved for Clojure itself.
Currently, Clojure doesn't allow to create user defined reader macros. This might/might not change in the future.
Related
Not sure if valid question, but i'm learning macros and i'm trying to write a macro (for clojurescript but should be same thing) so i can do nicer js/require in node.
The syntax will look like this:
(import ["some-module" :as module1]
["some-other-module" :as module2])
and it would expand to this:
(do
(def module1 (js/require "some-module")
(def module2 (js/require "some-module"))
My question is:
Is it ok to do 'def' inside a do block?
cljs does not seem to complain, but is it ok from a macro design stand point?
Yes, using the (do (def ...) (def ...)) pattern is generally the only way to def multiple things in a macroexpansion.
I'm searching a way to keep my helpers functions to the bottom of the file, without declare them all at the top.
One solution should be to write a "declare-helpers" function that grab the names of all functions create via defn- macro in the current file and wrap them in a declare call.
Here I'm asking about the better way to grab those names.
* edit *
I know this is bad practice but, the following code seems to do what I want
Note that it apply only to helpers function define with the "dehfn" macro
;define helper function
(defmacro dehfn [name & body]
`(defn- ~name ~#body))
(defmacro declare-helpers []
`(declare ~#(map symbol
(re-seq #"(?<=dehfn\s)[a-zA-Z+!\-_?0-9*~##''`/.$=]*(?=\s)"
(slurp (str "src/" *file*))))))
Now you can do that:
(declare-helpers)
(defn hello-user [name] (greet name))
(dehfn greet [name] (str "Hello my dear " name))
This is not possible. No macro can know about code written later in the file than the macro invocation, since there are no vars for it to inspect yet. Just practice reading files "upside down": Clojure is not the only language in which the public and/or important stuff is often at the bottom.
I have been looking at the source for defmacro which uses "let" in its definition:
(def
^{:doc "Like defn, but the resulting function name is declared as a
macro and will be used as a macro by the compiler when it is
called."
:arglists '([name doc-string? attr-map? [params*] body]
[name doc-string? attr-map? ([params*] body)+ attr-map?])
:added "1.0"}
defmacro (fn [&form &env
name & args]
(let [prefix (loop [p (list name) args args]
However, "let" is defined as a macro itself:
(defmacro let
"binding => binding-form init-expr
Evaluates the exprs in a lexical context in which the symbols in
the binding-forms are bound to their respective init-exprs or parts
therein."
{:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]}
[bindings & body]
(assert-args
(vector? bindings) "a vector for its binding"
(even? (count bindings)) "an even number of forms in binding vector")
`(let* ~(destructure bindings) ~#body))
Can someone explain how this works as I can't understand how "defmacro" can be defined in terms of things which need "defmacro" to already be defined. (if that makes sense :)
This is possible because before defining defmacro function in core.clj there is already a definition of let at this location (which gets redefined later). Macros are just normal functions and the var they are bound to has meta data key :macro with value true so that at compile time the compiler can differentiate between a macro (which execute at compile time) with a function, without this meta key there is no way to differentiate between a macro and a function because macro itself is a function that happens to process S-expressions.
recusrive macros work fine and occur in many place in both the clojure language core and in other programs. macros are just functions that return S-Expressions, so they can be recursive just as functions can. In the case of let in your example it's actually caling let* which is a different function (its fine to have * in a functions name), so although recursive macros are fine, this doesn't happen to be an example of them
I was reading Clojure in Action chapter 8 about TDD and experimented with the stubbing macro. It uses the dynamic binding mechanism to stub functions. Alas, in Clojure 1.3 it is not possible to use the binding mechanism for non-dynamic vars, so the stubbing macro doesn't work in most cases, unless you explicitly declare the var which points to a function dynamic. Then I wondered how stubbing is done in Midje and tried to find the source for 'provided', but I couldn't find it. So here it goes:
How is 'provided' implemented in a fact in Midje? Can someone explain this in detail?
Clojure 1.3 provides a with-redefs macro that works even with vars that haven't been declared dynamic:
user=> (def this-is-not-dynamic)
user=> (with-redefs [this-is-not-dynamic 900] this-is-not-dynamic)
900
For backward compatibility, Midje uses its own version, whose guts look like this:
(defn alter-one-root [[variable new-value]]
(if (bound? variable)
(let [old-value (deref variable)]
(alter-var-root variable (fn [current-value] new-value))
[variable old-value])
(do
(.bindRoot variable new-value)
[variable unbound-marker])))
On a particular namespace I am working on I am beginning to run out of function names. Is there a way to get a warning like the one I get if I override a symbol from another namespace if I reuse a symbol which is already bound to a function in the same namespace?
If this is enough of a problem that you'd be willing to replace a (set of) core macro(s), you could try this approach:
(ns huge.core
(:refer-clojure :exclude [defn]))
(defmacro defn [name & defn-tail]
(assert (nil? (resolve name))
(str "Attempting to redefine already defined Var "
"#'" (.name *ns*) "/" name))
`(clojure.core/defn ~name ~#defn-tail))
Then any attempt to redefine an existing Var with defn will fail:
user=> (defn foo [] :foo)
#'user/foo
user=> (defn foo [] :bar)
AssertionError Assert failed: Attempting to redefine already defined Var #'user/foo
(nil? (resolve name)) user/defn (NO_SOURCE_FILE:2)
You could similarly replace defmacro; in that case you would have to call clojure.core/defmacro when defining your own variant.
Plain, unadorned def is a special form and receives magic treatment from the compiler, so you could still overwrite existing Vars with it. If you would like to guard against name clashes on that flank too, you could switch to something like defvar (used to be available in clojure.contrib.def) with a similar custom assert.
This isn't quite an answer to your question but may help avoid the issue depending on how the functions in your namespace are being used. You could make them into local functions using letfn, allowing you to reuse names for functions that are only used within the context of another function.
(defn main-fn [x]
(letfn [(secondary-fn [x] (* x x))
(another-fn [x] (secondary-fn (inc x)))]
(/ (another-fn x) 4)))
Even if you restrict yourself to single-character function names, you are in no danger of running out, as there are (about) 64 thousand Unicode characters, any one of which is a valid function name.
Given that you can in fact have names that are ten thousand characters long, you are on even safer ground.