Sure, I'm not arguing that all large projects suffer from this, and I'm not
entirely sure why Cursive does so badly. But the argument I often see
online is the opposite - that Clojure codebases never suffer from this, and
if they do then it must be because of interop, or the application must be
strange in some way. I think this sort of argument is equally disingenuous,
and like I say, I've heard numerous anecdotes to the contrary.

One theory about why Cursive is particularly prone to this that I forgot to
mention - Cursive *is* unusual in that it is run on users' desktops. When
writing, for example, a web application, assuming you're validating your
input you have a reasonable handle on the expected space of inputs, and you
can test various combinations of your application state. For Cursive, that
is much harder - I currently support 6 versions of the underlying IntelliJ
platform, and they run on 3 operating systems. There are two
main IntelliJ configurations (Ultimate and Community). These variations are
actually surprisingly stable and don't tend to create a lot of problems,
but users can also have any combination of plugins installed, and they can
sometimes interact in surprising ways - I've had bugs logged against
Cursive that have turned out to be bugs in the Scala plugin, and vice
versa. Plugins can hook into all sorts of different IDE functionality at
different levels and this can interact in strange ways. I've had a lot of
bugs of this sort, and it's plausible that many of the bugs that are
currently unresolved are a result of this in some way.

In this sort of situation, a static type system which provides universal
guarantees (this value can never be null) is more useful than a contract
system (no null values have been seen yet for the test inputs you've
tried). There's simply no way I can test all combinations, or reproduce all
combinations that users might have running. While the spec'ed core
definitely sounds like something I should try, it will still only work for
the combinations that I actually test unless I leave it running in
production builds.

On 21 October 2016 at 17:51, Alex Miller <a...@puredanger.com> wrote:

> Just as a counter-anecdote, I have worked on large Clojure codebases (both
> ones I developed and ones I was unfamiliar with), including ones that
> interfaced with existing Java codebases, and have not experienced this
> problem to the degree you describe Colin. So while I believe these problems
> exist, I don't think it's a foregone conclusion that they must.
>
> FYI, I've found that when working with a partially instrumented spec'ed
> clojure.core, that unexpected nil colls (and colls containing nil) are
> reported earlier and better (because they occur at the point they are
> introduced rather than later and several layers down in some RT method).
>
> On Friday, October 21, 2016 at 10:15:23 AM UTC-5, Colin Fleming wrote:
>>
>> This is a discussion that I've had a couple of times. I don't think that
>> interop is the main factor here, I think it's more that I'm programming
>> against a large codebase I don't understand well (I can't since it's around
>> 4 million LOC). I suspect that if I were programming against a large
>> undocumented Clojure codebase I'd have similar problems, or worse.
>>
>> Note that Java interop often gets the blame here, but it's worth pointing
>> out that in Clojure everything is Java interop in the end. (+ 1 x) or
>> (str/trim x) will give you an NPE as easily as in Java if you pass nil in
>> x. And even if Java interop *is* the root cause of the problem,
>> supposedly interop is idiomatic in Clojure, and interfacing with existing
>> Java systems is a key use case for continuing Clojure adoption. I don't
>> think that the type of application that Cursive is is as much of an outlier
>> as people think - anyone integrating with an existing system will probably
>> face similar problems. Indeed, after my previous conversations, several
>> people contacted me to say that their experience matched mine in similar
>> systems.
>>
>> People have also asked me about whether nil punning helps. In my
>> experience, it allows for some elegant code but it has a really terrible
>> tendency to mask bugs and push them much further into the system than would
>> otherwise be the case. It would be nice to be able to say that I'm
>> expecting a collection to be non-nil, and to get an NPE at the point of the
>> collection call if it's nil due to a bug, rather than just silently
>> returning nil and continuing.
>>
>> Also, when tracking down an NPE from a bug report, if there are
>> collection methods in the stack trace I now have to consider (at least) 3
>> cases: the collection is unexpectedly nil, the collection is unexpectedly
>> empty, or the collection unexpectedly contains a nil value. This greatly
>> increases the space of problems that I have to consider as possibilities
>> when trying to work out what's going on.
>>
>>
>>
>> On 21 October 2016 at 05:39, Daniel <doubleagen...@gmail.com> wrote:
>>
>>> Just curious... What do you think the primary contributing factor is for
>>> Cursive's NPEs? Java interop?
>>>
>>> --
>>> 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.
>>>
>>
>> --
> 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.
>

-- 
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.

Reply via email to