简体   繁体   中英

Clojure's dot special form weirdness

I'm curious why this works (as I would expect it to after reading the documentation on the dot special form ):

(map #(. % isInstance {}) [clojure.lang.IPersistentMap])

returns:

(true)

But this does not:

(. clojure.lang.IPersistentMap isInstance {})

I get an error, "No matching method: isInstance". The form is exactly the same as in the map function call above, but outside of map , it doesn't work. Why?

The . (dot) sperial form is the weirdest of them all. Not sure if I'm going to explain it well, but let's try.

Per docs :

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. Note that nested classes are named EnclosingClass$NestedClass, per the JVM spec. Otherwise it is presumed to be an instance member and the first argument is evaluated to produce the target object.

Emphasis mine.

So you have hit the first case with (. clojure.lang.IPersistentMap isInstance {}) - clojure.lang.IPersistentMap resolves to class name and the whole expression is assumed to be a static method call.

In the map case the symbol is evaluated (the part with emphasis), evaluates to clojure.lang.IPersistentMap class object before being passed to the anonymous function and the whole expression is an instance method call on that class.

So it boils down to the fact that in one place the clojure.lang.IPersistentMap is being used as a symbol that refers to a class name and in the other as something that evaluates to a class object.

Also look here :

Note that class names normally denote class objects, but are treated specially in certain special forms, eg '.' and new.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM