Skip to content

repl: Failed assignment "blocks" further assignments to a variable name #6118

Closed

Description

@dodev

Hi!

On an assignment statement TypeError, using the same variable name is not possible due to either Reference or TypeError when trying to assign a value to a variable with that name.

Steps:

  1. Assign to a variable with statement which causes TypeError ((let|const|var) a = Math.PI())
  2. Try to assign to the same variable name using let|const|var OR try to use the variable;

Result:
The variable name is no longer available, because you get a TypeError: Identifier has already been declared OR ReferenceError: variable is not defined if you try to use the variable name

Expected Behavior:
The variable name to remain undeclared.

Sample Output:

> let c = 1;
undefined
> let a = c();
TypeError: c is not a function
    at repl:2:9
    at REPLServer.defaultEval (repl.js:269:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:439:12)
    at emitOne (events.js:95:20)
    at REPLServer.emit (events.js:182:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)
    at REPLServer.Interface._ttyWrite (readline.js:827:14)
> let a = 1;
TypeError: Identifier 'a' has already been declared
    at repl:1:1
    at REPLServer.defaultEval (repl.js:269:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:439:12)
    at emitOne (events.js:95:20)
    at REPLServer.emit (events.js:182:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)
    at REPLServer.Interface._ttyWrite (readline.js:827:14)
> a = 1;
ReferenceError: a is not defined
    at repl:1:3
    at REPLServer.defaultEval (repl.js:269:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:439:12)
    at emitOne (events.js:95:20)
    at REPLServer.emit (events.js:182:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)
    at REPLServer.Interface._ttyWrite (readline.js:827:14)
> 

Activity

  1. added
    replIssues and PRs related to the REPL subsystem.
    on Apr 8, 2016
  2. changed the title [-]repl: Failed assignment "blocks" further assignemts to a variable name[/-] [+]repl: Failed assignment "blocks" further assignments to a variable name[/+] on Apr 8, 2016
  3. Fishrock123 commented on Apr 8, 2016

    @Fishrock123
    Contributor

    The current behavior is technically semantic, but this is a repl so I agree it is somewhat poor usability.

    Ideally if you did const x; it would delete the existing x, even if it was const, and make the new declaration.

    I'm not actually sure this can be fixed though, because I'm pretty sure it's interpreted to the VM like a script. 😕

  4. jasnell commented on Apr 8, 2016

    @jasnell
    Member

    +1 this has been somewhat of an irritation for me for a while. Just not convinced that it is something that can be fixed in Node.js as I believe it's a v8 issue (Chrome gives precisely the same error). Quick test in the Chrome dev console shows:

    const m = n
    VM192:1 Uncaught ReferenceError: n is not defined(…)
    const m = 1
    VM221:1 Uncaught TypeError: Identifier 'm' has already been declared(…)
    
  5. Fishrock123 commented on Apr 8, 2016

    @Fishrock123
    Contributor

    It originates in v8 I think, but I doubt it is an "issue" on that level, it's just how the language semantics work.

    Maybe we could give short errors for redeclarations in the REPL along with a more informative message.

  6. dodev commented on Apr 8, 2016

    @dodev
    ContributorAuthor

    @jasnell In chromium's repl I get a different behavior, than the one I get in node. But it is unexpected non the less:

    > const q = 1();
    VM481:2 Uncaught TypeError: 1 is not a function(…)(anonymous function) @ 
    > const q = 1;
    undefined
    > q
    VM520:2 Uncaught ReferenceError: q is not defined(…)(anonymous function) @ 
    
  7. jasnell commented on Apr 8, 2016

    @jasnell
    Member

    Sigh.. gotta love consistency. +1 to seeing if we can at least improve the errors in REPL.

  8. lance commented on Apr 25, 2016

    @lance
    Member

    This seems to be a side effect of the way Javascript evaluates let and const declarations as defined by the spec: http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations. Based on this grammar, I can see why const would behave this way, since the variables are "created when their containing Lexical Environment is instantiated". So for const, it seems the variable is created, but when the exception is thrown, it's the lingering const reference cleaned up. But I'm kind of spitballing here, since let variables can be reassigned, and so should not throw a ReferenceError when reassigned.

    Without digging too much, it almost seems like a V8 bug to me, but a quick search of the bug tracker doesn't shed any light: https://bugs.chromium.org/p/v8/issues/list?can=1&q=assignment+exception&colspec=ID+Type+Status+Priority+Owner+Summary+HW+OS+Component+Stars&x=priority&y=owner&cells=ids

  9. jasnell commented on Apr 25, 2016

    @jasnell
    Member

    Yep, there's actually nothing we can do on this one in Node except maybe make the error a bit more informative. There has been at least one other issue about this reported. Going to close this as it's not something we can fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    replIssues and PRs related to the REPL subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions