Skip to content

'it' is not defined when referenced only by object literals? #899

Description

@dk00
->
  it.name
->
  it
  {it.name}
->
  {it.name}

compiles to:

// Generated by LiveScript 1.5.0
(function(it){
  return it.name;
});
(function(it){
  it;
  return {
    name: it.name
  };
});
(function(){
  return {
    name: it.name
  };
});

the third function has no argument

Another example:

t = ->
  (cb) ->
    it
// Generated by LiveScript 1.5.0
var t;
t = function(){
  return function(cb){
    return it;
  };
};

Activity

  1. WreckedAvent commented on Jun 8, 2016

    @WreckedAvent

    More complicated than just the object literal, it's something to do with the shorthand.

    ->
      { name: it.name }

    compiles to =>

    (function(it){
      return {
        name: it.name
      };
    });

    Similarly,

    -> { it }

    compiles to =>

    (function(){
      return {
        it: it
      };
    });
  2. summivox commented on Oct 25, 2016

    @summivox
    Contributor

    From code readibility point of view I don't like t = -> (cb) -> it implying it in the outermost func. IMHO it is intended for short and simple expression lambdas (that cannot be expressed with the more concise partially-applied operator syntax), not any arrow function that has a single param, and certainly not across function scopes.

    I wish we could:

    • deliberately limit it inference to direct function scope
    • emit warning/error on nested it functions e.g. t = -> alert it; do -> alert it or example above.
  3. rhendric commented on Oct 25, 2016

    @rhendric
    Collaborator

    My reading of the it feature (which, modulo this bug, seems to agree with lsc) is that it always refers to the first argument of the innermost function; so -> (cb) -> it should have it == cb. A warning in cases like this might be nice, but should only be reserved for cases where it's very likely the programmer is confused, IMO.

    (I have a fix for this bug that's part of a slightly larger unit of work; I'll be PRing it one of these days, either with that work or separately.)

  4. summivox commented on Oct 25, 2016

    @summivox
    Contributor

    @rhendric : I beg to differ. it === cb is aliasing. You already have a name for the first parameter of the inner arrow function; it is confusing to have a second implicit name for it. It does avoid the cross-scope problem (i.e. it is always local function scope).

    My understanding (which of course does not agree with LSC master) had been:

    the unnamed implicit single argument of the innermost function without an explicit parameter list

    i.e. -> (cb) -> it compiles to (it) -> (cb) -> it. Note that I'm not advocating for this, nor do I write code like this -- I am trying to point out to part of the confusion.

    As for a stricter syntax, I believe we should emit warning/error when:

    • it is found in a function with an explicit parameter list but not assigned anywhere in the lexical scope (honestly I would even remove the "but" clause to make it stricter)
    • a function that contains implicit it is nested in a function that also contains implicit it

    Regardless I'm looking forward to your big chunk of change ;)

  5. rhendric commented on Oct 26, 2016

    @rhendric
    Collaborator

    Upon revisiting this, it appears that I had entirely imagined this aliasing feature! I thought that was how things worked already in some cases, but I'm quite happy that it isn't. For the record, I retract my ‘should’ above: -> (cb) -> it is already compiling exactly how I think it should (plus or minus a warning/error), with the it assumed to be a variable in an outer scope or on the global object.

    I'll hold further opining on issuing warnings or errors for possibly confusing uses of it until that proposal gets its own issue. 😃

  6. dk00 commented on Dec 20, 2016

    @dk00
    ContributorAuthor

    name: it.name parses to:

      Obj
        Prop
          Key name
          Chain
            Var it
            Index .
              Key name
    

    {it.name} compiles to the same, but parses differently:

      Obj
        Prop
          Key name
          Chain
            Key it
            Index .
              Key name
    

    it should be Var, but the parser gives Key. Maybe we should convert the shorthand to the same AST?

    that also does the same, as expected.
    data = {that.name} if result compiles to:

    if (result) {
      data = {
        name: that.name
      };
    }
  7. added a commit that references this issue on Dec 26, 2016
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions