What does this "#" mean in this Clojure context? - clojure

I stumbled upon the official Om example under "examples/mixins", there's a definition as this:
(def MyComponent (let [obj (om/specify-state-methods! (clj->js om/pure-methods))]
(aset obj "mixins" #js [TestMixin])
(js/React.createClass obj)))
What does "#js" mean? I couldn't find any Clojure documentation on symbol "#" when it's used in this way.

From the Om tutorial:
#js {...} and #js [...] is what is referred to as a reader literal. ClojureScript supports data literals for JavaScript via #js. #js {...} is for JavaScript objects:
#js {:foo "bar"} ;; is equivalent to
#js {"foo" "bar"}

First of all Om is a Clojurescript library. There are some differences between Clojure and Clojurescript, they are documented here.
#js is called a tagged literal, that comes from edn, basically a tagged literal tells the reader how to parse the data, in the case of #js it tells the reader to parse the data as a Javascript object. Take a look here for more information.

All dispatch reader macros begin with #. When you see this it means something special will happen at the moment the code is read, and that is no different with #js than with #( or #_ or even #{ for sets. In this case it tells the reader that what follows is a JavaScript literal.
More here: http://clojure.org/reader#The%20Reader--Macro%20characters

Related

Clojure evaluating string variable as a symbol, is this use of read-string okay?

I can use memfn to create a clojure function that invokes a java function.
(macroexpand '(memfn startsWith prefix))
=> (fn* ([target2780 prefix] (. target2780 (startsWith prefix))))
((memfn startsWith prefix) "abc" "a")
=> true
memfn requires that the function name be a symbol. I'm wondering if I can write a macro to invoke an arbitrary method whose name is provided as a string. That is, I'd like to be able to invoke the following:
(def fn-name "startsWith")
=> #'user/fn-name
(macroexpand '(memfn' fn-name "prefix"))
=> (fn* ([target2780 prefix] (. target2780 (startsWith prefix))))
((memfn fn-name "prefix") "abc" "a")
=> true
The only way I can think to do this involves using read-string.
(defmacro memfn' [fn-name arg-name]
`(memfn ~(read-string fn-name) ~arg-name))
Edit: A version using read-string and eval that actually works the way I want it to.
(defn memfn' [fn-name arg-name]
(eval (read-string (str "(memfn " fn-name " " arg-name ")"))))
Am I missing a fundamental macro building tool to take the string that a symbol references and turn it into a literal without potentially executing code, as read-string might?
Thanks for any ideas!
There's no way to do this, with or without read-string. Your proposed solution doesn't work. The distinction you're really trying to make is not between string and symbol, but between runtime data and compile-time literals. Macros do not evaluate the arguments they receive, so even if fn-name is the name of a var whose value is "startsWith", memfn (or your memfn' macro) will only ever see fn-name.
If you are interested in calling java methods only then you can rely on java.lang.reflect.Method and its invoke method.
Something like this should work for parameterless methods and would not require a macro.
(defn memfn' [m]
(fn [o] (.invoke (.getMethod (-> o .getClass) m nil) o nil)))
((memfn' "length") "clojure")
;=>7

How can I iterate over a list with a macro?

I am trying to print the documentation for all functions in a given namespace by invoking the following expression in a REPL:
(doseq
[f (dir-fn 'clojure.repl)]
(doc f))
However the invocation of this expression returns nil without printing the documentation to the REPL. I know this might have to do with doc being a macro, but I'm a Clojure novice and am not entirely sure how to understand the problem.
Why does this expression return nil without printing the documentation?
How can this expression be modified so that it prints the documentation for each function in a given namespace?
Thanks!
Update: Combined both provided answers:
(defn ns-docs [ns']
(doseq [[symbol var] (ns-interns ns')]
(newline)
(println symbol)
(print " ")
(println (:doc (meta var)))))
(ns-docs 'clojure.repl)
I would, instead, start here:
The Clojure CheatSheet
ClojureDocs.org
Clojure-Doc.org (similar name, but different)
The API & Reference sections at Clojure.org
Note that doc is in the namespace clojure.repl, which reflects its intended usage (by a human in a repl). Here is some code that will also iterate on a namespace & print doc strings (using a different technique):
(doseq [[fn-symbol fn-var] (ns-interns 'demo.core)]
(newline)
(println fn-symbol)
(println (:doc (meta fn-var))))
where demo.core is the namespace of interest.
Note that ns-interns gives you both a symbol and var like:
fn-symbol => <#clojure.lang.Symbol -main>
fn-var => <#clojure.lang.Var #'demo.core/-main>
The meta function has lots of other info you may want to use someday:
(meta fn-var) =>
<#clojure.lang.PersistentArrayMap
{ :arglists ([& args]),
:doc "The Main Man!",
:line 9, :column 1,
:file "demo/core.clj",
:name -main,
:ns #object[clojure.lang.Namespace 0x14c35a06 "demo.core"]}>
While this probably won't help you with answering your question, the problem of evaluating macro's comes up a lot when you are learning Clojure.
Macros are responsible for the evaluation of their arguments. In this case clojure.repl/doc will ignore the current lexical context and assume that the symbol f that you're giving it is the name of a function you want to see the documentation for. It does this because it's intended to be used at the REPL, and is assuming you wouldn't want to type quotes all the time.
As f doesn't exist, it prints nothing. Then doseq returns nil, since it exists to do something for side effects only - hence starting in do. In order to pass an argument to a macro that refuses to respect the lexical context like this, you need to write the code for each element in the list.
You can do this by hand, or by constructing the code as data, and passing it to eval to execute. You can do this in an imperative style, using doseq:
(doseq [f (ns-interns 'clojure.repl)]
(eval `(doc ~(symbol "clojure.repl" (str (first f))))))
or in a slightly more Clojurey way (which will allow you to see the code that it would execute by removing eval from the end and running it at the REPL):
(->> (ns-interns 'clojure.repl)
(map #(list 'clojure.repl/doc (symbol "clojure.repl" (str (first %)))))
(cons `do)
eval)
In both of these we use quote and syntax-quote to construct some code from the list of symbols reflected from the namespace, and pass it to eval to actually execute it. This page on Clojure's weird characters should point you in the right direction for understanding what's going on here.
This an example of why you shouldn't write macro's, unless you've got no other options. Macro's do not compose, and are often difficult to work with. For a more in depth discussion, Fogus's talk and Christophe Grand's talk are both good talks.
Why does this expression return nil without printing the documentation?
Because the doc macro is receiving the symbol f from your loop, instead of a function symbol directly.
How can this expression be modified so that it prints the documentation for each function in a given namespace?
(defn ns-docs [ns']
(let [metas (->> (ns-interns ns') (vals) (map meta) (sort-by :name))]
(for [m metas :when (:doc m)] ;; you could filter here if you want fns only
(select-keys m [:name :doc]))))
(ns-docs 'clojure.repl)
=>
({:name apropos,
:doc "Given a regular expression or stringable thing, return a seq of all
public definitions in all currently-loaded namespaces that match the
str-or-pattern."}
...
)
Then you can print those maps/strings if you want.

What are all of clojure's special forms?

As part of improving Cider's debugger, I need to implement special handling for all possible special-forms. In order words, I need to know all symbols which satisfy special-symbol?.
The doc page on Special Forms, while helpful, doesn't offer all of them.
For instance, after some experimentation, I've learned that
Most of the forms listed there have a * counterpart (let* and loop*, for instance).
There is a clojure.core/import* special-symbol (which I wouldn't have found if not for sheer luck).
Is there a complete list of all special symbols?
Alternatively, is there a way to list all interned symbols? If so, then I could filter over special-symbol?.
Looking at the definition of special-symbol? provides a big clue:
(defn special-symbol?
"Returns true if s names a special form"
{:added "1.0"
:static true}
[s]
(contains? (. clojure.lang.Compiler specials) s))
Thus:
user=> (pprint (keys (. clojure.lang.Compiler specials)))
(&
monitor-exit
case*
try
reify*
finally
loop*
do
letfn*
if
clojure.core/import*
new
deftype*
let*
fn*
recur
set!
.
var
quote
catch
throw
monitor-enter
def)

Unable to get random (doc) from a namespace

I want to display random (doc) page for some namespace.
The random function name I can get by:
user=> (rand-nth (keys (ns-publics 'clojure.core)))
unchecked-char
When I try to pass this to (doc) I get this:
user=> (doc (rand-nth (keys (ns-publics 'clojure.core))))
ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol clojure.core/ns-resolve (core.clj:3883)
I'm new to Clojure and I'm not sure how to deal with this... I tried to convert this into regexp and use (find-doc) but maybe there is a better way to do this...
Explanation
The problem here is that doc is a macro, not a function. You can verify this with the source macro in the repl.
(source doc)
; (defmacro doc
; "Prints documentation for a var or special form given its name"
; {:added "1.0"}
; [name]
; (if-let [special-name ('{& fn catch try finally try} name)]
; (#'print-doc (#'special-doc special-name))
; (cond
; (special-doc-map name) `(#'print-doc (#'special-doc '~name))
; (resolve name) `(#'print-doc (meta (var ~name)))
; (find-ns name) `(#'print-doc (namespace-doc (find-ns '~name))))))
If you're new to Clojure (and lisps), you might not have encountered macros yet. As a devastatingly brief explanation, where functions operate on evaluated code, macros operate on unevaluated code - that is, source code itself.
This means that when you type
(doc (rand-nth (keys (ns-publics 'clojure.core))))
doc attempts to operate on the actual line of code - (rand-nth (keys (ns-publics 'clojure.core))) - rather than the evaluated result (the symbol this returns). Code being nothing more than a list in Clojure, this is why the error is telling you that a list can't be cast to a symbol.
Solution
So, what you really want to do is evaluate the code, then call doc on the result. We can do this by writing another macro which first evaluates the code you give it, then passes that to doc.
(defmacro eval-doc
[form]
(let [resulting-symbol (eval form)]
`(doc ~resulting-symbol)))
You can pass eval-doc arbitrary forms and it will evaluate them before passing them to doc. Now we're good to go.
(eval-doc (rand-nth (keys (ns-publics 'clojure.core))))
Edit:
While the above works well enough in the repl, if you're using ahead ahead-of-time compilation, you'll find that it produces the same result every time. This is because the resulting-symbol in the let statement is produced during the compilation phase. Compiling once ahead of time means that this value is baked into the .jar. What we really want to do is push the evaluation of doc to runtime. So, let's rewrite eval-doc as a function.
(defn eval-doc
[sym]
(eval `(doc ~sym)))
Simple as that.

Destructuring forms and Compojure?

I'd thought I'd post this as I got it to work through guesswork without a real understanding of what's going on and I thought it might be helpful if someone explained it.
I understand how to get at an element of the :params map in a Compojure handler:
(GET "/something" [some_arg] "this is the response body")
or
(GET "/something" {{some_arg "some_arg"} :params} "this is the response body")
although I don't completely understand what the {some_arg "some_arg"} part is doing :(
I also wanted to access the :remote-addr part of the request as well as some_arg. And I ended up with
(GET "/something" {{some_arg "some_arg"} :params ip :remote-addr}
(do-something-with some_arg ip))
So, I get that the unquoted strings some_arg and ip are the names of variables to which I want the values bound but the map above isn't a valid Clojure map. How does it work?
I also get that this is evaluated against the Ring request map (which is somehow supplied by the defroutes macro) but the expression above isn't a function or macro definition so how can it 'exist' as a valid expression in my code? Is there some sort of suspension of the normal rules for macro arguments? I've been unable to find a definition of the syntax of destructuring forms comprehensible to this non-Lisp'er.
The map is a valid destructuring map. In any place where you bind names, you can use destructuring. You could do the same thing in a let, like this:
user=> (let [{{some-arg "some_arg"} :params ip :remote-addr} {:remote-addr "127.0.0.1" :params {"some_arg" "some_value"}}] [ip some-arg])
["127.0.0.1" "some_value"]
I wrote a post about map destructuring in the context of named arguments, but it applies here. You might find this useful: Clojure - named arguments
There are a lot of blog posts demonstrating destructuring, including this one. I'm not sure which one would be a canonical place to learn from.
I don't pretend to know what exactly compojure does with that map under the hood, but I presume it throws it in a let or something similar as I demonstrated above. GET is a macro, so it doesn't have to evaluate the map you pass it, which is why you wouldn't get an error unless it evaluated it.
user=> (defmacro blah [m])
#'user/blah
user=> (blah {a "b" c "d"})
nil
user=> (defn blah [m])
#'user/blah
user=> (blah {a "b" c "d"})
java.lang.Exception: Unable to resolve symbol: a in this context (NO_SOURCE_FILE:9)
Under the hood, magic happens to that map and it gets passed to a function called destructuring that does the destructuring magic.
There isn't really anything special going on here other than normal macro/special form foo and delayed evaluation.
Destructing takes place within a binding form, and for map destructuring the var to be bound is on the left, and the key is on the right:
user=> (let [{a :foo} {:foo :bar}]
user=* a)
:bar
Compojure is doing a binding form behind the scenes, so that map destructuring form you were using above is effectively turned into something like:
(let [{{some_arg "some_arg"} :params} request]
...)
Where request is an implicitly provided map.
The vector version (e.g., [some_arg]), is an alternative that just binds against the :params map contained in the request.