Is there a difference between :refer (x) and :refer [x] within ns (:require [.. ])
I see more [ ] than ( ), is it purely a stylistic difference ?
one exception to () for invocation: case
Yep
Both work and have the same semantics; the ns macro expects a sequence.
Generally speaking, in Clojure, we try to keep parens for function/macro calls, and use brackets elsewhere, to highlight the distinction between code and data.
afaik [] is just a (relatively) newer syntax Basically what ^ said
thank you. I also found () misleading, because it looks like function invocation.
One good reason to use parens in ns calls I've seen is for :import, because of the nature of Java packages and the default indentation of most Clojure tooling.
IIRC the convention is [] for requires and () for imports
Because:
(ns example
(:import (package Class1
Class2)))
reads a little bit better than
(ns example
(:import [package Class1
Class2]))huh I never considered that @gaverhae, I always wondered why people used parens with :import til
Incidentally, I'd never thought about it this way before, but that's also likely why we tend to prefer (:import and (:require to [:import and [:require, which I've never tested but assume would also work.
Could also be that most people just want to follow conventions and follow something like https://stuartsierra.com/2016/clojure-how-to-ns.html which also recommends (:import (java.util ,,, though there the rationale is different.
While either is fine, I prefer [ ] for all of the “args” (including import, I disagree with Alessandra on that one point - while the first part is special, it’s not invoked). ( ) are usually reserved for invocation. import, refer, etc in ns are actually converted to invocations so I think ( ) for those clauses make sense.
Hi! I'm trying to utilise java Kubernetes Client lib, and stuck at Watch example (found at https://github.com/kubernetes-client/java/blob/master/examples/examples-release-latest/src/main/java/io/kubernetes/client/examples/WatchExample.java), specifically this line:
new TypeToken<Watch.Response<V1Namespace>>() {}.getType()
I cannot quite understand what it does in Java and subsequently how I should translate that into Clojure. Could someone help please?Thanks! I'll try and do that when I get back to it. I also tried to leverage Nubank's k8s API which seems to just use HTTP, but couldn't make watches work either, with requests timing out. If I can't make that work, I'll probably fall back to thin-wrapping the thing in Java.
I don't know, it seems that I have to satisfy the function and pass it some type which I don't quite get how to construct in Clojure.
Reading through https://github.com/kubernetes-client/java/blob/a3b1d912035e9cf50b74d41d1f19aa384d407fec/util/src/main/java/io/kubernetes/client/util/Watch.java#L4, it looks like the watchType field https://github.com/kubernetes-client/java/blob/a3b1d912035e9cf50b74d41d1f19aa384d407fec/kubernetes/src/main/java/io/kubernetes/client/openapi/JSON.java#L856-L875 gson.fromJson, so I think it really does need accurate type information to return the expected Java types. I'd recommend doing this part in Java, and try to build yourself a somewhat more type-isolated API you can call from Clojure, while internally lauding the "no named types; generic maps everywhere" approach Clojure has taken to that kind of issue.
I don't know of any way to instantiate a parameterized class in Clojure itself.
Thank you very much @gaverhae! That's the path I'll follow then; thanks for helping me out.
or just construct the Type thing yourself https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Type.html
(or just use the http api directly and not have to deal with that horribleness)
that is create a new anonymous class that extends TypeToken<Watch.Response<V1Namespace>> and instantiating it, and calling getType on it
horrendous
It's a sneaky, roundabout way to get hold of a generic type in Java so that you can coerce objects to the correct type and satisfy the compiler. I imagine you wouldn't need such a thing in Clojure since it's all dynamic anyway?
Right. If you know what the expected string is, you can do something like (reify java.lang.reflect.Type (getTypeName [_] "the string")). But I personally have no idea what the string should be.