35 comments

[ 3.4 ms ] story [ 56.9 ms ] thread
Looks nice, congratulations.

I feel like we've done full circle. Languages are back to being (mostly) procedural. I'm not sure I like it, but it seems that this is what people prefer.

Personally, I'd rather see something like dependant types on a dotnet language. An addition, not just a simplification.

Just trying to offer some help here, not an attack:

``` G# brings Go-, Kotlin-, and Swift-style ergonomics — packages, func, data class, nullable handling with if let, structured concurrency with scope — to the .NET runtime. Source compiles directly to managed assemblies. ```

This is a decent description - but as someone also building a language in a similar space - who isn't super familiar with the .NET runtime... My first question is... Why not C#?

I'm by no means a C# expert, but I thought most of this was supposed to be in C#. C# is not terribly un-ergonomic, and Go is simple, but not really ergonomic except for Goroutines...

`packages` and `func` being the first two selling points is alarming. Sure, people probably prefer `fn foo() -> Dog` over `Dog foo()`. No one's picking a language for that. C# has namespaces... C# has `record` and `record struct`. C# has not-ideal nil handling, but it still has it. I'm not convinced `if let` is better enough to be a selling point - a lot of people don't like that!

Your main selling point seems like `scope` and your concurrency model vs C#, but C#'s is not exactly terrible...

Rich Hickey has a joke about semi-colons in language design, and your main pitch seems to sell yourself short.

Btw, I think your GitHub page does your language a lot better justice.

I like it. I consider myself picky with regards to weird syntax in new languages and this is terse and very readable. Approved!
What is it bringing from those languages? The FAQ reads like it is just altered syntax for C#, no difference in semantics or function.
How is this different than C#? What new concepts does this bring that C# doesn't?

20 years ago there was some momentum behind Visual Basic .Net; but the language was so similar to C# that it just wasn't worth using. There was a joke that .Net was a "skinnable language."

BTW, there's a whole nitpicky/semantic argument that C# isn't null safe because of the null forgiving operator. That will probably come into play with G# if the null forgiving operator can be used from C# to pass null into G# code that doesn't expect it.

I think it would be more valuable if it had less concepts than C# but it doesn't seem clear if they succeeded in that.
I wish README is clear whether they are using AI or not, and if so what the guidelines are. Not that anything wrong with using it, but given anyone with $$$ for tokens can do it, its nice to know what their process is etc etc. Gives me more confidence that its worth checking out.
This should be a standard section in READMEs now. I've started adding it to mine. Even if you don't use AI, please add a section saying that! It can be one sentence.

  # Use of AI

  No AI was used. / This is entirely written by Claude and I didn't even read the code. / ...
New programming languages? Doesn't seem needed anymore
Things like Zig, D, Odin, Rust, etc, are outliers. Most new programming languages are used only by their creators.

It's hard for a new language to find its feet, and make a name for itself. Unless its created by a big company with a lot of clout and internal users. (e.g. Rust, Go).

People keep creating new languages because it's educational, interesting, and sometimes even fun. Doesn't mean they'll get used, and it doesn't mean they're pointless.

Of course you learn very little if you make an LLM write the damn thing. But that's a different story.

Here I am wanting the opposite. I want C# compiled into a static binary like with the GoLang toolchain!

Maybe .NET AOT will get there one day..

You don't need AOT for a single self-contained binary. This already works with C#, but it's still JIT-based.
Self-contained != static compilation though. The self-contained binaries still have pretty poor startup time and are large since they contain the whole JIT.
Looks pretty good to me.
Yuck. I like both Go and C# a lot, and use them both professionally.

In my experience the strengths of Go are mostly - Deployability via single-file static binaries - Simple syntax that anyone can learn (no exceptions, no classes or inheritance) - Wicked fast compile times

And the strengths of C# are - Powerful language with null-safety and lots of syntax sugar - Runtime-level coroutines so you don't need `async/await` everywhere

G# seems like it has the _worst_ of both worlds, not the best. It's fun to write compilers, and good on them for doing it, but no thank you for real use

C# has single-file static binaries
> And the strengths of C# are [...] Runtime-level coroutines so you don't need `async/await` everywhere

If I'm not mistaken, that isn't the case. Could you elaborate?

I've worked with C# for a decade, and Go for the past 5ish years and I think the biggest difference between them is in the philosophical design on implicity and explicity. I have a strong dislike for C# like languages these days, but it's not for technical reasons. I think C# is supperior to Go in many ways, but I absolutely hate the implicity in it's design, and this is a personal opinion that is not objective. In this context I can't imagine how you would create a mix of the two that wouldn't violate either approach. Looking at something like this:

> @DllImport("libc", EntryPoint: "strlen", CharSet: CharSet.Ansi)

I would argue that they made something I suspect many Go developers will dislike. I know I absolutely hate it. If I wanted to do things like that I might as well use C#. Then again, these days I'm shifting more and more of my development to either Python (which is objectively an awesome language that also sucks) or Rust. While one of my favorite features of any programming language is the Go modules with single folders and upper and lower cases for private/public. I am becoming a fan of how rust does structs with impl methods.

Anyway...

C# is a pretty bad language when you take away the stack it sits atop of. I do mostly like the async but developers put up with a lot of shit to e.g. use the msft networking stack and containers
Does this support new programming abstractions, or just another remix of existing ones?
I'm less familiar with Swift but from a design point of view Go and Kotlin have really different ergonomics. Kotlin leans in really hard to creating DSLs etc. whereas Go avoids all that stuff like the plague. To me this makes the tag line a little confusing, like what does this imply for the design of this language?
I lived long enough to see a programming language called G#.

What a great era.

I was hoping from the tagline it would have sum types (rust-like payloads on enums, like Swift).
“Width-bearing”, wow, Claude really loves that “bearing” suffix doesn’t he
- stupid question: how do you make a programming language like this from scratch?

- what is the thought process that goes into making a programming language

- what is this field of study or discipline called?

- why do we have so many programming languages? what purpose do they intend to solve and how do we know what purpose a programming language was made for?

- for example, why was swift made if objective c exists and why was objective c made if c++ exists?

Is the familiar syntax so important? I learnt f# being used to algol syntax, and the syntax was not a hurdle.
I love Go but am not a fan of .NET

Have to ask what is the point of .NET is it even needed being the navel gazing MS fraternity?

Looking at the code and the commit log, this is a large pile of slop
Go, C# and .Net? And here I am wishing for typescript-like language for backend systems.
So... the verbosity of Go without the compile speed of Go? Go is not a language I would associate with ergonomics, and this doesn't even have most of modern C#'s best features: does xUnit.NET work? Does immutable records work? Do collection expressions work? Does LINQ work?

Calling a language with `let` instead of `const` and async/await and iterators and classes "Go" is plain just incorrect. This G# is more similar to TypeScript than Go.

The ONE feature that C# really needs is payload enums with `match` instead of C#'s current pattern matching with `switch` anyways, and Rust is more similar to Go anyways so why not copy from Rust instead? I'm honestly baffled.

for i in 1 ... 5 { sum = sum + i }

Means "for 1 to 4". Kill me now.

why doesn't anyone just jump the gun and introduce proper parallelism primitives? SML/NJ got it right in 1991. ocaml5.0 has domains and effect handlers.

why do people still accept CSP? It is simple to do some things in it, bit please just give me concurrentML with "simple" channels for that kind of work , and proper channels for any kind of hard stuff. I have had to write things in go that took me days to get straight that would have been 20 trivial lines in any concurrentML implementation.