Hacker News new | ask | show | jobs
by yoha 3640 days ago
This is effectively wishful thinking.

If a bug causes an unexpected undefined value, it will lead your code to an undefined behavior. It might work well 999 times and wipe everything on the 1000th execution. Thankfully, Javascript is mostly limited to web browsers.

Exceptions make it so that nothing unexpected happen. This is especially useful when you do not know the whole codebase. Of course, there are many cases when you can just ignore the errors. Exceptions allow you to fine tune this.

2 comments

> If a bug causes an unexpected undefined value, it will lead your code to an undefined behavior.

Let's not confuse "undefined", a JS value that is basically like C's NULL, with "undefined behavior", the concept from e.g. the C language spec. Operations on the JS value "undefined" are perfectly well-defined in the C sense; you can reliably test for it and have a case to handle it. In particular, the well-defined behavior for Underscore/Lodash in response to mapping over "undefined" is to return an empty array. The programmer upthread is using the library's documented and well-defined behavior; there is nothing wrong with that.

It is just like how, in C, some functions (like time()) are well-defined if you pass them a NULL pointer, and some functions (like strlen()) are not, and result in undefined behavior. In this case, the functions in question are all well-defined if you pass them "undefined".

> Exceptions make it so that nothing unexpected happen.

No, it makes it so that your program surprises the user by crashing, which is (hopefully!) pretty unexpected.

Unless, of course, you use the exceptions to provide some sane default code path that handles the problem, but that's exactly what lodash is doing for you in this example.

Crashing is exactly what the correct program should do if it hits undefined behavior.
What?

1. Where did anyone say we were hitting undefined behavior? We're hitting a well-defined JavaScript value whose name is "undefined".

2. Why is crashing correct? Don't answer in terms of language specs, answer in terms of desired behavior for whatever you're trying to do with the program. Software engineering is a tool for accomplishing other things. Sometimes, yes, software crashing is the right thing in service of that other goal. But not always.

Undefined behavior of a program is when a programmer didn't define how to handle a particular situation. If an array becomes "undefined" and the programmer didn't expect such result (e.g. there's no if (typeof array === "undefined") { ... }), then the behavior is undefined regardless of what kind of types there are in JavaScript.

Crashing in such case is used to avoid incorrect functioning of the program, such as overwriting user data or introducing security vulnerabilities. By definition, if the behavior wasn't expected, the program is in unknown state. Sure, you can gracefully handle such situations (e.g. allow website to load other scripts if the particular piece that "crashes" not important for its functioning, crash just some kind-of sub-process and restart it, or — if it's user input — end up with some predefined value regardless of the incorrect input, etc.), but the correct _default_ behavior is to crash, otherwise you'll end up with unknown state and the algorithm that you wrote will be incorrect.

I recommend anyone who wants to see how much unexpected behavior is in their JavaScript programs to install typescript@next and start adding types, compiling with tsc --strictNullChecks.

Lodash methods handle things like String#match which returns array/null.

More for avoiding guard scaffolding than for undefined behavior.