I wrote some code which extends the capability of a library I am using. What is the best practice for structuring folders/namespaces in this case - e.g. when the lib is called foo would you add this into the foo namespace, separate from the main project's code? E.g. when main code lives in src/company/my_project/**.clj , would you place the extension code in src/foo/new_stuff.clj ?
Definitely not as foo can potentially add new_stuff.clj itself and things will break on your end then.
Apart from that, it doesn't really matter since it doesn't seem like you will be distributing that code for use by others.
Could be src/company/foo/new_stuff.clj, could be src/company/foo_new_stuff.clj, could be src/company_foo/new_stuff.clj - as long as it's more or less clear what's going on.
great - thanks. FWIW I did actually make a PR to add to the lib, just need a place to put the code until it got reviewed/accepted
Ah, then src/foo/new_stuff.clj could actually make sense, but only if you're quite careful with removing it once the new stuff is merged in and the new version of foo is used by the project. Might even add a temporary test that checks that if that file is present then the specified version of foo must be exactly x.y.z.
good, this confirms my assumptions (coming from Ruby, this is how I would typically do a monkey patch)
When looking for a namespace full.path.to.namepsace, Clojure (the JVM, really), will look for a file at the relative path full/path/to/namespace.clj.
Relative to what? The JVM process has a "classpath", which is a series of paths (typically one per dependency you have); it will look through each of these paths for the relative path above, and stop at the first one it finds.
Another way to think about it is that all of your dependencies are zip files that all get extracted into your src folder, with no overwrite.
This is why things are a lot simpler when each library "owns" its own prefix: if you have no common paths between libraries (and your own code), then the order of the classpath does not matter.
yeah, if your org is company and your project is myproject, the best place for your extension to bar/foo is src/company/foo/feature.clj - that's precisely the use case for having an org part and a project part
I've added a clojure.spec.alpha/assert to a lower-level function and now I've got an assertion failure somewhere in my code, which I don't think I'll be able to find precisely without progressively commenting stuff until I eventually reach the point where I comment out the code causing the failure. Is there a more efficient way to go about finding precisely where this assertion failure occurs?
It should tell you in the exception trace. Your editor should also let you jump directly to it.
Some editors sometimes hide the details of the exception, something that trips up beginners a lot.
Ah I see, I'll look this up ty!
is there any function to let binding a symbol to itself? (let [foo foo] ...)
Getting back to the original question, which was not about type hints: when you write (let [foo foo] ...) you are creating a new local binding called foo that shadows the existing, external binding of foo. The order of operation for let is always first evaluate completely the right-part, then create the binding defined by the left-part. So you get a new, local binding of the symbol foo to the value that the (external) symbol foo was mapped to.
In the vast majority of cases this is useless, and it only works if foo was already declared.
I can see two reasons to do that off the top of my head:
• The external foo is a dynamic var and you want to get a stable reference to its current value. I'd personally advise you to steer away from dynamic vars, but to each their own I guess.
• You somehow believe that a local is "accessed" faster than a var. I have done quite a bit of optimization work in Clojure and never thought to try that, so I can't completely dismiss it, but I would be surprised if this mattered.
are you asking why something might do this?
common pattern in macros
or a pattern similar
(let [arg# ~arg] …)
No, not the macro pattern, cuz those are meaningfully different. I'm thinking of lines like this: https://github.com/clj-kondo/clj-kondo/blob/0f55a04562f28a835c520faa7cc3ca7ba0b2aa77/src/clj_kondo/impl/macroexpand.clj#L18
Doing reassignment with a reader conditional or with a type-hint makes sense:
(let [foo #?(:clj foo :cljs (js-foo-getter))] ...)
(let [foo ^ArrayList foo] ...)
but sometimes, i see code that (probably through renaming) ends up with a (let [... foo foo ...] ...) construction, and i'm wondering if there's special significance to it (like it helps the compiler) or if it's merely a no-opi’d be surprised if it isn’t more a quirk of authors just listing stuff in one place and not splitting locals from arguments
(let [^ArrayList foo foo] ...) is the correct type hint placement
tell that to clojure.core lol https://github.com/clojure/clojure/blob/da1c748123c80fa3e82e24fc8e24a950a3ebccd9/src/clj/clojure/gvec.clj#L371
😕
that code is 15 years old, so it's more than likely that the correct placement has changed since then, but it's funny to see old/discouraged type hints in core
no it hasn't changed, it just also happens to work the other way
it would propagate there right? that’s a bit different and still correct?
(let [sum ^Long (+ 1 1)] … is different from (let [sum ^Long sum]…)
i mean "preferred", of course
same way that clojure.core is peppered with functions with type hints on the symbol and not the param vector
different, the type hinting the arg vector is a new syntax that has become preferred, but the type hint on the var pre-dates it and used to be the only way to do it (and for non fns it is still how you type hint vars)
for lets both locations for type hints have always "worked" but hinting the new name is correct (for some value of correct which is tricky to nail down because there is no language spec, and the impl as mentioned accepts both)