[HN Gopher] C# Language Design Meeting for June 30th, 2025
___________________________________________________________________
C# Language Design Meeting for June 30th, 2025
Author : jasonthorsness
Score : 41 points
Date : 2025-07-15 14:53 UTC (4 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| jasonthorsness wrote:
| I always enjoy reading the language design committee notes (this
| is the latest one). C# has the most open and collaborative
| development process I am aware of. Do any other languages
| progress like this?
| tester756 wrote:
| Probably they're the only one among mainstream languages
|
| And somehow C# has the most sane programming ecosystem
| mdhb wrote:
| Dart is also absolutely fantastic in this regard.
|
| https://github.com/dart-lang/language
|
| https://github.com/orgs/dart-lang/projects/90/views/1
| sakesun wrote:
| Python, Kotlin
| legobmw99 wrote:
| The python PEP process is fairly open, most of the discussion
| ends up happening on public facing boards. I don't think they
| have regularly scheduled meetings to consolidate decisions,
| though
| monocularvision wrote:
| Swift
| brainzap wrote:
| Go has a repo with all discussions. the discussion about the
| package file format (go.mod) is very inspiring
| jeswin wrote:
| C# is a fantastic language, and with NativeAOT it can become a
| real alterntive to Go. It "can"; but most likely it won't.
|
| The problem with C# is that its design decisions won't attract
| any new users who are considering or using Go (or in some cases
| Rust). That's a consequence perhaps of listening to its users,
| who are mostly Windows-based and have rigid preferences. And then
| on the other hand, C# goes on to introduce excellent functional-
| style abilities - while at the same time handicapping them in
| some way.
|
| Recently, on one of their GH issues I was arguing that it's a
| good idea to reduce typing and allow namespace inference from
| directory structures/paths - given that most projects already
| have them in sync (and it can be done in a non-breaking way). In
| general, I felt that the community feels that it should be solved
| with "IDE features". Pushing these into an IDE is the Windows way
| of doing things.
|
| To win in Unix land, C# needs to be editable in a plain text
| editor. It requires succinctness. But with the current community,
| I'm afraid they'll never figure this out.
| rjbwork wrote:
| >But with the current community, I'm afraid they'll never
| figure this out.
|
| I hope that remains the case. File structure inferred
| namespacing to save one line per file seems like a ridiculous
| breaking change. If you're looking for succinctness to the
| level that something like that matters in your line/character
| count, use Perl or something.
|
| If you're looking for something like scripting without a lot of
| fanfare, just look at
| https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...
| glimshe wrote:
| I never understood people who advocate radical succinctness
| so _typing_ a program is optimal when most programming time
| is spent in reading documentation and debugging.
| jeswin wrote:
| It's not radical succintness. I just like to write pure
| functions. C# embraces many fp idioms, but in the end makes
| it hard to use them without a lot of ceremony.
|
| So what I see is a very capable language, with generics far
| ahead of golang, but a pain to write because I need to nest
| them inside namespaces and classes. If you take the HN
| crowd for instance (which is what a lot of startups are
| like), nobody wants to write Java-style OOP. C# can
| simplify it quite a bit (retaining full backward compat),
| but likely won't.
| tyleo wrote:
| Agreed with this. I happen to work on some Unity projects
| that do not have namespace and file structure in sync. Unity
| makes this more likely to some extent.
|
| Features like this just cause more unexpected and surprising
| things to happen.
|
| I always tell folks I work with to have a "reader bias" when
| writing code. People bend backwards to add fancy reflection
| and magic to automatically save 3 lines of code then spend
| days of headache debugging it when it causes a problem.
| jeswin wrote:
| > ridiculous breaking change
|
| Not at all. This can be done without breaking code. The
| important part isn't typing the namespace - rather, the
| freedom to move files around without having to change
| namespaces.
|
| Even if it were something like: auto
| namespace; // for example
|
| it's good enough. Allows me to move directories around,
| without having to depend on an IDE to keep namespaces in
| sync. IDEs anyway can only take a good guess at this, if
| namespace doesn't match the dir name.
|
| > just look at
| https://devblogs.microsoft.com/dotnet/announcing-dotnet-
| run-...
|
| I am not looking for a scripting solution. C# is a misfit for
| it. I want all of C#, with terseness and not forcing OOP.
| zvrba wrote:
| > Allows me to move directories around, without having to
| depend on an IDE to keep namespaces in sync.
|
| So... without and IDE, you'd move code around, let the NS
| be changed due to being placed in a different directory
| structure, and then fix namespaces on use-sites manually?
|
| > I want all of C#, with terseness and not forcing OOP.
|
| C# does not force OOP on you. You can have a single
| namespace, single static partial class and spread its
| members across as many files as you want. So the "ceremony"
| consists of the following snippet _per file_
| namespace NS; static partial class C {
| // Your methods here }
| zvrba wrote:
| > Pushing these into an IDE is the Windows way of doing things.
|
| s/Windows/modern/
|
| > To win in Unix land, C# needs to be editable in a plain text
| editor.
|
| I guess hard-core unix users still use sticks and stones to
| make fire.
| jeswin wrote:
| I just want to focus on writing functions. Here's a trivial
| example.
|
| I would like: // math/adder.cs public
| static add(int x, int y) : int { return x + y;
| }
|
| Instead of: // math/adder.cs namespace
| math { class adder { public static add(int
| x, int y) : int { return x + y; }
| } }
|
| Both are callable as: math.adder.add(10, 20);
| politician wrote:
| Consider: // math/adder.cs
| package math; ...code...
| metaltyphoon wrote:
| I agree with the first example. I wish C# could do "free"
| floating functions which just lives in the namespace
| itself. Your second example could do with the extra
| namespace indentation by doing
|
| namespace math;
| tester756 wrote:
| But why?
|
| Having to use class/struct instead of free floating funcs
| tries to force some hierarchy, architecture, etc
|
| Which eventually makes the code better *globally*
| jeswin wrote:
| I was arguing that the hierarchy is already in your path.
| The explicit namespace (and even the class name) is
| redundant if what you want are mostly functions.
|
| Currently, you're forced to define the hierarchy in the
| directory structure, and then again with namespaces.
| There should be a way to opt out of this.
| tester756 wrote:
| Ok, I see
|
| As of now you can opt out of physical hierarchy (file
| patches)
|
| I think logical hierarchy is better because you avoid
| stupid things like moving file to other folder causing
| compilation errors.
|
| I've witnessed too much of such issues in C++/cmake world
| to want it.
| zvrba wrote:
| C# allows file-level namespaces so you can write
| namespace Math; static class Adder {
| public static int Add(...) { ... } }
|
| (one nesting level less). Next, elsewhere you can write
| namespace Whatever; using static Math.Adder;
| class CC { void M() { var z = Add(10,
| 20); // no NS qualification needed due to using static
| above } }
|
| Java enforces directory structure to reflect package names,
| and this feature is not universally popular.
| claytongulick wrote:
| Just Linux (not counting other *nix) has a ~63% server market
| share. [1]
|
| That's a lot of sticks and stones.
|
| [1] https://en.m.wikipedia.org/wiki/Usage_share_of_operating_
| sys...
| speed_spread wrote:
| Server != Dev Workstation
| uticus wrote:
| > Pushing these into an IDE is the Windows way of doing things.
|
| I used to think in this idealistic way - if I can't reasonably
| use the language in VIM (without plugins of course!) the
| language is flawed, etc.
|
| Lately I've come to embrace the viewpoint that a mixture of
| language features _and_ great editor support are what enable
| productivity and creativity.
| fsloth wrote:
| Great tooling is 50% of what makes C# and F# so damn good.
| For the love of god don't write C# in a text-editor. The live
| debugger gives you over 80% of what people gush about in
| lisp-interactivity - a live program environment you can poke
| and introspect.
|
| Being able to observe a live program in a debugger is so much
| more powerfull technique. I know there are people out there
| who can architect anyhting from first principles and
| deduction - but unless you are really strong it that way live
| IDE wins.
| CharlieDigital wrote:
| Hard disagree on path based namespace inference.
|
| It's a pain to couple these two and you end up with giant
| stacks of `import`s in "modern" JS.
|
| When you reorganize files, now references need to be updated in
| many places. The editor slows to a crawl as the files are
| updated and the LSP has to process the changes.
|
| Big yikes. I hate it in TS/JS because its a paper cut that
| doesn't need to exist. Namespaces make refactoring organization
| structure way less jarring and at least I do that very
| frequently in certain lifecycles of code.
| jeswin wrote:
| > When you reorganize files, now references need to be
| updated in many places.
|
| This is exactly why directory based namespaces are a good
| idea.
|
| Otherwise:
|
| 1. You refactor. But namespaces which were formerly in sync
| with dir structure, but now aren't because you decided to
| move directories around to manage code better.
|
| 2. You don't refactor because it's a lot of work.
|
| > I hate it in TS/JS
|
| It's not only JS/TS. Python, Go, Rust ....
|
| C#'s approach here is redundant, and due to copying whatever
| Java was doing.
| metaltyphoon wrote:
| > It's not only JS/TS. Python, Go, Rust
|
| Rust allows you to move modules around without you changing
| using.
| jeswin wrote:
| When you write 'mod foo;' in a Rust file (say, main.rs),
| Rust will look for the source code for the module named
| foo in one of two places: a file named foo.rs in the same
| directory as the file declaring the module, or a folder
| named foo/ with a file named mod.rs inside it.
|
| That's great. Something like this is what C# can also aim
| for, while retaining full backward compatibility.
| metaltyphoon wrote:
| This would break every codebase in C# where a file lives
| in a folder where it is NOT in sync with the file system.
| jeswin wrote:
| This can be opt in, and not break any existing code.
| viraptor wrote:
| > 2. You don't refactor because it's a lot of work.
|
| Why? It's free is you use an IDE and otherwise mostly
| doable with search and replace + a few manual fixes where
| the compilation fails.
| logicchains wrote:
| C# will never attract Go users because async is much less
| pleasant to use than goroutines. I've never met anyone who'd
| used both extensively and preferred async. CSP is a
| theoretically cleaner and easier to reason about approach to
| concurrency.
| metaltyphoon wrote:
| This is just a preference. CSP in Go has its warts too, such
| as idiosyncrasies with channels.
| Thaxll wrote:
| It will never be an alternative to Go because the language
| itself is already 10x more complicated with tons of changes /
| feature each releases.
|
| I was using net core 6 years ago, 6 years is not much but the
| code from back then does not compile anymore and the ecosystem
| changed a lot.
| metaltyphoon wrote:
| > the code from back then does not compile
|
| Are you to share the code? C# 1 code still compiles today, so
| I don't understand this statement at all.
| patates wrote:
| not the author but perhaps because of the .net core
| transition? all code will obviously compile with the
| framework they are coded for but a significant migration
| was necessary to switch to core.
| metaltyphoon wrote:
| OP specifically said .net 6.
| viraptor wrote:
| > To win in Unix land, C# needs to be editable in a plain text
| editor.
|
| What do you mean? It's editable in plaintext already. See what
| "dotnet new" generates.
| le-mark wrote:
| > To win in Unix land, C# needs to be editable in a plain text
| editor.
|
| This isn't a C# issue, it's dynamic vs static typing issue. You
| can edit C# in any text editor (obviously) but you don't get
| all benefits a good IDE gives you. Statically typed languages
| in general allow IDEs to provide a wealth of benefits that make
| writing and _maintaining_ code much easier. With the IDE one
| can be much more productive.
|
| This is also possible for dynamically typed languages but in
| practice they're not at the same level.
|
| So yeah write your little dynamically typed language scripts in
| vim. The first thing I'm doing for a large C++ project is put
| it in an IDE. Not to build it but to explore it and understand
| it, ymmv
| metaltyphoon wrote:
| > given that most projects already have them in sync
|
| What makes you think this? I'd wager that most C# code is not
| open source.
| bob1029 wrote:
| I like the type parameter inference from constraints proposal.
|
| I've been adopting these new approaches into my code gradually
| over time by way of intellisense suggestions. Sometimes I'll see
| the little ... in front and think "what the hell, let's see". If
| it looks ugly, it's easy enough to back out. Some things took a
| while to grow on me.
|
| So far the only newish thing I haven't preferred much is the
| range operator syntax [0]. Every time I accept that one its a
| quick revert to the more verbose indexing operators.
|
| [0] https://github.com/dotnet/csharplang/discussions/198
| louthy wrote:
| As the author of language-ext [1] (functional programming library
| for C#) -- these suggestions are a big "YES!!!!!" from me. I
| assume they're doing the first one due to the way they're using
| static interfaces like traits (which is what I also do to support
| Functor, Applicative, Monad, etc. traits). Being able to refine
| the type-checker based on constraints would be a huuuge win.
| Although, I'd prefer higher-kinds :)
|
| The second one has been a big ballache when using pattern-
| matching. I think the leading `.` on the patterns isn't pretty,
| but I'd take it over handwriting the full type name every time.
|
| [1] https://github.com/louthy/language-ext/
| ctenb wrote:
| Sorry to go tangential, I was reading your blog posts following
| the link from your post. The monoid example is possible without
| static interface methods: you could use the new() constraint
| and have the empty constructor act as identity element. Kudos
| on the posts, very nice to read.
| louthy wrote:
| True! (Although that requires an allocation)
|
| The technique works best for encoding higher-kinded traits
| and, as you say, Monoid doesn't need any of that, but it was
| an easy way to introduce the ideas.
| chris_pie wrote:
| The second one seems very similar to the "using static"
| feature, but less verbose.
___________________________________________________________________
(page generated 2025-07-19 23:01 UTC)