beginners

Christoph 2025-09-10T07:57:06.513789Z

Is there a difference between :refer (x) and :refer [x] within ns (:require [.. ]) I see more [ ] than ( ), is it purely a stylistic difference ?

James Amberger 2025-09-11T23:39:00.721529Z

one exception to () for invocation: case

Alex Miller (Clojure team) 2025-09-11T23:45:51.556729Z

Yep

gaverhae 2025-09-10T08:10:22.361229Z

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.

1
Roman Liutikov 2025-09-10T08:10:56.535069Z

afaik [] is just a (relatively) newer syntax Basically what ^ said

Christoph 2025-09-10T08:11:06.879979Z

thank you. I also found () misleading, because it looks like function invocation.

gaverhae 2025-09-10T08:11:13.644599Z

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.

💯 1
exitsandman 2025-09-10T08:12:20.406129Z

IIRC the convention is [] for requires and () for imports

gaverhae 2025-09-10T08:12:57.521969Z

Because:

(ns example
  (:import (package Class1
                    Class2)))
reads a little bit better than
(ns example
  (:import [package Class1
            Class2]))

🔖 1
liebs 2025-09-10T08:13:39.355399Z

huh I never considered that @gaverhae, I always wondered why people used parens with :import til

gaverhae 2025-09-10T08:13:40.389419Z

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.

Gent Krasniqi 2025-09-10T08:20:08.841509Z

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.

Alex Miller (Clojure team) 2025-09-10T12:57:41.663169Z

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.

true.neutral 2025-09-10T19:39:08.215519Z

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?

true.neutral 2025-09-15T11:20:27.974549Z

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.

true.neutral 2025-09-11T12:32:31.578999Z

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.

gaverhae 2025-09-11T13:10:09.659279Z

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.

gaverhae 2025-09-11T13:13:03.191739Z

I don't know of any way to instantiate a parameterized class in Clojure itself.

true.neutral 2025-09-11T13:28:32.533309Z

Thank you very much @gaverhae! That's the path I'll follow then; thanks for helping me out.

2025-09-11T15:48:37.579469Z

or just construct the Type thing yourself https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Type.html

2025-09-11T15:50:05.318269Z

(or just use the http api directly and not have to deal with that horribleness)

2025-09-10T21:56:44.597079Z

that is create a new anonymous class that extends TypeToken<Watch.Response<V1Namespace>> and instantiating it, and calling getType on it

2025-09-10T21:57:22.588909Z

horrendous

2025-09-10T23:38:34.010669Z

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?

gaverhae 2025-09-12T10:03:36.784409Z

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.