2
class A 
   constructor: ->
   method: ->

In the above example, method is not bound to the class and neither is constructor.

class B 
   constructor: ->
   method: =>

In this case, method is bound to the class. It behaves as you expect a normal object method to behave and has access to all of class B's fields. But the constructor is not bound? That seems strange. So i tried the following.

class C 
   constructor: =>
   method: =>

This doesn't compile. I would expect the syntax to be the same on all methods that are bound to a class.

I would like to regard the -> operator as a static operator and the => operator as a dynamic operator. But it doesn't seem like you can. If you could, a method with the -> operator could not be called with super. But, in actuality, you can. Why does this make sense for the syntax of an object oriented language? This seems to not agree with most object oriented languages inheritance rules.

Paul Nikonowicz
  • 3,883
  • 21
  • 39

2 Answers2

4

Try looking at how the code compiles. When you use =>, the methods are bound inside the constructor. Thus, it doesn't make any sense to use => for a constructor - when would it be bound?

I'm not sure about your issue with static vs. dynamic operators, but you can definitely call methods defined with the -> operator with super. The only thing -> vs => affects is that the => ensures that this is the object in question regardless of how it is called.

Summary of comments:

Calling the difference between -> and => analogous to static vs. dynamic (or virtual) does not quite convey what those operators do. They are used to get different behavior from javascript's this variable. For example, look at the following code:

class C
  constructor: ->
  method1: ->
    console.log this
  method2: =>
    console.log this

c = new C()

c.method1()        //prints c
f = c.method1;f()  //prints window

c.method2()        //prints c
f = c.method2;f()  //prints c

The difference is in the second way we call each method: if the method is not "bound" to the object, its this is set by looking at what precedes the method call (separated by a .). In the first case, this is c, but in the second f isn't being called on an object, so this is set to window. method2 doesn't have this problem because it is bound to the object.

Normally, you can think of the the constructor function automatically being bound to the object that it is constructing (thus, you can't bind it with =>). However, its worth noting that this isn't quite what's happening, because if a constructor returns an object, that will be the return value of the construction, rather than the this during the constructor.

Aaron Dufour
  • 17,288
  • 1
  • 47
  • 69
  • what i mean by static vs dynamic is that a static method cannot be overridden whereas a dynamic method you can. Instead of dynamic maybe i should say virtual? – Paul Nikonowicz Feb 17 '12 at 15:43
  • I don't think either of those concepts map to the differences between `->` and `=>`. They have to do with weirdness in javascript's `this` variable. – Aaron Dufour Feb 17 '12 at 15:58
  • ya, i get that. but putting the fact that the language is compiled to javascript aside so that we can evaluate coffeescript directly, do these syntax rules make sense? – Paul Nikonowicz Feb 17 '12 at 16:02
  • 1
    I think so, and I'll try to explain it. The `=>` operator is useful so that when you say `c = new C();f = c.method;f()`, the `this` variable in the `c.method` function is `c` as one would expect. Without binding with `=>`, the `this` variable in the `c.method` function will be `window`. In the constructor, you don't have an object yet, so it doesn't make sense to "bind" the constructor - there's nothing to bind it to. – Aaron Dufour Feb 17 '12 at 16:12
  • @AaronDufour instead of "there's nothing to bind it to" you can think of it as *already* bound to the new object - that's what makes it a *constructor* function. – Ricardo Tomasi Feb 17 '12 at 20:00
  • @RicardoTomasi You can think about it that way if it helps, but it might be worth knowing that that's not how constructor functions work in javascript. If a constructor `C` returns an object, the returned object, as opposed to the `this` object in the scope of the constructor, is what is returned by `new C()`. – Aaron Dufour Feb 17 '12 at 22:36
  • Can someone summarize these comments into the answer and i will close the question? This is all very good. Thank you all. – Paul Nikonowicz Feb 18 '12 at 03:13
  • @PaulNikonowicz That summarizes it, I think. Let me know if I missed anything. – Aaron Dufour Feb 18 '12 at 17:45
  • @AaronDufour that's exactly how it works. The constructor function is called with a fresh object as it's context. If you return another object that's a different matter, it won't share the prototype either, you're throwing away the instance. See this question: http://stackoverflow.com/questions/6750880/javascript-how-does-new-work-internally. Returning a different object doesn't change the fact that the constructor function is always bound to the new instance. – Ricardo Tomasi Feb 23 '12 at 16:18
1

I think you're massively confused as to the meaning of the '=>', or fat arrow.

First off though, your examples aren't actually valid coffeescript, are they? There is no -> after the class declaration. Adding one is a compiler error.

Back to the fat arrow, there's no mapping to the terms static and dynamic that I can think of, that would apply here. Instead the fat arrow is a convenient syntactic sugar for wrapping a function with a closure that contains the reference to the object you're calling the function on.

The C++ analog is to possibly to say that the fat arrow is a method for automatically creating a functor: it lets you give the function as a callback to a third party who can call it without knowing your object, but where the code invoked inside will have access to your object as the this pointer. It serves no other purpose, and has no bearing on whether a function can be overloaded, or whether it can have access to super.

Chris Subagio
  • 6,099
  • 1
  • 15
  • 7