##Notes##
Update The Existential Operator
in docs
###Ticket Bug###
There's a bug in the ticket -- if(a != null) a = b;
should be if(a == null) a = b;
Of the two options:
a != null || (a = b); # 22 chars; clever
if(a == null) a = b; # 21 chars; more easily understood? (a virtue for the output JS?)
I like the second. (one less char, more easily understood)
###Compilation difference###
Ticket and -bpe
disagree on compilation; currently compiles to:
var a;
a = 0;
if (a != null) {
a;
} else {
a = b;
};
This is because of commit e84e703211dfc5af3653462cdba066cad4bcffb4 by @thejh for #1108
#1108
"[v] = a ? b" must compile to
v = (typeof a != "undefined" && a !== null ? a : b)[0];
and not to:
v = typeof a != "undefined" && a !== null ? a : b[0];
###Threequals###
if (a != null) {
a;
} else {
a = b;
};
Shouldn't that be a !**==** null
?
Yes, but unfortunately, it won't work; see #Challenges section
039109ed56d3b70f6118fba86f23a98a9881e335 and d5a5f9572e353f4d82f58b43cd172c74142616c4
@jashkenas made these changes "for consistency"
from
"typeof #{code} == \"undefined\" || #{code} == null"
"typeof #{code} != \"undefined\" && #{code} != null"
to
"typeof #{code} === \"undefined\" || #{code} === null"
"typeof #{code} !== \"undefined\" && #{code} !== null"
@michaelficarra asked about the change, and @jashkenas then modified all instances of == "undefined"
to === "undefined"
in commit d5a5f9572e353f4d82f58b43cd172c74142616c4
##Challenges##
###Inverting the comparison###
foo = 0; foo?
compiles to var foo; foo = 0; foo != null;
foo = 0; foo ?= bar
compiles to:
var foo;
foo = 0;
if (foo != null) {
foo;
} else {
foo = bar;
};
so if we want to make the compiled output:
var foo;
foo = 0;
if (foo === null) foo = bar;
we need to make sure we don't also make foo = 0;foo?
compile to var foo; foo = 0; foo === null;
i.e., we need to invert the test when and only when we're compiling a ?=
Op
class was given an @isExistentialEquals
property to differentiate it from a vanilla ?
operation
###Strict Equality### Changing the comparison to strict equality for existential assignment for functions with a defined local var
(e.g.,
"#{code} #{if @negated then '==' else '!='} null"
to ->
"#{code} #{if @negated then '===' else '!=='} null"
)
broke existing code with the following error:
dev:coffee-script$ bin/cake build:full
lib/coffee-script.js:34
throw err;
^
TypeError: In Cakefile, Cannot read property '0' of undefined
at Rewriter.tag (lib/rewriter.js:337:53)
at Rewriter.<anonymous> (lib/rewriter.js:70:57)
at Rewriter.scanTokens (lib/rewriter.js:30:20)
at Rewriter.removeMidExpressionNewlines (lib/rewriter.js:68:19)
at Rewriter.rewrite (lib/rewriter.js:14:12)
at Lexer.tokenize (lib/lexer.js:37:29)
at lib/c
Cakefile:72
throw err;
... maybe a ticket for another day.
##Output##
###existentialEquals with locally scoped var defined###
bin/coffee -bpe 'a = 0; a ?= b'
was
var a;
a = 0;
if (a != null) {
a;
} else {
a = b;
};
now
var a;
a = 0;
if (a == null) {
a = b;
};
###existentialEquals with locally scoped var not defined###
bin/coffee -bpe 'a ?= b'
was
if (typeof a !== "undefined" && a !== null) {
a;
} else {
a = b;
};
now
if (typeof a === "undefined" || a === null) {
a = b;
};
###existential operator with locally scoped var defined###
bin/coffee -bpe 'a = 0; return unless a?'
(no change)
was
var a;
a = 0;
if (a == null) {
return;
}
now
var a;
a = 0;
if (a == null) {
return;
}
###existential operator with locally scoped var not defined###
bin/coffee -bpe 'return unless a?'
(no change)
was
if (typeof a === "undefined" || a === null) {
return;
}
now
if (typeof a === "undefined" || a === null) {
return;
}