Hacker News new | ask | show | jobs
by YuechenLi 16 days ago
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.

4 comments

I don't find Go especially verbose - in fact, due to the economy of syntax, Go code without the usual syntax sugar features ends up similar in length to other curly brace languages. I tested this with C# and Typescript, where I migrated projects from these languages to Go - the overall volume of code stayed roughly the same.

  err := do_something()
  if (err != nil) {
    return nil, err
  }

  err = do_something_else()
  if (err != nil) {
    return nil, err
  }

  err = do_something_more()
  if (err != nil) {
    return nil, err
  }
...

So very concise. And this is not even including the error wrapping that is recommended.

First, this is legal:

       if err := do_something() ;err != nil {
         return nil, err
       }
Not horrible imo. But I've found that verbose error handling and explicit errors made me consider which parts of the code can return err, and reorganize code around that - with that I've been able to eliminate most 'err' from my codebase.

Like, if you go by function: ReadData(has err)-> ParseData(has err) -> ProcessData(no err)

Instead of having functions that can fail dynamically all over your codebase.

  modern C#'s best features: does xUnit.NET work? Does immutable records work? Do collection expressions work? Does LINQ work?
xUnit and LINQ are not C# features, why should they not work in another .NET language?
Micro$oft's wiki:

> Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language.

Generally when people say LINQ they're referring to the IEnumerable/IQueryable APIs in the BCL, not to C#'s little-used query syntax.
Yeah, I still don't understand why they don't just use enums and have to invent a special "union" keyword instead. C#'s enums are extremely underpowered to begin with and the syntax they designed here way more convoluted and uglier to say:

    enum Pet { 
    Cat,
    Dog,
    Bird
    }

    var description = Pet switch
    {
        Dog d => d.Name,
        Cat c => c.Name,
        Bird b => b.Name,
        _ => "no pet"
    }
The other issue is they introduced `null` to pattern matching on their union example when the whole point of pattern matching is that you can pretty much mostly remove `null` from the language altogether with Result<T, E> available, as Rust has shown.
It sounds like they didn't reuse the enum keyword for this for the most backwards compatibility and to avoid confusion. Your example enum is an `int` today. Either you break existing code expecting an `int` sized thing or you need additional syntax and can't use the "clean" form that you are hoping for.

The null patterns predate these unions and the relevant section of the documentation is showing that you can use nullable unions, not that you have to or should use them. Other examples also show a fully closed Result<T, E> type that yeah would be great for projects hoping to eliminate more nullable code.

I think C# switch supports type matching.