Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

`unless variable?` compiles to two different things. #2455

Open
Zegnat opened this Issue · 13 comments

7 participants

@Zegnat

Setting any variable depending on its own existence (checked with the existential operator ?) results in different JavaScript code depending on whether the variable has been assigned a value somewhere prior to the check. See code examples below.

I would expect the JavaScript output to be the same in both cases. Because both cases add the var statement and therefor neither has to check via typeof.


Input

a = {} unless a?

Output

var a;
if (typeof a === "undefined" || a === null) {
  a = {};
}

Input

a = a # Setting a to itself, the most pointless of variable assignments.
a = {} unless a?

Output

var a;
a = a;
if (a == null) {
  a = {};
}
@paulmillr

coffee checks if the variable was already declared, so this to be a proper way to me.

why the heck would someone assign var to itself?

@Zegnat

why the heck would someone assign var to itself?

You wouldn’t, that is just by example. Doing a = a does, as far as I know, nothing. Yet CoffeeScript seems to think it does something because it changes the output if considerably.

When I use input number 1 CoffeeScript adds var a;. So it knows a exists. So why does it check the typeof? I would expect the output from example two with the input of example 1. That’s what this is about.

@michaelficarra
Collaborator

In the first example, the test is made before the assignment, but the compiler should know that the declaration was hoisted above the test. Marking as bug.

@satyr
Collaborator

Related: #1500

@jashkenas jashkenas closed this in 56fe211
@jashkenas jashkenas reopened this
@matrinox

Still broken here
I think it just makes sense to keep the ? as an existential check only. None of this smart "this variable once defined can never be undefined" logic.

This code:

if a?.b?.c
  a.b.c

Compiles to:

var ref;

if (typeof a !== "undefined" && a !== null ? (ref = a.b) != null ? ref.c : void 0 : void 0) {
  a.b.c;
}

It's like it gives up after the first try...
Safe navigation is really great syntax that provides safety to developers. Would be nice to get this to check for undefined as well

@jashkenas
Owner

That's not broken.

If you really think it's broken, submit a failing test that proves it.

@vendethiel
Collaborator

Why was this issue reopened, by the way?

@jashkenas
Owner

It looks like the comments on that commit are why — but I'm not sure if they're still relevant or not.

@matrinox

Just curious if the purpose of the ? operator is to always check for null/undefined or just null. The website says the former but code output often produces the latter

@vendethiel
Collaborator

That's how != works -- differently from !==. It's in the FAQ and in a dozen other issues.

@matrinox

@vendethiel In Coffeescript, you can't do !== and they automatically convert != and isnt to !==. Ditto with ==/is becoming ===

@vendethiel
Collaborator

We're talking about generated code here, not coffeescript code.

@matrinox

I see, you're right @vendethiel. Thanks for the help! != null is false for undefined and void 0, as well as null

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.