Timothy Baldridge wrote on Tuesday, January 12, 2016 at 1:56 PM: Since most functions in core also support nil, it isn't as big of an issue as some make it out to be. So things like this work as expected, even if a nil exists somewhere
Indeed. This is just idiomatic Clojure but it does take some getting used to. In languages like Scala and Haskell etc you have Maybe/Option types and then you need monadic operations to compose them (Scala’s for-comprehension, for example). With Clojure that "extra level" is essentially collapsed so you can either compose straight through with nil-punning: (-> coll (map first) (filter even?) count) Or you can use some-> if you want execution to short-circuit at the first nil, so you have control / choice over the behavior you want. I know some people may disagree with me, but I probably loose a max of a few minutes a week to a issue related to a nil. It's really not that big of an issue. When I first started with Clojure, I ran across NPEs quite a lot and cursed under my breath. Now it’s pretty rare to run into an NPE unless I’m off in Java interop land and, like Timothy, I rarely waste more than a few minutes a week on nil-related issues. I’ve tried both Prismatic Schema and core.typed as ways to "deal with this" — we’ve even gone back and forth between those a few times — ultimately we decided that it just didn’t buy us enough "bang for our buck" to be worthwhile, the more idiomatic our code became. Basically, we ran into many of the same issues that CircleCI ran into: http://blog.circleci.com/why-were-no-longer-using-core-typed/ Our code base is "only" 28,500 lines in just over 130 namespaces (we also have just under 10,000 lines of tests** — mostly Expectations, but also some clojure.test and some test.check generative code — spread over 100+ namespaces). Like CircleCI, I think we got to about a quarter of our namespaces annotated before we gave up and removed all the annotations. Things keep improving in Typed Clojure land and we may revisit this decision (again!) at some future date. A big issue (from my point of view) is that type inference for Clojure code can produce complex, cumbersome types that are often so general they are of very little real use, and then they won’t unify with an annotation that you’ve placed on a higher-level API: this is because so many core functions are extremely general and apply to all sequences (e.g., being able to map a sequence-consuming function over a hash-map, since that’s a sequence of pairs… a sequence of sequences). That in turn forces you to annotate several levels deep in your call chain and then you still need :no-check annotations (or, worse, have to refactor perfectly idiomatic code to something that satisfies the type checker). **That 10,000 lines also includes a lot of code that tests our REST APIs which are built with a mix of Clojure and non-Clojure technology. Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ "Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.