[HN Gopher] The history of C# and TypeScript with Anders Hejlsbe...
___________________________________________________________________
The history of C# and TypeScript with Anders Hejlsberg [video]
Author : doppp
Score : 180 points
Date : 2026-01-27 17:07 UTC (5 days ago)
(HTM) web link (www.youtube.com)
(TXT) w3m dump (www.youtube.com)
| andrewstuart wrote:
| We need Anders to make one final language.
|
| 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.
| vaylian wrote:
| Sounds like golang to me
| andrewstuart wrote:
| Without the features I identified,yes, you're right!
| steve1977 wrote:
| Considering they used Go for the native compiler he might
| actually agree with you.
| LarsKrimi wrote:
| Oberon 07?
| appsoftware wrote:
| What would you take out of C# etc?
| littlecranky67 wrote:
| (not OP) I would take out mostly historic stuff, that is in
| there for backwards compat, that has been superseeded. But
| this could be achieved using linters.
| wvenable wrote:
| All non-generic container classes and nullable reference
| types.
| hirvi74 wrote:
| > _nullable reference types._
|
| What would you suggest instead? I quite like the nullable
| reference types, but I do know many get annoyed. My brain
| is often a scurry of squirrels, so I grew to become
| thankful for the nullable refs overtime.
| jborean93 wrote:
| I don't mind NRT but I hate dealing with C# projects that
| haven't set < Nullable>Enable</Nullable> in their csproj.
| It's not perfect because I know at runtime it can still
| be nullable but it's nice when the compiler does most of
| the checks for you.
| wvenable wrote:
| The compiler now _mostly_ solves this now but the
| abstraction is a little leaky.
|
| I heavily use nullable types but I always want them to be
| _declared_ nullable.
| aloha2436 wrote:
| > Rust without the crazy town complexity.
|
| To be clear, the language has a GC then?
| jayd16 wrote:
| I suppose it could have some kind of ARC. In theory some
| future languages could even have some hybrid approach? A high
| perf default but you can fallback to a GC allocation for hard
| things?
| AndrewDucker wrote:
| I'm pretty sure that there are multiple GC crates for Rust
| out there. But using them mixed in with non-GC variables
| presumably makes things more complex.
| gucci-on-fleek wrote:
| What about Lua? The language is very minimal, memory safe, and
| has Pascal-like syntax just like Delphi.
| ptx wrote:
| Lua's variables being global by default seems somewhat error-
| prone.
| gucci-on-fleek wrote:
| Agreed, but the recently-released v5.5 fixes that [0], and
| it's fairly easy to fix this in older versions with the
| following snippet setmetatable(_G, {
| __newindex = false, __index = false })
|
| [0]: https://www.lua.org/manual/5.5/manual.html#2.2
| andrewstuart wrote:
| verything is an off by one error in Lua.
| gucci-on-fleek wrote:
| Or conversely, everything is an off-by-one error in every
| other language :)
| ahartmetz wrote:
| *everythin
| blackoil wrote:
| I want something that will bring productivity of Delphi to Web.
| May be I am old now, but I could have built applications in a
| weekend in Access or Visual Basic that will take weeks now in
| latest web stack.
| pjmlp wrote:
| OutSystems, but it isn't cheap.
| rr808 wrote:
| Right? I was hoping webassembly would bring back some proper
| gui tools like this to avoid the whole JS/DOM but no luck so
| far.
| hirvi74 wrote:
| Blazor is pretty cool if you are into that kind of stuff.
| Mind you, you still might need the slightest tiny dash of
| JS, but depending on your needs, you might be able to get
| away from JS entirely.
| NetMageSCW wrote:
| ASP.Net Web Forms still exists, though it is deprecated.
| qingcharles wrote:
| Eh. I admit I just use AI now when I want to quickly build a
| web app like that. I built a huge content management system
| in a couple of hours that way.
|
| If you're talking Windows desktop apps like Delphi used to
| do, then Visual Studio WinForms is still just like that in
| 2026 and still getting updates.
| tester756 wrote:
| C# is way to go then
| tonyedgecombe wrote:
| >We need Anders to make one final language.
|
| 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.
| kryptiskt wrote:
| C# doesn't depend on a VM these days when it is AOT compiled.
| Same for Java, though C# is rather more user friendly in how
| it goes about it.
| trympet wrote:
| > C# doesn't depend on a VM these days when it is AOT
| compiled
|
| Maybe I'm being pedantic, but this is an oxymoron. Also the
| premise is incorrect. It's not like the VM is gone. Merely
| baked into the code at compile time. It compiles IL to
| native code. Same for IL2CPP. The VM is still there.
|
| The term "virtual machine" is confusing. I think you meant
| to say JIT compiler :-)
| rednb wrote:
| What you are looking for is called F#. You get native interop
| with C# and access to all .NET/C# libraries as a bonus. We
| use it as a daily driver for a complex B2B2C cloud platform.
| Sammi wrote:
| Does it not run in a VM?
| rednb wrote:
| Yes you are right, it does not properly support NativeAOT
| yet.
|
| 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.
| christophilus wrote:
| It can be compiled, but that's not the use case it was
| originally designed around, so it's not quite as first
| class an experience as with Go or Rust.
| NetMageSCW wrote:
| You can embed the framework into the application so it is
| a single distributable.
| EddieRingle wrote:
| Kotlin has a LLVM backend, among others.
| jorams wrote:
| There are plenty of languages in that niche you could be
| using. OCaml, Haskell, F#...
| fpsvogel wrote:
| Roc might be that language one day. Not yet because it's
| pre-0.1.
| metaltyphoon wrote:
| C#, with default tooling, can compile without needing a VM,
| for windows, macOS, linux and some other platforms.
| zigzag312 wrote:
| I wish that Nuget would show which packages are NativeAOT
| compatible.
| metaltyphoon wrote:
| It will probably get there one day since all BCL is
| annotated. Perhaps this is not done because you can have
| parts of the library be completely safe to use in AOT
| while another part not be.
| HumblyTossed wrote:
| That's the problem though. People want one language to be The
| One (tm) and that's just not possible. Your The One (tm)
| isn't mine.
| Sharlin wrote:
| The minimal memory-safe language is Go. Turns out it's too
| minimal for most.
| andrewstuart wrote:
| It's not memory safe.
| Findecanor wrote:
| Please elaborate. I've heard that you could break Go's
| memory safety through a race condition, but that's as far
| as my knowledge goes.
| bonesss wrote:
| On the .Net VM you're describing F#, mostly by virtue of being
| based on OCaml.
|
| 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.
| christophilus wrote:
| It's a great language. I just wish its compilation speed
| matched that of OCaml.
| pmkary wrote:
| Yeah exactly.
| pjmlp wrote:
| Hardly, even Turbo Pascal 7 for MS-DOS is more advanced than
| Go's type system.
| HumblyTossed wrote:
| You don't have to use all the features of C#. I make my living
| at it and don't touch a lot of them. The issue with C# is
| culture. They went full in on blog driven development so
| there's way too many people who will yell this is the way to do
| things this week.
| hirvi74 wrote:
| It's true. You will incur the wrath of C#'ers if your simple
| ToDo list app doesn't have a
| ToDoListItemRepositoryServiceFactory.cs and a minimum of 4
| separate layers in which one must update 20 files because you
| added a property to one class.
|
| Don't get me wrong, I still love C#/.NET. I use it everyday,
| but my god, has Swift been a breath of fresh air. The Swift
| community, when not whining about Swift UI, has been much
| less dogmatic in my experience.
| socalgal2 wrote:
| I don't know that many languages but, having been writing lots of
| typescript in the last 3 years there are so many things I love
| about it.
|
| 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 Color
|
| In 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.
| sfn42 wrote:
| Lots of languages can infer types. And your last example with
| the colors is just a dictionary.
| grumpyprole wrote:
| Most languages have poor support for structural types though.
| If you try and join two records together (like a SQL join),
| what will your favourite language infer then?
| sfn42 wrote:
| C# has anonymous types which is pretty much the same thing.
| Though I prefer to declare actual types for most usecases,
| I'll only use anonymous types for intermediate results and
| such.
| grumpyprole wrote:
| I certainly don't mean to knock nominal types. But I
| think structural types are more fundamental. A language
| would only need a single "newtype" or "nominal" keyword
| to create nominal types from structural types.
| lock1 wrote:
| Why structural is more fundamental?
|
| 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.
| KellyCriterion wrote:
| Claude is "very good" in applying >var< continuously :-D
| sheept wrote:
| dictionaries generally aren't guaranteed to contain an entry
| for every possible value of the key type. while you could
| implement the colors example with a dictionary, ideally you'd
| want the type system to assure that given a Color, there will
| be a string associated with it
| vips7L wrote:
| Sounds like enums with extra steps.
| epolanski wrote:
| Enums aren't type safe in typescript
| vips7L wrote:
| Sounds like a major flaw.
| socalgal2 wrote:
| it's Enuma associated with data without having to repeat
| yourself
|
| 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
| vips7L wrote:
| Maybe you can elaborate but enums in Java or Kotlin
| easily have data associated with them.
| enum class Color(val rgb: Int) {
| RED(0xFF0000), GREEN(0x00FF00),
| BLUE(0x0000FF) }
| fuzzy2 wrote:
| It's not a dictionary (type-wise). "as const" is the magic
| ingredient.
| grumpyprole wrote:
| What you are describing is structural types. It is indeed a
| mystery that these are so under used, especially as they are a
| cornerstone of type theory. Structural types are so useful that
| they creep into most languages in some way. Even in Java, the
| Kingdom of the Nouns, where the rulers refused to merge a pair
| class, functions essentially take tuple arguments and these
| tuples don't have to be named and defined. You can't return a
| tuple though, so there is an unfortunate asymmetry. In Haskell
| and OCaml, we like to describe functions in a structural way,
| so com.google.android.Predicate would be just "a -> Bool". You
| wouldn't have to convert your com.google.guava.Predicate. But
| even these languages lack structural records and variants and
| suffer for it.
| ngruhn wrote:
| By now I'm also convinced that structural typing is a better
| default. Nominal types are still useful to assign properties
| that are hard or impossible to encode with structure alone
| (e.g. string that is a valid email address) . But I haven't
| encountered any other examples yet, where I'm missing nominal
| types.
| octachron wrote:
| OCaml has structural variants in the form of polymorphic
| variants. On the product side, OCaml has objects, first-class
| modules, labelled tuples (since OCaml 5.4) which are all a
| form of structural records, with different trade-off in term
| of ergonomics.
| fuzzy2 wrote:
| Inferred types are really great, but I feel they do not scale.
| Inside a method/function? Generally fine, but the signature,
| including the return type, had better be explicit.
|
| Also, I think there was some performance issue with too much
| inference? Could be wrong, could also be fixed.
| g947o wrote:
| This. As soon as you need to use the type in another function
| (e.g. function parameter), you'll discover that it's better
| to just write it out.
| epolanski wrote:
| They do scale, but explicit types have two bonuses in my
| eyes:
|
| 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
| g947o wrote:
| Even though that works reasonably well, you may still want to
| explicitly define your types/interfaces. In this example, if I
| do need to hardcode the data instead of fetching it somewhere,
| I would define the interface with "state" being a union of
| values, because there is nothing that stops you from using
| `state: 'ABC'` which would be hard to discover.
| raw_anon_1111 wrote:
| Not surprisingly, C# worlds the same way with the only
| exception that you have to declare the variables as "var" but
| they are still strongly typed
| recursive wrote:
| Technically you're also allowed to use anonymously typed
| objects as inferred generic typed parameters in method calls.
| jeroenhd wrote:
| Type inference is part of every modern language. Structural
| typing not so much, though.
|
| Java has it through a compiler extension
| (https://github.com/manifold-
| systems/manifold/tree/master/man...) but I don't know many
| other languages that support this feature.
|
| As much as I dislike the entire Javascript runtime environment,
| I find TypeScript to be the best typing system out there for
| any imperative language.
| matt_kantor wrote:
| > I don't know many other languages that support this feature
|
| The other widely-used one is Go with its structurally-typed
| interfaces.
| rixtox wrote:
| If you feel that TypeScript, or hell even JavaScript, is becoming
| more alike C#, it's actually deliberately done by Microsoft in
| benefiting their ecosystem. In this interview they mentioned they
| had internal demands to convert/transpile C# into JavaScript or
| TypeScript. So by making these target languages more like C#, it
| directly benefits their need. But I don't think this should be
| the driving force in designing ECMAScript. When they are pushing
| a language feature, they have an unspoken internal goal, and
| every choice they make is to make JS/TS look more like C#, and
| they are more likely to dismiss proposals that preventing them
| from deliverying that goal. There's likely a bit of conflict of
| interest there.
| tester756 wrote:
| It sounds like conspiracy theory that they design TS/JS to
| convert from C# easier, huh.
|
| 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
| froh wrote:
| that's the "evil MS" perspective
|
| 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 ...
| oaiey wrote:
| Spot on.
| ptx wrote:
| Python has an elected steering council and core team. The
| governance process explicitly tries to avoid conflict of
| interest by disallowing more than two steering council
| members working for the same employer. See PEP 13 [1].
|
| 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
|
| [4] https://github.com/dotnet/sdk/issues/6145
|
| [5] https://github.com/dotnet/sdk/issues/22247
| no_wizard wrote:
| According to the docs, .NET 10 has hot reload via the cli,
| unless I'm misunderstanding something:
| https://learn.microsoft.com/en-
| us/dotnet/core/tools/dotnet-w...
| steve1977 wrote:
| Well, for one, benefiting Microsoft's ecosystem does not imply
| being detrimental to other ecosystems per se.
|
| 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?
| oaiey wrote:
| As a long term observer: definitely not a goal. But you have to
| be clear here: JavaScript and C# both are OO languages, both
| are having origins stories in Java/C++, both are facing the
| same niche (system development), same challenges (processor
| counts, ...) and so on. And then, you put teams on it which
| look left and right when they face a problem and then you
| wonder that they reuse what they like?
|
| 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.
| m132 wrote:
| > They did not do a lot of mistakes in the 25+ years
|
| 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.
|
| [1] https://www.theregister.com/2005/05/26/dotnet_longhorn/
| Sammi wrote:
| Are we mixing the language and the runtime here? C# the
| language seems weirdly free of weirdness and footguns.
| jayd16 wrote:
| Not only that, they went as deep as mixing in project
| issues with language design. A massive rewrite mixed with
| massive feature changes is always a tricky thing no
| matter the language.
| moron4hire wrote:
| .NET was already a going concern before Longhorn even
| started. What sank Longhorn was the fact that writing an OS
| from scratch is hard and maintaining compatibility with
| existing OSes in the process is even harder, especially
| when you're adopting a completely new architecture.
| Longhorn would have been a microkernel running 100% on the
| .NET runtime, mainline Windows is a monolithic kernel
| written in C++. I don't know how it would have ever worked,
| whether .NET was "perfect" or not.
| pjmlp wrote:
| See Android, or Meadows for alternative reality.
| moron4hire wrote:
| Android still runs on a monolithic kernel written in a
| memory-unsafe language. I'm finding it suprisingly
| difficult to find information on Meadow, other than it
| runs .NET DLLs as user-space applications, but nothing
| about the structure of the kernel.
|
| Longhorn was going to be more than that. Microsoft did
| have Singularity/Midori projects, started around the
| middle of Longhorn/Vista, and continued much longer after
| Vista released to build out the managed microkernel
| concept. It's been about a decade since they've put any
| work into it, though.
| pjmlp wrote:
| Microsoft wasn't even able to deliver that, which was my
| whole point.
|
| Joe Duffy mentions on a talk, that even with Midori
| running production workloads, Windows team could not be
| changed their mind.
|
| Meadow uses a C++ based microkernel, the whole userspace
| is based on .NET, by the way.
| senderista wrote:
| No, Longhorn was neither a microkernel nor was the kernel
| rewritten in .NET.
|
| Source: I was there.
| oaiey wrote:
| I think he confuses longhorn with Singularity research
| project.
| pjmlp wrote:
| Nope, what sunk Longhorn was politics.
|
| Windows team is a C++ kingdom, and those devs will not
| adopt .NET even at gun point.
|
| They redid Longhorn with COM and called it WinRT, irony of
| ironies, WinRT applications run slower than .NET with COM
| reference counting all over the place.
|
| Google has showed those folks what happens when everyone
| plays on the same team, and now it owns the mobile phone
| market, a managed userspace with 70% world market.
| oaiey wrote:
| The article is presenting some stuff mixed up. Had nothing
| to do with the language or the framework. WinFS was a
| database product. Over engineered and abstract.
|
| .NET and C# were researched a lot for operating system
| usage (Midori, Singularity) but that was after Longhorn.
|
| The operating system group UI toolkits was a further
| problem and they pivoted there dozen of times in the years.
| Particular for a C++ based os group.
|
| But the death of longhorn was ultimately about the security
| restart of Bill Gates
| epolanski wrote:
| C# is inherently OOP oriented and it's type system works
| completely differently.
| pmkary wrote:
| Not at all. Before the use of TypeScript exploded, they had two
| features brought into it from C# which were namespaces and
| enums (both of which are amazingly good features. For the first
| one, no one knew what was the right choice back then. We had
| almost a dozen different module systems and TypeScript had gone
| their way to support all of them and namespaces were their own
| solution to the mess (remember they were trying to solve their
| own problems at first, it wasn't to dominate anything). I
| personally used namespaces and I could have only the TypeScript
| compiler running and producing a single JS file for rapid
| development without the burden of --- then very slow ---
| webpack.
|
| And 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.
| pdevr wrote:
| I watched this last week.
|
| 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.
| m132 wrote:
| Surprising to me that (in the context of TypeScript) ECMAScript
| 4, ActionScript, and Google Closure were not mentioned!
| Especially the first two; Macromedia/Adobe and Netscape/Mozilla
| have been working on baking TypeScript into JavaScript proper for
| a whole decade before HTML5, the mobile boom, and the associated
| problems have emerged. ES4/AS3 even had a nearly identical
| syntax.
|
| 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.
| epolanski wrote:
| Out of the big 4 involved in typescript, only one was involved
| with the tc39
| pier25 wrote:
| > _ES4 /AS3 even had a nearly identical syntax._
|
| Yeah. As someone who lived that era it was so frustrating that
| they abandoned ES4. I used AS3 daily for almost a decade until
| Adobe abandoned ActionScript4 and Flash Next around 2015.
| afavour wrote:
| I worked on a web app that used AS3 and Adobe Flex for UI.
| It's crazy to think about how powerful that framework was and
| it was twenty years ago now.
|
| No, it was never right for public facing web sites but it
| shined making internal admins. HTML5 still hasn't matched it.
|
| EDIT: turns out Flex still lives on as Apache Royale:
| https://royale.apache.org/ wish I had an excuse to take it
| for a spin.
| theusus wrote:
| Wasn't he fired by MS?
| algorithmsRcool wrote:
| No. He is a Microsoft Technical Fellow and still a core
| contributor to the TypeScript compiler.
| CharlieDigital wrote:
| I started my career doing ~20 years of C# from pretty much the
| very beginning (JavaScript even before then!).
|
| Around 2020, I switched into the startup space and quickly picked
| up TypeScript since that's "what the kids use". It wasn't without
| struggles, but once I wrapped my head around TypeScript as
| "shapes for JavaScript", it clicked.
|
| At the time, the startup was undertaking a new product built on
| Nest.js[0] which looked awfully similar to ASP.NET web APIs which
| had the benefit of being much more mature, complete, and with one
| of the best ORMs (EF Core). I suggested it to the team and was a
| bit shocked by the pushback.
|
| It ultimately inspired me to do a bunch of writing [1][2] on just
| how similar these two languages are and how they've converged on
| syntax (no doubt owing to Anders at the helm). Of course, they
| ultimately still have quite a bit of a gap, but for teams that
| are working in TS and finding that they are outgrowing it, C# is
| a very natural choice.
|
| I left that startup after a short stint, but boomeranged almost 3
| years later. Company went from seed to series C in that time. End
| of last year, we started the migration from TypeScript on the
| backend to C# on the backend and haven't looked back. The
| toolchain is far simpler and stable, the "default" ORM is far
| more flexible and powerful, the more rigorous type chain seems
| more conducive for agent-driven coding. Team adapted relatively
| quickly within ~4 weeks.
|
| [0] https://nestjs.com/
|
| [1] https://typescript-is-like-csharp.chrlschn.dev/
|
| [2] https://itnext.io/getting-functional-with-c-6c74bf279616
| rafaelmn wrote:
| I can't say for sure because I don't know the full situation,
| but I've heard a similar story a few times and IMNSHO looking
| at it as "they made the wrong choice initially" is off because
| it assumes that a C# team could have delivered the initial
| version in the timeline required to get to the the next level
| of project.
|
| If they had a team that knows nest and can iterate fast with it
| that's the perfect choice. I've worked at multiple agencies
| over the years and was mostly in C# teams. Whenever a C# team
| got on greenfield/startup projects it ended up being a shit-
| show of self inflicted slowdowns/over-complications. I've seen
| 3 projects where in large part due to slow development of the
| MVP the project missed investment window or ran out of funds.
|
| From my experience Node/Rails teams were much more capable of
| delivering shit that works. It would eventually have a bunch of
| problems that would be non issues by default on a different
| stack like ASP.NET, but the difficulty of getting to that point
| and realizing that just being in that situation is a win is
| what most engineers miss.
| ngruhn wrote:
| Same experience here. C# might have superior tooling,
| performance, whatever but the OOP baggage is too heavy. In
| theory you can write something else than a giant over-
| complicated, over-abstracted pile of OOP nonsense in C#, but
| every team I've seen _has_.
| hvb2 wrote:
| Just to keep it relevant and off topic. Typescript is
| moving to go because you just cannot get performance out of
| javascript because of its design.
|
| As he says in the video about perf "you cannot leave 10x on
| the table".
| CharlieDigital wrote:
| You can write very functional C#. Our codebase is a mix
| with some aspects being functional (`ErrorOr`[0] being a
| big part of it as well as `OneOf`[1]) and OOP. Our core,
| common services all return `ErrorOr` to allow fluent call
| chaining at the top of the stack (controllers).
|
| Modern C# features like `switch` expressions[2] (not
| `switch-case`) and pattern matching mean that it is
| possible to write very terse, expressive code. Extension
| members and methods[3] go a long way as well by making the
| builder pattern easier to implement.
|
| Overall, it's up to the team to make use of the tools
| provided by the C# team. You can write C# in a very OOP
| heavy way (as is possible with TS in the case of Nest.js);
| you can also write in in a very functional way given many
| of the functional features adopted from F# over the years.
| It's up to the team.
|
| [0] https://github.com/amantinband/error-or
|
| [1] https://github.com/mcintyre321/OneOf
|
| [2] https://timdeschryver.dev/blog/pattern-matching-
| examples-in-...
|
| [3] https://typescript-is-like-
| csharp.chrlschn.dev/pages/interme...
| rafaelmn wrote:
| That's a perfect example of making it overcomplicated,
| just in the FP direction.
|
| C# uses exceptions for error handling. It has it's own
| control flow primitives. C# developers know how to work
| with it, everything else uses it. Why would I want to
| pull in a randos GH DSL and types to pretend I'm writing
| F# when I can just use F# that has first class support
| for this ?
| CharlieDigital wrote:
| C# is already very functional when it comes to Linq. In
| real world use, this just feels like extending in the
| same directionality while still preserving familiarity.
| Whereas F# does feel like an entirely different language.
|
| Learning C# when you know TS is like learning Portuguese
| when you know Spanish.
| overfeed wrote:
| > In theory you can write something else than a giant over-
| complicated, over-abstracted pile of OOP nonsense in C#,
| but every team I've seen has.
|
| C# syntax is fine, but has a rotten[1] culture/conventions.
| I suppose it makes sense that Microsoft's "Java-killer"
| became enterprise-y, with the same over-engineered
| indirections.
|
| 1. IMO - I find it very unpleasant and never allowed myself
| to Internalize the IConventions out of spite. YMMV.
| CharlieDigital wrote:
| > ...because it assumes that a C# team could have delivered
| the initial version in the timeline required to get to the
| the next level of project.
|
| I linked the Nest.js project because you can see how similar
| these two are[0] with Nest.js leaning into the OOP aspects of
| TS at the very core. Controllers and services are classes in
| Nest.js, for example. It uses a somehow more complicated DI
| system than ASP.NET. It is Spring Boot or ASP.NET, but
| without the maturity, performance, and ergonomics.
|
| The team had developers that had done C# before and later
| hires also included former C# developers.
|
| TS itself was new for the team at the time and several
| mistakes were made along the way resulting in a "dual-ORM"
| situation (Prisma + Drizzle; both with their faults) that
| ends up sapping a lot of productivity (one of the drivers to
| move to C#).
|
| [0] https://typescript-is-like-
| csharp.chrlschn.dev/pages/interme...
| oaiey wrote:
| Hmmm. I have a different take there: when you are young and
| wild, you achieve stuff because you think later and instantly
| produce code. When you turn older, you do it the other way
| leading to your example.
|
| In the early 2000s I have been in a startup and we delivered
| rapidly in C# as we did in PHP. We just coded the shit.
| rafaelmn wrote:
| I think what you said is a healthy progression : write dumb
| code -> figure out it doesn't scale -> add a bunch of
| clever abstraction layers -> realize you fucked yourself
| when you're on call for 12 hours trying to fix a mess for a
| critical issue over the weekend x how many time it takes
| you to get it -> write dumb code and only abstract when
| necessary.
|
| Problem is devs these days start from step two because
| we're teaching that in all sources - they never learned why
| it's done by doing step one - it's all theoretical example
| and dogma. Or they are solving problems from
| Google/Microsoft/etc. scale and they are a 5 people
| startup. But everyone wants to apply "lessons learned" by
| big tech.
|
| And all this advice is usually coming from very
| questionable sources - tech influencers and book authors.
| People who spend more time talking about code than
| reading/writing it, and earn money by selling you on an
| idea. I remember opening uncle bobs repo once when I was
| learning clojure - the most unreadable scattered codebase
| I've seen in the language. I would never want to work with
| that guy - yet Clean Code was a staple for years. DDD
| preachers, Event driven gurus.
|
| C# is the community where I've noticed this the most.
| wbobeirne wrote:
| I assume the startup wasn't also leveraging typescript heavily
| on the frontend, that tends to shift the weight in its favor.
| Having one set of tools to use across everything, being able to
| share logic and types without needing to go through lossy
| translation layers, and giving (especially small) teams better
| flexibility to move people around is a huge benefit.
| CharlieDigital wrote:
| We are using TS on the FE with React.
|
| But the reality is that at some point, your FE and BE teams
| will diverge anyways and we use an OpenAPI spec as the
| contract (Nest.js, _not_ Next.js).
|
| So there was no benefit to using TS on both ends; only pain
| on the BE.
|
| If a team is going to ship an OpenAPI spec and run it through
| a transformer, then it changes the selection criteria for a
| BE language: - Easy for a TS team to adopt;
| similar core semantics like `async/await`, exception
| handling, etc. - Flexible and pluggable OpenAPI spec
| generation for edge cases and advanced scenarios -
| Excellent ORM to improve productivity around CRUD -
| Good tooling - Extensive docs, platform maturity, but
| modern language features
|
| C# meets all of those in ways that no other language and
| platform does.
| hirvi74 wrote:
| > _the "default" ORM is far more flexible and powerful_
|
| I have never used any ORM that is as capable. Entity Framework
| Core with Linq is what keeps me on .NET.
| CharlieDigital wrote:
| Because EF's default behavior implements Unit of Work, a LOT
| of the complex transactional spaghetti ended up disappearing
| when we switched.
|
| This aspect of EF is highly underrated for complex entity
| graph mutations.
|
| EF makes the 90% use case easy and the 10% case possible with
| very little pain. The interceptors, global conventions, and
| other extension points are an enabler of complex behaviors
| that are still transparent to most of the team.
| lateforwork wrote:
| The real history of C# is that it is a rip off of Java. Anders /
| Microsoft understandably doesn't want to acknowledge that, but
| the rest of us can. C# today has diverged from Java, but the
| original release was Java with a few features added, such as
| properties, delegates, structs and unchecked exceptions.
|
| That last one was a mistake, see https://mckoder.medium.com/the-
| achilles-heel-of-c-why-its-ex...
| jolux wrote:
| Checked exceptions are bad because people just catch them and
| rethrow RuntimeException. Proper errors as data would be much
| preferable.
| lateforwork wrote:
| > _people just catch them and rethrow_
|
| People don't have to. There is a lot of misinformation out
| there about checked exceptions, and people are responding to
| the misinformation.
| vips7L wrote:
| Checked exceptions are proper errors as data. There is no
| difference between Result[T, E] and T throws E. The same
| people that just rethrow as RuntimeException would call
| unwrap() on Result and panic. The main problem with _Java_'s
| implementation of checked exceptions is that they're not
| fully in the type system because of Java's weak type system.
| That is solvable with a strong type system though, like in
| Scala or Swift.
| HumblyTossed wrote:
| MS poached him (and was even sued for it - that's how egregious
| it was) to create a Java killer because they had issues with
| Java.
| jodrellblank wrote:
| > "Hejlsberg: First of all, C# is not a Java clone. ... we
| looked at lots of languages, we looked at Java"
|
| -
| https://web.archive.org/web/20100109195800/http://windowsdev...
|
| You can just state the author of the language is lying and you
| somehow know better. You don't even justify _why_ "they don't
| want to acknoweldge it" - even with Hejlsberg there
| acknowledging taking ideas from Java - or explain why C# had
| those differences mentioned in the rest of that interview, or
| why Microsoft separately wrote their own Java implementation
| like Visual J++ if C# was just "their Java".
| equasar wrote:
| Completely agree, HN is mostly anti .NET/C#. It rarely gains
| attraction, and when it does, people bashes it with unfounded
| or very outdated info from another era.
| hvb2 wrote:
| He literally says they're standing on the shoulders of Giants.
|
| And, you would be stupid not to look at other languages.
|
| How can you expect anything to be a clean slate to begin with?
| Is every oop language a rip off then?
|
| Products don't get designed in a vacuum
| lateforwork wrote:
| > _He literally says they 're standing on the shoulders of
| Giants._
|
| Yeah everyone says that. He should have called out one giant
| specifically: James Gosling.
|
| > _And, you would be stupid not to look at other languages._
|
| Of course. Is that really what happened here? This was a
| literal clone. (And it is not like Microsoft never copies
| competitors' products.) Yes, they did add a few features.
| queenkjuul wrote:
| I recently wrote a project in C# 2.0 and i actually had the
| opposite conclusion; the inspiration from Java is clearly there
| but even by 2.0 it had diverged pretty meaningfully
| lateforwork wrote:
| Yes the languages have diverged, especially the ecosystems.
| For big data projects Java/JVM languages are preferred. For
| many open source projects too, Java is preferred because C#
| was late to the OSS party. But for many enterprise web
| applications ASP.NET works well.
| codeulike wrote:
| I was around in that era and yes when C# came out it was very
| obvious that Microsoft had been 'inspired' by the Java syntax
| ... Java had been the buzzword for the 5 years or so
| beforehand, like the only language that anyone talked about, so
| when Microsoft came up with C# it was glaringly obvious where
| they got the idea from.
|
| On the other hand Java came with the VM ("write once run
| anywhere" as they used to say) but C# turned that inside out
| with the Common Langauge Runtime, so you had various languages
| like C# and VB.Net that compiled to the same bytecode.
|
| The other innovation with Java back in the day was that it came
| with a huge library/framework of classes that did most of the
| stuff you would need to do. Similarly Microsoft's .NET library
| was a copy of that idea, although the frameworks themselves
| were pretty different.
| qingcharles wrote:
| They're also sweeping VB.NET under the rug.
|
| If I had to bet, I would guess VB.NET was the more popular .NET
| language at first. Everyone I know was converting all their ASP
| pages and VB apps to VB.NET.
|
| I didn't switch from VB.NET to C# as my main language until
| 2021. (the 90s was all C/C++/Java for me)
| nozzlegear wrote:
| I used to dream about a TypeScript that targeted dotnet. These
| days I'm not so sure I'd use it, only because I have a tendency
| to get caught in the weeds "big braining" the type system to make
| the perfect type for every situation. F# is my happy medium for
| the backend.
| gavmor wrote:
| What's missing from C#?
| hirvi74 wrote:
| Discriminated Unions is one thing I would like.
| nozzlegear wrote:
| If we're talking about C# versus F#, then as the other person
| said, discriminated unions is the main reason I prefer F#.
| Pipes are excellent too, but I also just like the syntax
| more.
|
| For C# versus TypeScript, it's primarily the type system.
| You've got DUs like F#, but you also have structural typing,
| dependent types, linear types, refinement types, string
| types, and so on. It's F#'s type system on steroids IMO.
|
| That said, C# is a great language and I use it all the time.
| I have a modestly popular open-source package that I write
| primarily in C#; I do that to make sure it's ergonomic for a
| C# developer first and foremost (since it's the more popular
| dotnet language by far) before adding in considerations for
| VB or F# developers like myself.
| kristianp wrote:
| Restraint.
| aristofun wrote:
| Typescript is the best thing that happened to web development
| since web development.
|
| I just hope they will not overengineer and ruin it moving forward
| bugfix wrote:
| I think this ship has sailed.
___________________________________________________________________
(page generated 2026-02-01 23:01 UTC)