Hacker News new | ask | show | jobs
by mici 3173 days ago
Great article! A few things have caught my eye:

> MyApp.users = MyApp.user || {};

Is this a typo, or intentional? If it is intentional, can someone explain the thought behind it?

Also, in some examples Medium (or the author's text editor) seems to have changed apostrophes and quotation marks, this makes the examples harder to try.

2 comments

  foo = foo || {}
"mark foo as being foo if it is already defined or as an empty new object {} if it is not"

It's just to not accidentally set a already defined foo as an empty object incase foo is already defined. Yeah... JavaScript...

Another common idiom:

  const PORT = process.env.PORT || 8080
The || (logical OR) can be used for setting a default incase the value before it is falsey (null, undefined, false...).
Why the “Yeah...JavaScript...”? The inline || is an incredibly common and useful feature in many languages. Also Op was just talking about the plural/singular difference.
You're right that we might use "short-circuiting" (AKA lazy) `||` in many languages to use a default value, but it doesn't usually work for variables.

For example, in Python:

    >>> foo or "default"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'foo' is not defined
In Javascript, variables are either bound (e.g. with `var`, as a function argument, etc.) or else they're treated as properties of the `window` object (behaving effectively as globals).

This is very unusual, and can be thought of as mixing "data" with "code": the `window` object acts like a reified version of (global) binding environment, which in most other languages is implicit. This has implications for things like the usual distinction between bound and free variables (since we can imperatively add fields to `window` at any point), and hence for things like alpha-equivalence.

It will work for `foo = None`. It is just that undefined vars in Python are an error in a different class from a missing value.

For some reason, the short-circuiting is more used on languages where undefined vars is in the same class of missing values. But that reason is not obvious to me. Python in particular has an odd mixing of quasi-static and dynamic errors that works unreasonably well but does not accept this construction.

> It will work for `foo = None`

Yes, but in that case the variable is irrelevant:

    foo = None
    foo or "default"
Here the variable `foo` is 'just doing its job' and can be simplified away to get:

    None or "default"
This shows that variables aren't involved here: `or` is just an operation on data (in this case `None` and `"default"`), just like `+` or ``.

> It is just that undefined vars in Python are an error in a different class from a missing value.

Exactly, and I think that's a perfectly reasonable justifaction for disparaging Javascript (along with bash, PHP and anything else which has this similar behaviour).

In fact, as I said above, Javascript doesn't even have a notion of "undefined variable", since variables will be looked up in the `window` object if they're not locally bound, and hence what looks* like an undefined variable is actually (according to Javascript's semantics) a missing value (a missing property of the `window` object).

> Python in particular has an odd mixing of quasi-static and dynamic errors that works unreasonably well but does not accept this construction.

I'm not sure what you mean here. As far as I can tell, there are two ways to think about errors in Python:

- From one perspective, all Python errors are dynamic, since they happen at run time when we attempt to interpret the offending code. Some of these errors happen when/if we interpret an `import` statement, some happen when a more localised expression/statement is encountered.

- A different perspective is that Python doesn't actually have a concept of errors at all. There are values available in the language which are called "errors", but they're not really errors, in the same way that `myError = "hello"` isn't actually an error (it's a string, which might represent an error but it isn't a distinguished category of things; it's just a value). Since it's semantically meaningful to perform calculations involving these values (often, but not necessarily, with the control-flow statements `try`, `except` and `raise` (which is just another form of `yield`)) they're not "errors" in the same way that, say, a segfault or a compiler error is (which Python doesn't, or shouldn't, have).

For example, here's a perfectly valid (although inadvisable) way of defining `hello world` in Python:

    $ cat x.py
    def say_hello():
        try:
            foo()
            print "goodbye"
        except:
            print "hello"

    def foo():
        i_am_undefined

    $ python
    Python 2.7.13 (default, Dec 17 2016, 20:05:07)
    [GCC 5.4.0] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import x
    >>> x.say_hello()
    hello
    >>>
Its not the inline ||. It is the need for such a pattern in JS due to terrible scoping rules, such that it is very easy for a variable definition to leak somewhere else and you really don't want to crush it.
I think he meant users vs user.
Yes, sorry if that was unclear, I meant plural vs singular.
> MyApp.users = MyApp.user

it's a typo