<< Back to previous view

[CLJS-339] (inc nil) returns 1 instead of throwing an exception Created: 23/Jul/12  Updated: 29/Jul/13  Resolved: 29/Jul/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Evan Mezeske Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug


(inc nil) => 1 in ClojureScript
(inc nil) => raise NullPointerException in Clojure

I think that Clojure's behavior (throwing) makes more sense in this context.

Comment by Evan Mezeske [ 23/Jul/12 12:44 AM ]

I observe that in my JS console, "undefined + 1 => NaN" but "null + 1 => 1". I assume this has something to do with this issue.

Comment by David Nolen [ 23/Jul/12 12:30 PM ]

Do you have any suggestions on how to make this work without slowing arithmetic down? If not I'm inclined to close this as Won't Fix.

Comment by Evan Mezeske [ 23/Jul/12 12:50 PM ]

I do not. I haven't had a chance to put a lot of thought into it, though.

I consider this kind of problem to be rather insidious. Null is not a number, and treating it as zero will lead to nasty bugs creeping into people's code.

A historical anecdote: the C function "int atoi(char* s)" takes a string and returns the number it represents. However, if the string can't be converted, it returns zero (which could also be a valid result for e.g. the string "0"). Technically, it's possible to distinguish "0 meaning error" and "0 meaning 0" by taking additional steps after the function call, but in practice people forget to do this. Thus, atoi is universally a disaster. I have literally seen the lights go off in a warehouse due to atoi's poor design (I used to work in building control).

Treating null as zero will result in similar problems. Someone forgets to check the result of a computation, it's null, and the program silently continues as if nothing is wrong. Hello, data corruption.

So I seriously urge you to not close this as Won't Fix, even if a performant solution is not yet obvious. IMHO it's worth more thought.

Comment by David Nolen [ 23/Jul/12 12:56 PM ]

Closing as Won't Fix doesn't mean we don't care, but this issue is simply a symptom of something much larger - punting on numerics. A ticket is the wrong place for this discussion as it has many nuances. It should be a part of a larger design for ClojureScript numerics. Without that larger discussion this ticket is likely to get stuck in limbo.

Comment by Evan Mezeske [ 23/Jul/12 12:59 PM ]

Fair enough! I thought Won't Fix had stronger implications than that. Do you know if there's already a design doc that addresses numerics? Or should I start one?

Comment by Fogus [ 23/Jul/12 1:04 PM ]

One place that this has burned me, that may warrant a separate card is

(update-in some-map [:foo :bar] inc)
where the key at that location did not exist. I would have preferred an exception rather than an broken 1.

Comment by Evan Mezeske [ 23/Jul/12 1:09 PM ]

@Fogus: Huh, that is the exact same use-case that burned me – I was using update-in/inc on a nested map. The default value for my [:foo :bar] was, in fact, supposed to be zero, so it silently worked for me. But when I moved that code from the client in my webapp (ClojureScript) to the server (Clojure), I found out that my original implementation was wonky.

Comment by David Nolen [ 23/Jul/12 1:17 PM ]

It doesn't seem to me that you could do that safely without fnil + 0. I too hate JS's silent failures around numerics. Been hoping someone would tackle this challenge with gusto.

Comment by Evan Mezeske [ 23/Jul/12 1:21 PM ]

@David Nolen: Yeah, fnil would do the job. In my case, I was calling update-in on what I thought was an initialized map, but it was actually nil. update-in initialized each level of nesting with an empty map, and then inc was called on nil. My fix was simply to initialize the nested maps like I meant to.

Comment by Fogus [ 23/Jul/12 1:21 PM ]

That was ultimately the solution, so I suppose we need to start advocating this pattern so that others might avoid the same fate.

Comment by David Nolen [ 29/Jul/13 11:32 PM ]

tickets of this nature aren't going anywhere without a fairly serious design pass on CLJS numerics.

Generated at Wed Feb 22 20:30:38 CST 2017 using JIRA 4.4#649-r158309.