It is already possible to use functions with lambda bodies as class properties:
class C {
currentTime = () => Date.time();
}
Perhaps they could also be used with getters and setters?
class C {
..
get currentTime = () => Date.time();
set endTime = (time) => this.timer.setEndTime(time);
}
_Edit_: or using an even cleaner syntax suggested by @kitsonk
class C {
..
get currentTime() => Date.time();
set endTime(time) => this.timer.setEndTime(time);
}
Since getters and setters (especially getters) are frequently one-liners, this may turn out to be a very handy feature.
I'm not sure whether ES6/7 already supports/plans to support this though, but if this would turn out to make sense in general, perhaps they could consider it as well?
I suspect that will be challenging because arrow functions refer to lexical this... so this wouldn't be pointing to what you thought it would be. It wouldn't be the instance. Obviously TypeScript when targeting ES5 could fix that, but how would you suggest emitting for ES6 work? Also, because people expect arrow functions to have lexical this, I suspect a lot of people would find it _surprising_ to have it not refer to the class instead of the instance.
Also, accessors are assigned like this in ES6 Classes (which is a single line by the way):
class C {
get currentTime() { return Date.time(); }
}
So I would suspect it would be more like:
class C {
get CurrentTime() => Date.time();
}
@kitsonk
I liked the alternative syntax you mentioned, that omits the =:
get currentTime() => Date.time();
I haven't thought that much about the this scoping, but in Typescript this inside an arrow/lambda function should refer to the enclosing context (in this case I guess the class instance). If I'm not mistaken that would be called "lexical this".
I have tested it and can confirm it is the case with arrow functions assigned to class properties:
class C {
num = 1;
mul = () => { this.num *= 2 };
}
let c = new C();
c.mul(); // c.num is now 2
c.mul(); // c.num is now 4
And that should also be the case in ES6 (MDN)? Unless I misunderstood something?
Lexical this
Until arrow functions, every new function defined its own this value (a new object in case of a constructor, undefined in strict mode function calls, the context object if the function is called as an "object method", etc.). This proved to be annoying with an object-oriented style of programming.
...
Arrow functions capture the this value of the enclosing context, so the following code works as expected.
In the older style syntax function () { this.num *= 2 }, this would try to access the function object itself, and at that case this.num would be undefined and *= 2 may result in a runtime error.
Just comparing the arrow function version to the existing ES6 syntax:
class C {
// Saves 5 characters
get currentTime() { return Date.time(); }
get currentTime = () => Date.time();
// Is 1 character longer
set endTime(time) { this.timer.setEndTime(time); }
set endTime = (time) => this.timer.setEndTime(time);
}
It's not worth adding a new syntax with no new semantics for the sake of less than a tab's worth of characters on average.
@RyanCavanaugh
It's not just about saving typing, it's also about readability and general "cleanness". Omitting return and curly brackets yields cleaner, more readable code. The version by @kitsonk, which omits the = looks even more cleaner.
I think that's a matter of taste and style preference. If the TypeScript team (and EcmaScript) see this as unnecessary, that's fine. I just hope it's not just the opinion of one person.
Also, it seems like the C# team thought otherwise when they added expression bodied members in C# 6, which also supports getters (but not setters, it seems). I'm surprised this was turned down so quickly here.
I'm not sure why this was marked as "Too Complex" though. It's a very simple feature.
@rotemdan the 'Too Complex' label is more accurately 'Too Complex Relative to Value Added' but that is a mouthful for a label name :) This is sort of relevant http://blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
I just hope it's not just the opinion of one person.
ECMAScript is defined by committee, so it's safe to say it's nearly the opinion of a bunch of people and the actual opinion of no one :wink:
Just in terms of TypeScript, we don't want to add duplicative syntax unless it's absolutely necessary. If enough people care about getters and setters having alternate syntax for bikeshed reasons, that discussion will happen organically in the ES committee.
@RyanCavanaugh where would you recommend we suggest this in the ES committee? I've never interacted with them, but for this would like to.
Although this issue is already closed, it should also be noted that the proposed concept blends very nicely with C# 6 syntax:
// Either is cleaner than the built-in, yes?
class Pair<T> {
public stringified => `${this.first} ${this.second}`;
public toString() => `${this.first} ${this.second}`;
}
Edit: Also, get currentTime() { return Date.time(); } and set endTime(time) { this.timer.setEndTime(time); } violate common tslint preference for endlines.
where would you recommend we suggest this in the ES committee? I've never interacted with them, but for this would like to.
Most helpful comment
@RyanCavanaugh
It's not just about saving typing, it's also about readability and general "cleanness". Omitting
returnand curly brackets yields cleaner, more readable code. The version by @kitsonk, which omits the=looks even more cleaner.I think that's a matter of taste and style preference. If the TypeScript team (and EcmaScript) see this as unnecessary, that's fine. I just hope it's not just the opinion of one person.
Also, it seems like the C# team thought otherwise when they added expression bodied members in C# 6, which also supports getters (but not setters, it seems). I'm surprised this was turned down so quickly here.
I'm not sure why this was marked as "Too Complex" though. It's a very simple feature.