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.
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.
For example, in Python:
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.