Why can't I use .?. in clojure? - clojure

I find a macro .?. on the website https://clojure.github.io/clojure-contrib/core-api.html. But I can't use it. I tried the example,
(.?. "foo" .toUpperCase (.substring 1))
the clojure repl returns an error:
user=> (.?. "foo" .toUpperCase (.substring 1))
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: .toUpperCase in this context
I notice the namespace of .?. is deprecated. Can't we use this macro anymore?

It has been moved to core.incubator, like #phipsgabler said.
You should use some-> from clojure.core.
(some-> "foo" (.toUpperCase) (.substring 1))

It has been moved to a separate module core.incubator.

Related

Why is my clojurescript macro not working

I need when-not-empty-let macro similar to clojure/core's when-let. So, I've just added not-empty call to when-let macro from clojure's source code:
(defmacro when-not-empty-let
"bindings => binding-form test
When test is not empty, evaluates body with binding-form bound to the value of test"
[bindings & body]
(.log js/console "check")
(let [form (first bindings) tst (second bindings)]
`(let [temp# ~tst]
(when (not-empty temp#)
(let [~form temp#]
~#body)))))
(also replaced (bindings 0) with (first bindings) as it didn't compile otherwise)
I use it in a following way:
(defn something
[]
(when-not-empty-let [foo ["foo"]]
(.log js/console foo)))
(something)
I'm getting following output:
undefined
check
What am I doing wrong?
Builded with Clojure v1.9.0, ClojureScript: v1.10.126, lein-cljsbuild: v1.1.7
Tested in Chrome v59.0.3071.115 under Ubuntu.
UPD: jsbin that reproduces issue (at least for me): https://jsbin.com/liluwer/1/edit?js,output
See output from question in browser's developer tool console.
From ClojureScript docs:
There is a strict rule for when you can use defmacro -- you can only use it in what we call a macro namespace, effectively forcing you to separate your compile time and runtime code.
The error is I tried to test the macro in the same namespace.

Turn off *print-namespace-maps* in repl

With Clojure 1.9-beta2, the reader and writer now support a compact syntax for maps. The syntax avoids repeating the namespace in the case where all the keys are qualified keywords with the same namespace:
> (pr-str {:a/foo 1 :a/bar 2})
"#:a{:foo 1, :bar 2}"
That causes problem when sending such a serialized map to a Clojure 1.8 process: the old reader running there will fail to read it and throw a java.lang.RuntimeException: Reader tag must be a symbol.
Luckily, the printer only does this when the dynamic variable *print-namespace-maps* is truthy, and it's falsey by default, so my app continues to work in production. However, the REPL sets it to true, so when I work in the REPL and do something that ends up sending a request to a Clojure 1.8 service, it fails. How can I disable the new syntax in the REPL also?
I thought that maybe I could just (set! *print-namespace-maps* false) in my repl or add {:user {:repl-options {:init (set! *print-namespace-maps* false)}}} to my ~/.lein/profiles.clj, but that doesn't seem to work. I think the reason may be that the REPL uses binding to create thread-local bindings for a bunch of variables including this one, and set! does not work for local variable bindings.
You can redefine print-method for maps, which should work regardless of environment.
(defmethod print-method clojure.lang.IPersistentMap [m, ^java.io.Writer w]
(#'clojure.core/print-meta m w)
(#'clojure.core/print-map m #'clojure.core/pr-on w))
Using (set! *print-namespace-maps* false) works for me. (But this is some 5 years later.)
This also works, and can sometimes be more desirable:
(binding [*print-namespace-maps* false]
(pr-str {:a/foo 1 :a/bar 2}))
=> "{:a/foo 1, :a/bar 2}"

clojure newbie how to call methods of a java object

I'm trying the following
(def myMap (HashMap.))
(doto (myMap) (.put "a" 1) (.put "b" 2))
I get as a result:
Reflection warning, core.clj:20:3 - call to method put can't be resolved (target class is unknown).
Reflection warning, core.clj:20:3 - call to method put can't be resolved (target class is unknown).
Am I doing anything wrong?
You need to remove the brackets around myMap:
(doto myMap (.put "a" 1) (.put "b" 2))
(myMap) will attempt to call myMap as a function.
Not really. The compiler is just warning you that its emitting code that uses reflection. You can type hint Clojure to get rid of this:
(def ^HashMap myMap (HashMap.))
(doto myMap (.put "a" 1) (.put "b" 2))
Update: Ha, I didn't read the error message very well :) However, as soon as you remove the parens from (myMap) you'll get an actual reflection warning (assuming (set! *warn-on-reflection* true)) which can be resolved by my example above.

Clojure CLR - Implement interface that contains properties

I'm trying to implement an interface that has properties but can't quite seem to get it to work and I also have not found any relevant examples via Google (yet). I'm sure I'm doing something completely wrong here but have no idea how to fix it.
(System.Reflection.Assembly/LoadWithPartialName "System.Web")
; naive, just trying to figure out how to implement the IHttpHandler interface in Clojure
(defn foo-handler []
(reify System.Web.IHttpHandler
(IsReusable [] false)
(ProcessRequest [context] ())))
IsReusable is a property and I don't know how to tell reify that it is not a traditional function.
CompilerException clojure.lang.CljCompiler.Ast.ParseException: Must supply at least one argument for 'this' in: IsReusable
Okay, I supply 'this' for IsReusable
CompilerException clojure.lang.CljCompiler.Ast.ParseException: Can't define method not in interfaces: IsReusable
I've also tried proxy but I get similar results.
I've also tried naming IsReusable to get_IsReusable which doesn't actually make a difference and I get the same compiler errors as above.
I've also tried deftype but I get a completely different error:
(deftype foo-handler []
System.Web.IHttpHandler
(get_IsReusable [this] false)
(ProcessRequest [this context] ()))
Compiler error:
InvalidCastException Unable to cast object of type 'clojure.lang.Var' to type 'System.Type'. clojure.lang.Namespace.ReferenceClass
Update:
The code posted for deftype works, I cannot reproduce the error that I posted above. I have no idea now what I was doing wrong at the time.
This took me a few hours of research and trial and error but I finally have success!
user=> (def foo-handler
(reify System.Web.IHttpHandler
(get_IsReusable [this] false)
(ProcessRequest [this context] ())))
#'user/foo-handler
user=>
Success!
user=> (instance? System.Web.IHttpHandler foo-handler)
true
This way is better and works fine from an ASP.NET application:
(deftype foo-handler []
System.Web.IHttpHandler
(get_IsReusable [this] false)
(ProcessRequest [this context]
(.Write (.Response context) "Hello, From Clojure CLR!")))

How do I remove a function from the lein repl?

During a lein REPL session, I may define a number of functions. However, sometimes I would want the session to 'forget' them - for example when I execute (run-all-tests), this highlights failures from tests that I no longer need. Is there a way to remove functions from the session, or to clean it, without restarting?
use ns-unmap as described on the Clojure namespaces page http://clojure.org/namespacesuser>
(defn foo [x] (inc x))
#'user/foo
user> (foo 3)
4
user> (ns-unmap *ns* 'foo)
nil
user> (foo 3)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:1:1)