The part about veering constantly to navigate the maze of internal politics is fascinating. The compromises he had to make, like not being able to put in on Github initially. The easy victories, like making TypeScript open source.
The long road to success. The obligatory advice for people writing new programming languages (Hint: Mostly, don't.). His opinion about creating a new language for AI (I agree with his insight, but still think it is possible).
Overall, well worth watching.
What's even more interesting is that Microsoft and Google were part of TC-39 at the time, and were the main opponents of ES4. While they had some rightful reasons to take this position, there's no way ES4 hasn't shaped TS in the end. Perhaps the lack of mention of any of this is due to that TypeScript might have been handed to Anders' team after the project vision and original design have developed (in the video, it is introduced as a continuation of "SharpScript"), but the interview still left me rather insatiated.
It infers types. If I do
const data = [
{ name: 'bob', age: 35, state: 'CA' },
{ name: 'jill', age: 37, state: 'MA' },
{ name: 'sam', age: 23, state: 'NY' },
];
Typescript knows data is an array of { name: string, age: number, state: string }. I don't have to tell it.Further, if I use any field, example
const avg = data.reduce((acc, { age }) => acc + age, 0) / data.length;
It knows that `age` is a number. If I go change data and add an age that is not a number it will complain immediately. I didn't have to first define a type for data, it inferred it in a helpful way.Further, if I add `as const` at the end of data, then it will know 'state' can only be one of `CA`, `MA`, `NY` and complain if I try to check it against any other value. Maybe in this case 'state' was a bad choice of example but there are plenty of cases where this has been super useful both for type safety and for code completion.
There's insane levels of depth you can build with this.
Another simple example
const kColors = {
red: '#FF0000',
green: '#00FF00',
blue: '#0000FF',
} as const;
function keysOf<T extends string>(obj: { [k in T]?: unknown }): readonly T[] {
return Object.keys(obj) as unknown[] as T[];
}
type Color = keyof typeof kColors;
const kAllColors = keysOf(kColors);
Above, Color is effectively an enum of only 'red', 'green', 'blue'. I can use it in any function and it will complain if I don't pass something provably 'red', 'green', or 'blue'. kAllColors is something I can iterate over all colors. And I can safely index `kColors` only by a ColorIn most other languages I've used I'd have to first declare a separate enum for the type, then associate each of the "keys" with a value. Then separately make an array of enum values by hand for iteration, easy to get out of sync with the enum declaration.
Also, I think there was some performance issue with too much inference? Could be wrong, could also be fixed.
1. can be read without a compiler, useful when reading PRs
2. They make the compiler work less, it's easier to check than infer
C#'s anonymous type shares some flexibility of structural type system even though it still a nominal type.
> A language would only need a single "newtype" or "nominal" keyword to create nominal types from structural types.
I think you also can add `structural` keyword & apply structural type system in generally nominal type system as well if we're talking about adding feature.If you have to define the Enums in one place and then repeat them all in another just to associate data with each one you’ve failed
A MINIMAL memory safe language. The less it has the better.
Rust without the crazy town complexity.
The distilled wisdom from C# and Delphi and TypeScript.
A programming language that has less instead of more.
Contrasted with TypeScript and C#, F# is smaller, more expressive, stricter, with mature pattern matching and type resolution baked in from the ground up. F# was years ahead of the major languages on what are increasingly looking like ‘the basics’ around ADTs and immutability in modern distributed computing. OCaml and F# capture the linguistic high points of VB, Delphi, and C# with a broad spectrum of OOP(-lite) approaches, and have led those languages by decades on functional constructs that result in meaningfully tighter code. With the benefit of hindsight some approaches clearly map better to cloud computing and system verification.
F# also sits parallel to lots of living C#, objectively we see ‘less is more’. Less code per line, fewer lines per solution, terser and more LLM-efficient language. Error rates and refactoring costs are also meaningfully better IME, but harder to quantify in general terms.
To be clear, the language has a GC then?
I do feel like there is a gap for a modern compiled, functional and garbage collected language.
Go isn't it because it lacks the functional constructs.
C# and Java aren't it because they depend on a VM.
Rust isn't it because of its difficult memory management.
Swift isn't it because it is so tied to Apple and their platforms.
But it isn't a need for most use cases, unless you want to do mobile development and meet app store policies. But even then, mature F# frameworks like Fable transpile your F# code to React & Cie.
setmetatable(_G, { __newindex = false, __index = false })
[0]: https://www.lua.org/manual/5.5/manual.html#2.2And for enums, using strings as enums was not a very efficient idea. I think JavaScript introduced Symbols for locked/hidden properties but also meant to use them as enums. It never worked either and then the sum type, union type feature of TypeScript made the whole community to keep using strings as enums. This is still a very bad idea, it is not ergonomic, it is prone to many problems, and very inefficient to compare strings instead of integers. But hey TypeScript tried to fix the problem and almost everyone rejected it. And so enum is now discontinued.
Rest of the changes to TypeScript came from almost any other language but C#, probably the biggest changes ever to happen to JavaScript came directly from CoffeeScript. And then I personally saw how each of these new changes --- one by one --- arrived at C#. For what I have seen firsthand by reading the TC39 proposals, each feature came from a different community and different programming languages, (think about null operators !/?, the nullish coalescing ??, the incoming pipes, fat arrows and lambdas, mixings) as JavaScript is the only language everyone has to use, and it has benefited everyone to have a language that has all the great things from all other languages.
C# language team is also really good. They did not do a lot of mistakes in the 25+ years. They are a very valid source of OO and OO-hybrid concepts. It is not only TS/JS but also Java and C++ who often look to C#.
The story was not to transform C# code to JS but to use C# to write the code in the first place and transpile it. Not for the sake of having .NET usage but for the sake of having a good IDE.
If my memory serves, .NET and WinFS were the two major forces that sunk Longhorn, and both have been given their walking papers after the reset [1].
.NET and C# have grown to be mature and well-engineered projects, but the road there was certainly not without bumps. It's just that a lot of the bad parts haven't spilled outside of Microsoft, thankfully.
Furthermore, couldn't the convergence of TypeScript towards C# be simply a result of shared goals and values of the two languages, especially considering they have the same principal designer?
The truth is that C# is probably the best designed mainstream language out there.
C# was known as a language with lowest amount of WTF per LoC
The sequence of turbo pascal / delphi / c# / typescript which brought us LSP as a sidekick (!) IMHO has benefitted the whole industry at least as much as "transpile c# to ecma script via typescript" . no. much much much more.
I do not see a problem with MS also having an internal use case .
you know I wouldn't stop using python "because" Guido now works at MS ...
By contrast, .NET is controlled by Microsoft (with veto over board decisions [2] and code changes [3]), integrates Microsoft's telemetry to send your data to Microsoft by default [4] and deliberately hobbles features to benefit Microsoft [5].
[1] https://peps.python.org/pep-0013/
[2] https://dotnetfoundation.org/about/policies/.net-foundation-...
[3] https://github.com/dotnet/runtime/blob/main/CONTRIBUTING.md