Is there some way to see what has already been defined in a clojure session (equivalent to calling ls())? Let's say that I create a few objects:
(def x 1)
(def y 2.2)
(def plus-one (fn [x] (+ x 1)))
Is there a command that can be run to show me that these now exist in the user namespace?
I am doing all the assignments in user namespace.
user> (def *foo 10)
#'user/*foo
;; To see all the public intern mappings in the user namespace.
user> (ns-publics 'user)
{*foo #'user/*foo}
Now let's define a function which is not public
user> (defn- foobar[x]
(println x)
#'user/foobar
When you call ns-publics function. It will not show foobar function in the mappings.
user> (ns-publics 'user)
{*foo #'user/*foo}
To see the intern mappings for the namespace. Use (ns-interns 'YOUR-NAMESPACE)
user> (ns-interns 'user)
{foobar #'user/foobar, *foo #'user/*foo}
Maybe ns-publics ?
Returns a map of the public intern mappings for the namespace.
or ns-map ?
Returns a map of all the mappings for the namespace.
As I understand it, there is no "global environment," there are only namespaces. Of course whichever one you are currently "in" looks like a "global environment" for practical purposes.
Related
My goal is a function/macro that works like this:
(def f (polymorphic-fn
java.lang.Long (fn [a] (inc a))
java.lang.String (fn [a] (str a "x"))))
(f 1) ;; => 2
(f "abc") ;; => "abcx"
Since the type-based dispatch of protocols has the best performance I was thinking to create an 'anonymous' protocol for the 'fused' function with a macro like this:
(defmacro polymorphic-fn
[& pairs]
(let [proto (gensym)
method (gensym)
extends (for [[type handler] pairs]
`(extend ~type ~proto {(keyword ~method) ~handler}))]
`(do
(defprotocol ~proto (~method [e#]))
~#extends
~method)))
This produces the error: Unable to resolve symbol: G__18707.
Is there a way to return the 'anonymous' method, or is there a better way to implement such a function?
The problem is that the defprotocol will generate code that will intern the protocol methods. Ie. after macroexpansion, the symbols for your defined method is still not known to the compiler. Thus, the compilation fails and will barf that the symbol is unknown.
Many other def...'s will generate a macro "call" that will intern the symbol during macro expansion (and thus the compiler will remain happy).
To fix it you can just declare it beforehand. This works since declare is macro, will get expanded and the compiler will be happy:
(defmacro polymorphic-fn
[& pairs]
(let [proto (gensym "proto")
method (gensym "prot-method-")
extends (for [[type handler] (partition 2 pairs)]
`(extend ~type ~proto {~(keyword (str method)) ~handler}))]
`(do
(declare ~method)
(defprotocol ~proto (~method [e#]))
~#extends
~method)))
Note: I also fixed the keyword call in this.
I think you just want to use regular protocols, along with extend-type:
(defprotocol Fooable
(foo [this]) )
(extend-type java.lang.Long
Fooable
(foo [some-long] (inc some-long)))
(extend-type java.lang.String
Fooable
(foo [any-string] (str any-string "-and-more")))
with result:
(foo 3) => 4
(foo "hello") => "hello-and-more"
It may be possible to use a macro to hide the protocol name by using an auto-gensym, but I don't see the point. Just ignore the protocol name 'Fooable' and you have the same result.
Also, be aware that parts of Clojure implementation create concrete Java classes behind the scenes, which may require a hard-coded name.
You could also mimic the protocol functionality by using a cond:
(defn bar [it]
(cond
(= (class it) java.lang.Long) (inc it)
(= (class it) java.lang.String) (str it "-and-more")))
(bar 7) => 8
(bar "farewell") => "farewell-and-more"
You could define a function to generate bar like you do with polymorphic-fn if you wanted.
Let's say I have come across a class with several static setter methods that I'd like to call in a row. The functionality I'm looking for is similar to that provided by doto, except that it must work on a class instead of an object:
(doto MyClass
(setA "a")
(setB "b"))
Unfortunately, when I try this, I get RuntimeException: Unable to resolve symbol: setA. Is there a special doto macro for classes?
I will leave this question open, since I'm hoping there's a better answer, but here's my home-grown macro to solve this problem:
(defmacro doto-class
"Calls a series of static methods on a class"
[klass & forms]
(cons 'do
(for [f forms]
`(. ~klass ~f))))
which expands the example:
(macroexpand-1
'(doto-class MyClass
(setA "a")
(setB "b")))
to
(do (. MyClass (setA "a"))
(. MyClass (setB "b")))
How do you call a static Java method from Clojure? Like this ...
(Classname/staticMethod args*)
For example,
> (System/getProperty "java.vm.version")
=> "25.141-b15"
We want a macro, say doto-static, that re-arranges this from (doto-static System (getProperty "java.vm.version")), and also allows a chain of calls.
Such a macro is ...
(defmacro doto-static [class-symbol & calls]
(let [qualify (fn [method-symbol] (->> method-symbol
(name)
(str (name class-symbol) \/)
(symbol)))
elaborate (fn [[method-symbol & arg-exprs]]
(cons (qualify method-symbol) arg-exprs))]
(cons 'do (map elaborate calls))))
For example,
> (doto-static System (getProperty "java.vm.version") (getProperty "java.vm.version"))
=> "25.141-b15"
First, I have no experience with CS and Clojure is my first language, so pardon if the following problem has a solution, that is immediately apparent for a programmer.
The summary of the question is as follows: one needs to create atoms at will with unknown yet symbols at unknown times. My approach revolves around a) storing temporarily the names of the atoms as strings in an atom itself; b) changing those strings to symbols with a function; c) using a function to add and create new atoms. The problem pertains to step "c": calling the function does not create new atoms, but using its body does create them.
All steps taken in the REPL are below (comments follow code blocks):
user=> (def atom-pool
#_=> (atom ["a1" "a2"]))
#'user/atom-pool
'atom-pool is the atom that stores intermediate to-be atoms as strings.
user=> (defn atom-symbols []
#_=> (mapv symbol (deref atom-pool)))
#'user/atom-symbols
user=> (defmacro populate-atoms []
#_=> (let [qs (vec (remove #(resolve %) (atom-symbols)))]
#_=> `(do ~#(for [s qs]
#_=> `(def ~s (atom #{}))))))
#'user/populate-atoms
'populate-atoms is the macro, that defines those atoms. Note, the purpose of (remove #(resolve %) (atom-symbols)) is to create only yet non-existing atoms. 'atom-symbols reads 'atom-pool and turns its content to symbols.
user=> (for [s ['a1 'a2 'a-new]]
#_=> (resolve s))
(nil nil nil)
Here it is confirmed that there are no 'a1', 'a2', 'a-new' atoms as of yet.
user=> (defn new-atom [a]
#_=> (do
#_=> (swap! atom-pool conj a)
#_=> (populate-atoms)))
#'user/new-atom
'new-atom is the function, that first adds new to-be atom as string to `atom-pool. Then 'populate-atoms creates all the atoms from 'atom-symbols function.
user=> (for [s ['a1 'a2 'a-new]]
#_=> (resolve s))
(#'user/a1 #'user/a2 nil)
Here we see that 'a1 'a2 were created as clojure.lang.Var$Unbound just by defining a function, why?
user=> (new-atom "a-new")
#'user/a2
user=> (for [s ['a1 'a2 'a-new]]
#_=> (resolve s))
(#'user/a1 #'user/a2 nil)
Calling (new-atom "a-new") did not create the 'a-new atom!
user=> (do
#_=> (swap! atom-pool conj "a-new")
#_=> (populate-atoms))
#'user/a-new
user=> (for [s ['a1 'a2 'a-new]]
#_=> (resolve s))
(#'user/a1 #'user/a2 #'user/a-new)
user=>
Here we see that resorting explicitly to 'new-atom's body did create the 'a-new atom. 'a-new is a type of clojure.lang.Atom, but 'a1 and 'a2 were skipped due to already being present in the namespace as clojure.lang.Var$Unbound.
Appreciate any help how to make it work!
EDIT: Note, this is an example. In my project the 'atom-pool is actually a collection of maps (atom with maps). Those maps have keys {:name val}. If a new map is added, then I create a corresponding atom for this map by parsing its :name key.
"The summary of the question is as follows: one needs to create atoms at will with unknown yet symbols at unknown times. "
This sounds like a solution looking for a problem. I would generally suggest you try another way of achieving whatever the actual functionality is without generating vars at runtime, but if you must, you should use intern and leave out the macro stuff.
You cannot solve this with macros since macros are expanded at compile time, meaning that in
(defn new-atom [a]
(do
(swap! atom-pool conj a)
(populate-atoms)))
populate-atoms is expanded only once; when the (defn new-atom ...) form is compiled, but you're attempting to change its expansion when new-atom is called (which necessarily happens later).
#JoostDiepenmaat is right about why populate-atoms is not behaving as expected. You simply cannot do this using macros, and it is generally best to avoid generating vars at runtime. A better solution would be to define your atom-pool as a map of keywords to atoms:
(def atom-pool
(atom {:a1 (atom #{}) :a2 (atom #{})}))
Then you don't need atom-symbols or populate-atoms because you're not dealing with vars at compile-time, but typical data structures at run-time. Your new-atom function could look like this:
(defn new-atom [kw]
(swap! atom-pool assoc kw (atom #{})))
EDIT: If you don't want your new-atom function to override existing atoms which might contain actual data instead of just #{}, you can check first to see if the atom exists in the atom-pool:
(defn new-atom [kw]
(when-not (kw #atom-pool)
(swap! atom-pool assoc kw (atom #{}))))
I've already submitted one answer to this question, and I think that that answer is better, but here is a radically different approach based on eval:
(def atom-pool (atom ["a1" "a2"]))
(defn new-atom! [name]
(load-string (format "(def %s (atom #{}))" name)))
(defn populate-atoms! []
(doseq [x atom-pool]
(new-atom x)))
format builds up a string where %s is substituted with the name you're passing in. load-string reads the resulting string (def "name" (atom #{})) in as a data structure and evals it (this is equivalent to (eval (read-string "(def ...)
Of course, then we're stuck with the problem of only defining atoms that don't already exist. We could change the our new-atom! function to make it so that we only create an atom if it doesn't already exist:
(defn new-atom! [name]
(when-not (resolve (symbol name))
(load-string (format "(def %s (atom #{}))" name name))))
The Clojure community seems to be against using eval in most cases, as it is usually not needed (macros or functions will do what you want in 99% of cases*), and eval can be potentially unsafe, especially if user input is involved -- see Brian Carper's answer to this question.
*After attempting to solve this particular problem using macros, I came to the conclusion that it either cannot be done without relying on eval, or my macro-writing skills just aren't good enough to get the job done with a macro!
At any rate, I still think my other answer is a better solution here -- generally when you're getting way down into the nuts & bolts of writing macros or using eval, there is probably a simpler approach that doesn't involve metaprogramming.
I often want to run a small snippet of code in another namespace - perhaps a copy/pasted snippet of DSL code for example, and I'd like to avoid having to either:
Add a bunch of use clauses to my current namespace declaration. This makes the ns declaration messy, adds extra maintenance work and sometimes risks name clashes.
Add require clauses and be forced to add a namespace qualifier or alias to everything. Now my DSL code is much messier.
Ideally I'd prefer to be able to do something like:
(with-ns my.namespace
(foo bar baz))
Where foo, bar might be symbols within my.namespace, but baz is a symbol in the current (enclosing) namespace. So the code is running in something like a "local" namespace that "uses" my-namespace within its scope but otherwise doesn't affect the surrounding namespace.
Is there a standard/better way to do this? Or is this a crazy thing to want to do?
Try this one:
(defmacro with-ns [[namespace symbols] & body]
`(do (use '[~namespace :only ~symbols])
(let [result# (do ~#body)]
(doseq [sym# (map #(:name (meta (val %)))
(filter #(= (name '~namespace)
(str (:ns (meta (val %)))))
(ns-refers *ns*)))]
(ns-unmap *ns* sym#))
result#)))
(with-ns [clojure.string [split upper-case]]
(split (upper-case "it works!") #" "))
-> ["IT" "WORKS!"]
After work it removes used symbols from current ns.
This can be achieved using a macro as shown below.
NOTE: It may break in certain cases as I just tried it with a simple example
;Some other ns
(ns hello)
(def h1 10) ;in hello
(def h2 11) ;in hello
;main ns in which executing code
(ns user)
(defmacro with-ns [target-ns body]
(clojure.walk/postwalk
(fn [val]
(if (symbol? val)
(if (resolve (symbol (str target-ns "/" val)))
(symbol (str target-ns "/" val))
val) val)) body))
(def u1 100) ;in user
(with-ns hello (do (+ h1 u1))) ;110
I eventually found a macro in the old Clojure contrib that does part of this quite neatly:
(defmacro with-ns
"Evaluates body in another namespace. ns is either a namespace
object or a symbol. This makes it possible to define functions in
namespaces other than the current one."
[ns & body]
`(binding [*ns* (the-ns ~ns)]
~#(map (fn [form] `(eval '~form)) body)))
I'm a few days into learning Clojure and are having some teething problems, so I'm asking for advice.
I'm trying to store a Java class in a Clojure var and call its static methods, but it doesn't work.
Example:
user=> (. java.lang.reflect.Modifier isPrivate 1)
false
user=> (def jmod java.lang.reflect.Modifier)
#'user/jmod
user=> (. jmod isPrivate 1)
java.lang.IllegalArgumentException: No matching method found: isPrivate for class java.lang.Class (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4543)
From the exception it looks like the runtime expects a var to hold an object, so it calls .getClass() to get the class and looks up the method using reflection. In this case the var already holds a class, so .getClass() returns java.lang.Class and the method lookup obviously fails.
Is there some way around this, other than writing my own macro?
In the general case I'd like to have either an object or a class in a varible and call the appropriate methods on it - duck typing for static methods as well as for instance methods.
In this specific case I'd just like a shorter name for java.lang.reflect.Modifier, an alias if you wish. I know about import, but looking for something more general, like the Clojure namespace alias but for Java classes. Are there other mechanisms for doing this?
Edit:
Maybe I'm just confused about the calling conventions here. I thought the Lisp (and by extension Clojure) model was to evaluate all arguments and call the first element in the list as a function.
In this case (= jmod java.lang.reflect.Modifier) returns true, and (.getName jmod) and (.getName java.lang.reflect.Modifier) both return the same string.
So the variable and the class name clearly evaluate to the same thing, but they still cannot be called in the same fashion. What's going on here?
Edit 2
Answering my second question (what is happening here), the Clojure doc says that
If the first operand is a symbol that
resolves to a class name, the access
is considered to be to a static member
of the named class... Otherwise it is
presumed to be an instance member
http://clojure.org/java_interop under "The Dot special form"
"Resolving to a class name" is apparently not the same as "evaluating to something that resolves to a class name", so what I am trying to do here is not supported by the dot special form.
(Update: I've prepared something which might be acceptable as a solution... The original answer remains below a horizontal rule towards the end of the post.)
I've just written a macro to enable this:
(adapter-ns java.lang.reflect.Modifier jmod)
; => nil
(jmod/isStatic 1)
; => false
(jmod/isStatic 8)
; => true
The idea is to create a single-purpose namespace, import the statics of a given class as Vars into that namespace, then alias the namespace to some useful name. Convoluted, but it works! :-)
The code is looks like this:
(defmacro import-all-statics
"code stolen from clojure.contrib.import-static/import-static"
[c]
(let [the-class (. Class forName (str c))
static? (fn [x]
(. java.lang.reflect.Modifier
(isStatic (. x (getModifiers)))))
statics (fn [array]
(set (map (memfn getName)
(filter static? array))))
all-fields (statics (. the-class (getFields)))
all-methods (statics (. the-class (getMethods)))
import-field (fn [name]
(list 'def (symbol name)
(list '. c (symbol name))))
import-method (fn [name]
(list 'defmacro (symbol name)
'[& args]
(list 'list ''. (list 'quote c)
(list 'apply 'list
(list 'quote (symbol name))
'args))))]
`(do ~#(map import-field all-fields)
~#(map import-method all-methods))))
(defmacro adapter-ns [c n]
(let [ias (symbol (-> (resolve 'import-all-statics) .ns .name name)
"import-all-statics")]
`(let [ns-sym# (gensym (str "adapter_" ~n))]
(create-ns 'ns-sym#)
(with-ns 'ns-sym#
(clojure.core/refer-clojure)
(~ias ~c))
(alias '~n 'ns-sym#))))
The above looks up the Var holding the import-all-statics macro in a somewhat convoluted way (which is, however, guaranteed to work if the macro is visible from the current namespace). If you know which namespace it's going to be found in, the original version I've written is a simpler replacement:
(defmacro adapter-ns [c n]
`(let [ns-sym# (gensym (str "adapter_" ~n))]
(create-ns 'ns-sym#)
(with-ns 'ns-sym#
(clojure.core/refer-clojure)
;; NB. the "user" namespace is mentioned below;
;; change as appropriate
(user/import-all-statics ~c))
(alias '~n 'ns-sym#)))
(Original answer below.)
I realise that this is not really what you're asking for, but perhaps clojure.contrib.import-static/import-static will be useful to you:
(use 'clojure.contrib.import-static)
(import-static clojure.lang.reflect.Modifier isPrivate)
(isPrivate 1)
; => false
(isPrivate 2)
; => true
Note that import-static imports static methods as macros.
You are successfully storing the class in jmod, but isPrivate is a static method of java.lang.reflect.Modifier, not of java.lang.Class.
You could do this with reflection:
(. (. jmod getMethod "isPrivate" (into-array [Integer/TYPE]))
invoke nil (into-array [1]))
Here is a macro inspired by the two previous answers that handles static methods on class names and variables with class names as well as instance methods on objects:
(defmacro jcall [obj & args]
(let [ref (if (and (symbol? obj)
(instance? Class (eval obj)))
(eval obj)
obj) ]
`(. ~ref ~#args)))
As a relative newbie on macros, the tricky part was getting the evaluation order right.
For other newbies: The obj parameter to the macro is passed in with no evaluation, and we need to force the evaluation of vars so the var name expands into the class name it holds. We need an explicit eval for that, outside the actual macro body.
The test for whether obj is a symbol is there to restrict the evaluation to variables. The test for whether the variable contains a class is there to skip evaluation of non-classes, then it works for objects and instance methods too.
Example use:
;; explicit class name, static method
user=> (jcall java.lang.reflect.Modifier isPrivate 1)
false
;; class name from var, static method
user=> (jcall jmod isPrivate 1)
false
;; works for objects and instance methods too
user=> (jcall (Object.) toString)
"java.lang.Object#3acca07b"
;; even with the object in a variable
user=> (def myobj (Object.))
#'user/myobj
user=> (jcall myobj toString)
"java.lang.Object#4ccbb612"
;; but not for instance methods on classes
user=> (jcall Object toString)
java.lang.NoSuchFieldException: toString (NO_SOURCE_FILE:747)