Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

[flagged]


Please don't start random language fights.


That's no language fight. Rust doesn't want batteries included. That's highlighting a difference between the languages.


Directly addressing the topic of a upvoted article is starting random language fights?


Where does the word Rust appear in the article?


In the comments about every article including Go, generally.


I can't speak for Go-centric articles in general, but for this one in particular, the only one (as of now, after 14 hours of comments) bringing up Rust is this single person with (apparently) a weird chip on their shoulder.


The article is about Go, and while the article mentions other languages for comparison, Rust is not one of them. So traceroute66's comment comes across as starting a Rust vs. Go fight where not appropriate.


I think the comparison is totally apt and illustrates why Rust and Go get compared very often. They are both languages that compile to a binary, rather than running in a managed environment.


Doesn’t come across as starting a fight to me. Not even close.


Not even, they just expressing an opinion.


If only they would decide what to do with plugin package, not use SCM paths for packages and decide to eventually support enumerations instead of iota dance (Pascal style would be enough.

Maybe 10 more years.


    type Kind enum {
        Simple,
        Complex,
        Emacs,
    }

    const kindStrings [Kind]string = {
        "simple",
        "complex",
        "emacs",
    }

    func (k Kind) String() string {
        return kindStrings[k]
    }

    func t() {
        var a = Kind.Emacs - Kind.Simple  // a has type int and value 2
        var b = Kind.Simple + Kind.Emacs  // type error
        var c = Kind.Simple + 1           // type error
        var d = len(Kind)                 // d has type int and value 3

        for k := range Kind {
            fmt.Printf("%v\n", k) // prints what you expect it to do
        }

        // not sure about legality or runtime behaviour of the followng
        var t = Kind.Emacs
        t++
        t = Kind(42)        
    }
Would be nice, not gonna lie.


How is this any different than Go's existing enumerations, aside from the enumeration also creating an implicit list structure which, while kind of neat, isn't really a property of enumerations.

The parent is likely lamenting that Go doesn't enforce compile-time value constraints on enumerated sets like some languages do, but many other languages don't ether. Not even Typescript does. If Typescript doesn't find it important to have such value constraints, Go most certainly never will.


> Go's existing enumerations

Go doesn't have enumerations. So the first difference would be that my enums would actually exist.

> implicit list structure which, while kind of neat, isn't really a property of enumerations

It absolutely is, or people wouldn't have been regularly writing enums like

    typedef enum {
        KindSimple,
        KindComplex,
        KindEmacs,
        Kind_NUM_VALUES
    } Kind;
which they do about half the time.

> likely lamenting that Go doesn't enforce compile-time value constraints

Yes, that's my complaint as well. Which is why that "not sure about legality" part in my example: you want to be able to enumerate the enum (duh), but with last_value_of_enum++ being illegal, writing for-loop with "<" is illegal too, that's why there is support for it in for-range.

With incrementing (used in loops almost exclusively) taken care of, the rest of arithmetics on enums is meaningless in general except maybe in case of subtraction (when you use enums as keys/indices for a fixed-sized array) which is why I allow it — but it produces an int, of course.

As for what should happen in Kind(42) example — perhaps it could work like type-assertions?

    k, err := Kind(42)
    if err != nil {
        return err
    }


> Go doesn't have enumerations. So the first difference would be that my enums would actually exist.

That's obviously not true. That's what the iota dance is for.

    type Kind int

    const (
        KindSimple Kind = iota
        KindComplex
        KindEmacs
        Kind_NUM_VALUES   
    )
Go doesn't have a literal enum keyword, if that's what you mean, but enumerations aren't defined by having a specific keyword or specific syntax. Enumerations are a more general concept, defined as a set of named constants. The above is functionally identical to your example in C, among a host of other languages.

> Yes, that's my complaint as well.

Fine, but that's not a property of enumerations. If one wants support for value constraints, surely one should ask for that and not for something the language has had since the beginning?


Mmm. The original comment asked for "Pascal-style enums". Those are different from C enums: they are incompatible with integers and other enums, they don't support arithmetic operations (you have to use succ()/pred() built-ins) and they contain precisely the named values (calling e.g. succ() one too many times is supposed to be a runtime-detected range error). Plus, enums being ordinal types, you could use them as array indices in type definitions, like "array[Kind] of real" (so effectively, enum range checks and array boundary checks implemented by the same mechanism).

So that's what I went with, because I actually liked Pascal-style enums but thought they could be somewhat improved, so what you've read is my ideas (Go is surprisingly close to Oberon and both lack enums).


The original comment asked for enumerations. Despite him not realizing, Go has those. It has a relatively unique syntax for defining enums, sure, but enumerations are not defined by specific syntax. They are a higher level concept that transcends any specific syntax implementation.

The original comment also hinted at wanting other features that some other languages have, including Pascal, although not stating which features specifically. I expect he was referring to wanting some kind of constraint system, which is the most common feature I hear requested of Go. But that's beyond the scope of enumerations.


Regarding the “iota dance,” I wrote my 2 cents on what could be a slightly more robust approach a couple of days ago: https://preslav.me/2023/03/17/create-robust-enums-in-golang/

P.S generic type sets make it even better. I’ll write an update to my post these days.


From another point of view "usable" isn't a word I'd associate with Go, especially not when there is an "unlike Rust" in the phrase. I've not had any issues of the sort when building out Rust applications. At this point the only time I touch Go is if I need to modify something else someone has made-- which I avoid at all costs


Maybe AI will make it more palatable but I just can't get into Rust.

I can probably easily understand borrowing. It's mostly an issue of controlling pointer aliasing wrt mutability, especially in a multithreaded context I guess.

But that gottdarn syntax... And goroutines are too nice for the type of code I use.

I'm too spoiled with Go I guess.


That attitude assumes that the go standard library is the global maximum for Getting Stuff Done, and because of backwards compatibility guarantees ensures that it’s difficult to innovate on.

I think having a small standard library is actually a good thing because it encourages exploration of the space of possibilities.

For example Go’s stdlib http.HandlerFunc sucks, people instead opt for leaving it behind entirely in favour of Gin or trying to work around it with bad patterns like interface smuggling.


Using a crate is the opposite if reinventing the wheel. Also are we talking about go? The language without a set implementation?


Parent is saying those crates themselves are reinventing the wheel, not talking about using a crate


So by that logic Golang reinvented the wheel by creating a new programming language when java already existed


Yes. Is reinventing the wheel always a bad thing, though? Not if you ask me, not if the new wheel has novel characteristics and performs better in some aspects.


Rust's philosophy (unlike Python's, for example) consists in not including tons of stuff in the standard library, this way you can choose the best implementation for your specific use case from one of the many crates (which are super easy to install, by the way). There is no "always the best" implementation for a specific functionality, nor a legacy-but-still-officially-supported-in-std implementation that nobody uses anymore but still needs to be maintained with its own namespace.

I don't see this as negative or "reinventing the wheel". Reinventing the wheel would be writing your own implementation, which doesn't happen if you can choose from many high-quality crates.


"a legacy-but-still-officially-supported-in-std implementation that nobody uses anymore but still needs to be maintained with its own namespace."

The cardinality of the set of "nobody uses anymore" is usually in tens of millions.


If something is used by tens of millions, be sure that it will be updated even if legacy. Just not officially by the people who maintain the language.


> legacy-but-still-officially-supported-in-std implementation

There is massive value in this.


Not officially supported doesn't mean not updated or not supported in general.


Ah yes, the #1 thing golang is known for: a comprehensive stdlib. Like including a max function for integers, right?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: