I've recently come across the Logical OR Assignment (||=), and the Nullish Coalescing Assignment (??=) operators in JavaScript. They are not a revolution, just a shortcut for the usage of the OR (||) operator and the nullish coalescing operator in assignment situations. We use "||=" for falsy values and "??=" for nullish (null, undefined) values. Let's see:
// for "falsy" values
> let name = "";
> name ||= "default";
'default'
> name ||= "default2";
'default'
// is equivalent to:
> name = ""
> name = name || "default";
'default'
> name = name || "default2";
'default'
// for strict null or undefined values:
> let name = null; // or name = undefined
> name ??= "default";
'default'
> name ??= "default2";
'default'
// is equivalent to:
> name = null;
> name = name ?? "default";
'default'
> name = name ?? "default2";
'default'
Python does not have a 'None coalescing' operator (so obviously it does not have a 'None coalescing assignment' operator) so as equivalent we have to use an if-else expression. We have the 'or' operator (that we can use with falsy values), but not an "or assignment" operator. So the equivalent code to the above JavaScript is quite more verbose:
# for "falsy" values
> name = ""
> name = name or "default"
'default'
> name = name || "default2"
'default'
# for strict None values:
> name = null
> name = name if name is not None else "default"
'default'
> name = name if name is not None else "default2"
'default'
As the if-else pattern is quite verbose, we can write a simple coalesce function (I've just remembered that such function is almost standard SQL) to make code more straightforward.
def coalesce(value, default_value):
return value if value is not None else default_value
a = coalesce(a, "default value")
As for other languages, Kotlin has the || operator and the :? null coalescing operator, but not a shortcut form to use during assignment. Ruby has a logical or assignment operator that we can use with nil and false (the only falsy values in Ruby). It feels strange that Ruby does not have a null coalescing operator, so if we want to be strict and deal only with null (nil), we have to use the so rich Ruby syntax differently:
# for null coalescing assignment
# like JavaScript: a = a ?? "default"
# or Kotlin: a = a ?: "default"
a = "default" if a.nil?
# or
a = a.nil? ? "default" : a
Reached this point I think it'll be good to remember what are considered falsy values (those that, when evaluated in a boolean context, are considered as false) in different languages:
- JavaScript: false, null, undefined, 0, ""
- Python: False, None, 0, "", [], {}, set()
- Rubynil, false
- Kotlinfalse. Kotlin does NOT perform truthy/falsy coercion, it's fully, strictly typed:trying to use a non boolean value in a condition causes a compilation error.
As you can see the main (and very important) difference between JavaScript and Python is that in Python empty containers are falsy.
No comments:
Post a Comment