This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-08-08
Channels
- # announcements (1)
- # babashka (18)
- # beginners (32)
- # calva (3)
- # chlorine-clover (4)
- # cider (14)
- # clj-commons (24)
- # clj-kondo (1)
- # clojure (34)
- # clojure-europe (4)
- # clojure-filipino (1)
- # clojure-uk (4)
- # clojuredesign-podcast (2)
- # clojurescript (6)
- # conjure (3)
- # core-async (2)
- # datahike (1)
- # datomic (3)
- # emacs (3)
- # esprit (20)
- # fulcro (4)
- # graalvm (11)
- # helix (13)
- # honeysql (4)
- # jobs (1)
- # lumo (1)
- # observability (4)
- # off-topic (11)
- # other-lisps (6)
- # pathom (6)
- # re-frame (13)
- # reagent (1)
- # reitit (1)
- # shadow-cljs (26)
- # web-security (2)
- # xtdb (10)
Anybody care to weigh in on https://github.com/clj-commons/camel-snake-kebab/issues/63 ? It's about how functions should handle an input of nil
. I don't know what to think.
Personally I don't think nil
should be returned. Exception is better. Compare with for example (name nil)
, I think no-one would want that to return nil
.
ok well, at least: > We had an issue in production where this happened w/ some unexpected input They should fix that problem on their end, making sure nil is never passed. How they deal with the error is up to them
I'd still want to move from throwing an Error to an Exception since Error:s are unexpected for these kinds of problems (even though not really wrong).
It's pretty common to have assertion errors, e.g.:
user=> (defn foo [x] {:pre [(< x 5)]} x)
#'user/foo
user=> (foo 1)
1
user=> (foo 10)
Execution error (AssertionError) at user/foo (REPL:1).
Assert failed: (< x 5)
They can turn off assertions in their code if they want, using a System property. Then you'd probably get a NullPointer from somewhere else.
There doesn't seem to be a system property for that (yet, https://clojure.atlassian.net/browse/CLJ-2554).
FWIW, at one point I was grumbling that clojure.string
functions threw exception on nil
and it would be much nicer if they treated nil
as an empty string or safely returned nil
. So I tried it out with a forked version of clojure.string
. First off, adding logic to handle nil
slowed my programs down -- it turns out that even adding just one condition into every string function has a noticeable overhead in code that does a lot of string function calls (where they are nearly all non-`nil` arguments anyway). Second, it turns out that both alternatives tend to cause (or allow for) more subtle errors that are harder to track down because, instead of blowing up early as it does now, silently returning nil
or silently treating nil
as ""
just allows for an unexpected value to crop up further down the line in the code execution. I was a bit surprised by that, but it was more convincing than the (noticeable) performance overhead and that changed my position: string functions should not accept nil
: they should just blow up.
I think your concluding statement could be generalized to all/most functions from "string functions"…
Have we got any examples of when silent/"safe" handling of nil is actually a good thing?
just fyi, the rationale for clojure.string is explained at (doc clojure.string)
when doing Java interop, the nils do what they do in Java - NPE
when doing Clojure collection or sequence operations, those functions typically are polymorphic on nil and do something useful
clojure.string is explicitly acting as a set of interop calls. http://clojure.java.io does not though, and honestly this has thrown me off a few times
(
in particular gives me pause every time
I've come to appreciate that returning nil though as you can avoid checking for a nil arg and just check the resulting file instead, which is usually better (but also trouble in stuff like (.exists (file nil))
)
file is a pretty clear that it's a polymorphic protocol backed thing though so it is pretty clojurey