This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-31
Channels
- # announcements (4)
- # babashka (73)
- # beginners (128)
- # bristol-clojurians (1)
- # calva (8)
- # cider (8)
- # clj-kondo (4)
- # clojars (7)
- # clojure (148)
- # clojure-dev (16)
- # clojure-europe (5)
- # clojure-gamedev (1)
- # clojure-italy (10)
- # clojure-nl (7)
- # clojure-uk (57)
- # clojurescript (57)
- # clojutre (1)
- # community-development (2)
- # cursive (7)
- # data-science (1)
- # datascript (5)
- # datomic (9)
- # events (6)
- # figwheel-main (1)
- # fulcro (91)
- # garden (11)
- # graalvm (14)
- # graphql (1)
- # immutant (4)
- # jobs (1)
- # kaocha (33)
- # off-topic (63)
- # onyx (3)
- # pathom (4)
- # re-frame (23)
- # ring-swagger (1)
- # shadow-cljs (49)
- # sql (6)
- # testing (8)
- # tools-deps (45)
- # vrac (1)
- # xtdb (10)
https://lambdaisland.com/guides/clojure-repls ... super useful to untangle the repl mess 🙂 I don't even know where I got that link from!
what does this mean |#<clojure.lang.Var$Unbound@21fc24f0 Unbound: #'clj-journal.timbre/data_>
. I just evaluated a var and this other vars commes properly.
One way to get a similar result is to do (def a)
in a REPL, then try to evaluate a
I do not know if there are other ways to cause a var to be unbound.
Every time I get unbound I realize that the specific code with the var doesn’t run .. so the def is never set .. but yours might be a different scenario
well they're int indexed...
user=> Integer/MAX_VALUE
2147483647
they are Java strings
Unlike in other language ecosystems, I've noticed that in the Clojure ecosystem, fns don't tend to check for wrong args and throw InvalidArgumentException
s. I've seen systems external to the fns' source code itself to do that ex: spec, schema, malli etc. The fns themselves are usually GIGO. You give 'em garbage, you get garbage back. Not saying Clojurists are indisciplined or something like that. Just that most fns don't do this, but validation is done "at the gate", or at the edges of the program.
Is this a fair thing to say?
@jaihindhreddy I don't know that you can make much of a generalization there. I've seen plenty of Clojure code that either assert
stuff about arguments or explicitly checks them and throws IllegalArgumentException
.
I just searched the projects I have open in my editor right now and all of these do that to some degree: HoneySQL, Expectations, next.jdbc, clojure.java.data. I know that clojure.java.jdbc does it too. Our own code at work uses a mixture of assert
and conditional IllegalArgumentException
throwing in some places.

