Skip to content
This repository has been archived by the owner on Feb 19, 2018. It is now read-only.

CS2 Discussion: Output: Super - CS vs ES6 semantics #68

Closed
mrmowgli opened this issue Dec 28, 2016 · 7 comments
Closed

CS2 Discussion: Output: Super - CS vs ES6 semantics #68

mrmowgli opened this issue Dec 28, 2016 · 7 comments

Comments

@mrmowgli
Copy link

Currently we have classes working in connec's branch pull #4354 (read the comments) - however as we go through the tests and compatibility with ES6 classes there are a lot of edge cases around super. In particular how ES6 (currently) handles super.

The basics of ES and super:

  • super() needs to be called in a constructor for this to exist
  • super() can't be used in an bound ES constructor function () =>
  • super can't be called from an external constructor
  • super can't be called more than once in a constructor
  • super can be called in overridden methods, the syntax becomes super.methodName()

This leads to some definite breaks in how the original CS classes operated, but probably the biggest restriction is the first one: super() needs to be called in a constructor for this to exist. The reason this becomes an issue is a pretty common use case: @ parameters.

For example the following code won't compile:

class A

class B extends A
  constructor: (@name) ->

This is because to refer to @name we actually have to make a super() call. connec played with the idea of automatically inserting a super() in the generated code, which required hoisting it to the top of the method. This unfortunately means that a parent constructor is getting called without your knowledge, leading to unpredictable inheritance. You might not want to call the original constructor, but by using @ parameters you inadvertently call into the parent, potentially without fulfilling it's signature requirements.

In addition, the following leads to a race condition:

class A
  constructor(@name)

class B extends A
  constructor: (@name) ->
    super(@name)   

since the @name parameter requires this within the super call.

I understand that sneaking a super() into the constructor transparently can be an issue, but is there a way to make this available in a subclass without super? Perhaps a blend of the original CS and ES6?

I personally would want to keep as much of the existing CS syntax as possible.

Thoughts?

@triskweline
Copy link

Two more ES/super facts that are relevant to this decision:

  • If the constructor of a child class does not call super, the constructor is expected to return an object. The returned object is used in place of the object that was not constructed (sic).
  • If you neither call super in the constructor, nor return an object to use instead, a ReferenceError is thrown.

So we either must call super (by either automatically inserted or by forcing the developer to not forget) or support overriding of constructors.

@edemaine
Copy link

Instead of automatically calling super, can we just set this to a blank object (of the right type... perhaps this is what @henning-koch means about constructor overriding) and return it at the end? At least for constructors in subclasses that don't call super...

@connec
Copy link

connec commented Dec 29, 2016

@edemaine do you mean something like

class B extends A
  constructor: (@param) ->
    console.log @param

becoming

class B extends A {
  constructor (param) {
    var this1
    this1 = Object.create(B.prototype)
    this1.param = param
    console.log(this1.param)
    return this1
  }
}

?

@edemaine
Copy link

@connec Yes, except I think you need to return this1 at the end.

@connec
Copy link

connec commented Dec 29, 2016

Good point, updated for reference.

@GeoffreyBooth
Copy link
Collaborator

Closed via jashkenas/coffeescript#4424.

@coffeescriptbot coffeescriptbot changed the title Super - CS vs ES6 semantics CS2 Discussion: Output: Super - CS vs ES6 semantics Feb 19, 2018
@coffeescriptbot
Copy link
Collaborator

Migrated to jashkenas/coffeescript#4961

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants