Skip to content

Instantly share code, notes, and snippets.

@geraldalewis
Created May 10, 2011 23:42
Show Gist options
  • Save geraldalewis/965625 to your computer and use it in GitHub Desktop.
Save geraldalewis/965625 to your computer and use it in GitHub Desktop.
CoffeeScript issue #1216 ?= compilation Notes

##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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment