Thread overview | ||||||
---|---|---|---|---|---|---|
|
April 27, 2018 Things I found great about TypeScript that D could benefit from | ||||
---|---|---|---|---|
| ||||
Hello everyone! I haven't written a post in a long time. I love D, and I've been a D hobbyist for years now. Though I haven't written any D in a long time, I keep an eye on the changelogs and such. More recently I've been using TypeScript (TS) at work for front end code. TypeScript is a very different kind of beast, compared to D, but there are some features in TypeScript I now use every working day which have really improved the quality of the software that I write, and I'd like to share my thoughts on them. I'll explain a few things and then say what I think D could learn from TS. The first feature I found really useful is the --strictNullChecks option that TypeScript has. I hate null dereferencing errors with a passion, and they have been the number one source of bugs that I've seen. The TS type system with the option off effectively treats `T` as `T | null | undefined` with the option off, and excludes `null | undefined` with the option on, meaning it forces you to check for `null` or `undefined` where such values are possible, according to the type system. What I found really interesting is that TS implements null checking not through more traditional means like a "Maybe" or "Option" monad, but through typical syntax. If you write `if (x != null) { }`, then TS narrows the type from `T | null | undefined` to just `T` inside of that if statement. This also works for more complex syntax, such as breaking a loop, returning early if something is null and pressing on if it isn't, inside expressions like `x != null && x.y`, and so on. I could never get colleagues on board with changing all of their code to use Maybe/Option types, but this kind of syntax is something they don't even have to think about. The second feature I found very useful is that TS uses "structural typing." You declare an interface with some properties, and any object which matches those properties is considered to be of that type. Meaning that TS doesn't care what the "class" or prototype of your object is, just that has the right stuff in it. This is essentially statically-checked duck typing. There is some algebra on types, so you can write `T & U` for something with the properties of types `T` and `U`, or `T | U` for either. What's very powerful about unions in TypeScript is that it automatically determines which fields can be used as tag attributes for tagged unions. This means you can declare tagged unions without thinking about writing a very specific tagged union type, and without using a special tagged union type. This largely works because of the nature of TS's basis on top of a dynamic type system where attribute lookup is all virtual. The third big feature I'll end on is just the quality of the tooling. There's great code completion, tools for fixing bugs, pretty good diagnostics, a protocol like LSP I integrated into Vim, etc. They have done a pretty good job of getting the tools right. What I think D could learn is pretty much... * Strict null checking is a winner, and you can use ordinary syntax to handle this. * Writing `(InputRange r)` instead of `(T)(T r) if (isInputRange!T)` would be a nice improvement, and writing something like this hypothetical `InputRange` concept could be a lot easier, somehow. (C++20 might finally include concepts.) * Good tooling makes everything better. Keep on working on good tools for D. That's it, let me know your thoughts. |
April 28, 2018 Re: Things I found great about TypeScript that D could benefit from | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Friday, 27 April 2018 at 19:17:14 UTC, w0rp wrote: > * Writing `(InputRange r)` instead of `(T)(T r) if (isInputRange!T)` would be a nice improvement, and writing something like this hypothetical `InputRange` concept could be a lot easier, somehow. (C++20 might finally include concepts.) There was a discussion of this here: https://forum.dlang.org/post/oju39p$1il3$1@digitalmars.com |
April 28, 2018 Re: Things I found great about TypeScript that D could benefit from | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On 28/04/2018 7:17 AM, w0rp wrote:
> Hello everyone! I haven't written a post in a long time. I love D, and I've been a D hobbyist for years now. Though I haven't written any D in a long time, I keep an eye on the changelogs and such. More recently I've been using TypeScript (TS) at work for front end code. TypeScript is a very different kind of beast, compared to D, but there are some features in TypeScript I now use every working day which have really improved the quality of the software that I write, and I'd like to share my thoughts on them. I'll explain a few things and then say what I think D could learn from TS.
>
> The first feature I found really useful is the --strictNullChecks option that TypeScript has. I hate null dereferencing errors with a passion, and they have been the number one source of bugs that I've seen. The TS type system with the option off effectively treats `T` as `T | null | undefined` with the option off, and excludes `null | undefined` with the option on, meaning it forces you to check for `null` or `undefined` where such values are possible, according to the type system.
>
> What I found really interesting is that TS implements null checking not through more traditional means like a "Maybe" or "Option" monad, but through typical syntax. If you write `if (x != null) { }`, then TS narrows the type from `T | null | undefined` to just `T` inside of that if statement. This also works for more complex syntax, such as breaking a loop, returning early if something is null and pressing on if it isn't, inside expressions like `x != null && x.y`, and so on. I could never get colleagues on board with changing all of their code to use Maybe/Option types, but this kind of syntax is something they don't even have to think about.
>
> The second feature I found very useful is that TS uses "structural typing." You declare an interface with some properties, and any object which matches those properties is considered to be of that type. Meaning that TS doesn't care what the "class" or prototype of your object is, just that has the right stuff in it. This is essentially statically-checked duck typing. There is some algebra on types, so you can write `T & U` for something with the properties of types `T` and `U`, or `T | U` for either.
Signatures, I've got a DIP for this.
Only this is a pretty basic feature of it.
|
April 28, 2018 Re: Things I found great about TypeScript that D could benefit from | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Friday, 27 April 2018 at 19:17:14 UTC, w0rp wrote: > The first feature I found really useful is the --strictNullChecks option that TypeScript has. I hate null dereferencing errors with a passion, and they have been the number one source of bugs that I've seen. > * Strict null checking is a winner, and you can use ordinary syntax to handle this. > That's it, let me know your thoughts. Non-null class references are my #1 missing D feature. :-) When we don't have to worry about null-or-not, we have our mind free for the interesting problems. I love to peek around other languages and see how they tackle this problem. Thanks for the TS overview! You advocate automatic narrowing inside if (x != null) even over Optional types. Is it because you find automatic narrowing cleaner than Optional? Or do you simply consider automatic narrowing a worthwhile addition whether or not a language has non-null + Optional? ``` void f(Optional!T x) { if (x !is null) g(x); } void g(T x) { h(x); } void h(T x) { writeln(x.myField); } ``` With a strictly non-nullable T, you can write `g` and `h` cleanly and null-safely. Without non-nullable types, even with implicit narrowing, both `g` and `h` would need an if/get or optional dispatch, complicating their definition. -- Simon |
Copyright © 1999-2021 by the D Language Foundation