Thank you for doing that! I guess one thing that in no-small-part made me think way is nil-punning. Python for example, throws KeyError
instead of just returning None
.
True, nil-punning means that a lot of times you don't need to check for/exclude nil
arguments (which is a win, in my opinion).
But that's going to produce a runtime failure either way so if an illegal argument value is going to cause your code to blow up anyway, there's not much point in explicitly checking that (and throwing) -- unless you really want to provide a "better" error message for incorrect usage of your functions 🙂
If there was an easy way to add functions schemas/specs in the language core, or in a de-facto library, I think we would see a lot more of those.
I think that's true for all languages. Only that if there's a type system, it enforces some rules of its own.
adding a dependency to 3rd party schema lib, which adds 1sec to repl startup time, is not something that lib authors want to do.
(and instrumented specs can add quite an overhead at runtime so it's something you might see in dev/test but not in production)
I had an Advent of Code problem with some hot loops which took 15 minutes instead of 2 seconds with instrumentation enabled for speculative specs 🙂
There are significantly faster ways to do GI checking than spec, at least for some kinds of GI checking: https://github.com/jafingerhut/funjible#wait-isnt-this-what-clojurespec-is-for
@andy.fingerhut btw, clj-kondo has some type checking around this too now:
Out of curiosity, have you ever tried clj-kondo on the Clojure code in its implementation?
Do you mean you want to pass a string to C code that contains the two character %
followed by n
?
Neither of those should require special escaping that I can think of.
C code libraries often expect strings to be 8-bit, not 16-bit as they are in Clojure/Java, but I don't know what JNA might have in the way of translation of string contents there.
Well, 16-bit as they are in Clojure/Java, except when they are restricted to the ASCII subset, then JDK 9 and later will actually store them as 8-bit.
Oh, you want the C printf to get a format string such that it will output %
followed by n
?
like here https://github.com/runejuhl/clj-journal/commit/15b78e7f4c691bb61df18ce8814a2db087462ac4#commitcomment-37062267 it crashes, but the author escapes things with adding _
betwean those symbols
@andy.fingerhut Do you mean lint Clojure itself? or clj-kondo itself?
lint Clojure itself.
That happens on every CI build as a way of linting a corpus for checking regressions. Why you ask?
Just curious if you had done it. At least tools.analyzer.jvm that Eastwood uses, that was a big step making that not give any errors running on most/all clojure.core code.
yeah. I used a lot of false positives from clojure itself to improve clj-kondo in the beginning
In particular, one line of code in the Clojure.data namespace might cause that warning on the use of union you showed to fire.
Yeah, I think that also came up when speculative got specs for clojure.set: https://github.com/borkdude/speculative/issues/70#issuecomment-435185067
and now that I remember some discussions on speculative, I probably sound like a broken record there 🙂
it seems clj-kondo doesn't catch that error, maybe because it has no type annotation for keys yet.. I'll check
ah, it has, but the return type is :seqable . clj-kondo has a somewhat relaxed type system, so when something can take the form of some valid input it doesn't complain. and keys can return nil which would be a valid input for set/union
I guess it depends on whether you avoid a warning when something might be given valid input, vs. when it must be given valid input
if you take the first route then you end up changing your code just to avoid type warnings
I know small changes to conditions for issuing warnings can change false positive rates in unexpected ways, until you try it on many code bases, sometimes.
it's kind of what you get with typescript where you must convince the compiler that some object has a certain key
understood.
works and no other regressions: https://github.com/borkdude/clj-kondo/runs/419883444 expand the diff thing
< clojure/data.cljs:52:39: warning: Expected: set or nil, received: seq.
< clojure/data.cljs:52:48: warning: Expected: set or nil, received: seq.
And I use keys often with map
for example. So the nil punning seems really useful, so that if the map is empty then I don't need to loop over anything
That's why I'm saying if the linting was changed to check that nil isn't passed as input to keys, but the return type still allowed nil
@U0K064KQV Can you come up with a practical example where a return type of keys being spec-ed as seq instead of seqable results in a linter warning?
Relying on keys returning nil might even be relying on an implementation detail, since it's not even in the docstring
And, now that I think some more, I wasn't really thinking type checking but return type validation. In a type check scenario, I think you're probably right
The only example where this would not work is if you had a function that insists it be called with nil and nil only. Then (keys {}) would be valid, but not if you spec it as seq. But that seems very unlikely in Clojure.
Ya, totally agree now. I really don't see why someone would ever use keys to a function that takes only nil.
I was thinking it would fail when passed to a fn on seqable input, that was my only concern
I think in general it works out if functions are typed with correct inputs (broad enough) but somewhat too narrow outputs.
It does make sense, especially in linting, since you can just ignore a few false positive in the rare edge case
if you spec a function with a too narrow output (a instead of a or b) and you feed the output into a function which expected a or b, it still works fine.
If I had say a function, and it could return nil or a seq based on the implementation, and I said it returns a seq, that would warn ?
I am tossing in two cents based upon no real knowledge of clj-kondo internals, but I was under the impression that for certain core functions, borkdude simply tells it in some data structure "I claim that this returns type foo", and clj-kondo uses that, but does not check it.
"I claim that keys always returns a seq" that's how it works yes. And no code breaks on that assumption. If there would be code broken by this assumption, it's probably too specific
Okay, I see for core. What about for my code being linted? Do you just check inputs as well? So if I return the result of next
and I claimed my fn returns seq only, it would be valid?
Is clj-kondo's mechanism for declaring function return types open to user extension?
that's how it works. not a lot of people are using this format already and I want to give it some time before committing to it, but it is open to configuration
There is one schema library (malli) which is going to try to generate this format from information that users provide via their defn-like macro
Excited to see where this all goes, if more library authors start providing clj-kondo type configurations for their libs, linting would get really great
Are there any recommendations on doing reinforcement learning on Clojure? My shallow search shows cortex
, which hasn't been updated in 2 years, and the interop for Clojure in deeplearning4j
. Are there others that one should be aware of?
I have not read this book, but the author has worked on libraries for using Clojure to generate code for GPUs, and I believe reinforcement learning is one of the use cases he covers: https://aiprobook.com/deep-learning-for-programmers/
Thanks. Yep, I threw in to support the project, and I can now read his book. He's got general neural networks addressed, but upon first skim, I don't really see anything for reinforcement learning. Still looks promising for other areas I care about though...
I do not know how open the author is to suggestions for additional chapters, but you could try contacting him to see his plans for covering reinforcement learning, if any