Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • fascinating how many people are displeased with the expansion of generics! i love go and this is some functionality i always missed.
    by ewy1
  • “Go 1.27 is a meaty release whose center of gravity is the type system. A few themes stand out:”

    llm generated

  • > A quick credit first: the interactive Go tours were started by Anton Zhiyanov, who wrote one for every release from Go 1.22 through Go 1.26. He’s decided to stop, so we’re picking up where he left off.

    But he actually wrote those and they made sense.

  • Some examples for the upcoming release https://go.dev/doc/go1.27
  • Adding simd in std and even being used in map is nice. Would have to look for places to experiment with it in hot loops in code I have.
  • >The quieter but bigger change

    I really wish they didn't use such stupid LLM-isms.

  • This post seems to be mostly llm generated
  • Worth flagging, real gap, transparent win, center of gravity... I'm tired boss
  • The entire thing is obviously LLM generated. Much better off just reading the release notes.
  • I do wonder whether, as a group of people being regularly exposed to text written by LLMs, we'll gradually end up writing and talking like that in our normal language. At that point perhaps text written by LLM and human will be indistinguishable. I already find myself using terms like 'footgun' in jest more than I ever did before!

    "The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which." ― George Orwell, Animal Farm

  • Those Generics syntax in Golang seems so hard to read.
  • imho it is much better that C++ equivalent
  • It does, but at the same time it's not "normal" code; I see it much like Typescript's advanced types, ultimately it's something that mainly lives in libraries.
  • stared at it for a bit and im mostly certain i prefer it to java. at least writing other go = its not bad for me to break apart the signature line on a generic

    java feels kinda unhinged the more that i look at it

        public static <T extends Comparable<? super T>> T max(Collection<? extends T> c)
    
    :x i wonder if anyones done something like this, would be super unhinged

        Map<String, List<Map<Integer, Optional<Pair<String, Function<? super List<? extends Comparable<?>>, ? extends Map<String, ?>>>>>>> config;
    
    go seems to get a lot of flack around these parts. i kinda lurv it though, just getting compiled binaries out of not much code and not needing a runtime to do shtuff. once i got a wrangle on goroutines i dunno i feel like its pretty solid for webapp backend which is mostly what i use it for
  • It is verbose but inference helps a lot to keep it “tidy”. I always find myself increasing my focus a notch when I start dealing with generics. It’s one of the things I use only if I really “need”.
  • Go's standard library has always been it's strength, especially the crypto package! Lovely stuff.
  • Automatically draining http response bodies is a risky silent behaviour change. I think it will be an improvement for most applications, but it's very subtle if you were relying on the old behaviour
  • Can you go more into this? I don’t quite follow
  • The Go team is addressing that in the release notes: https://go.dev/doc/go1.27 They think it will only affect use cases where a high number of idle connections were allowed to linger, for instance by setting MaxIdleConns in Transport to 0. They recommend to disable keep alives in that case.
    by kune
  • This release also fixes runtime.findnull() to be compatible with MTE on Android ([1] and [2]). This was the only thing preventing MTE from being enabled for apps that use gomobile on MTE-compatible Android OS's like GrapheneOS.

    [1] https://go-review.googlesource.com/c/go/+/749062

    [2] https://go-review.googlesource.com/c/go/+/751020

  • I still don’t understand why Go isn’t the primary supported language for android.
  • "The best way to teach something new is to compare it to something the audience already understands."

    Could someone take the example, reduce it to a non-generic version for two types I DO understand, then show that with the new feature I can collapse them into the Box/Map example in the doc?

    I have 10+ years of Go experience and I can't make heads or tails of "(b Box[T]) Map[U any](f func(T) U) Box[U]"

  • If you instantiate it with concrete types, does "(b IntBox) Map(f func(int) string) StringBox" make more sense? You have a collection (in this case Box) containing values of type T, a function that maps values of type T to type U, and if you apply that function to all elements in that collection you get a collection of type U.
    by pkal
  • I think part of the issue is that they didn’t explain what is gained by adding generics on methods. You’re right that a few examples here are useful.

    Without generics:

    ‘’’

    type Stream[T any] struct{ ... }

    func (s Stream[T]) MapInt(f func(T) int) Stream[int] { ... }

    func (s Stream[T]) MapString(f func(T) string) Stream[string] { ... }

    ‘’’

    Then later you need to map floats:

    ‘’’

    func (s Stream[T]) MapFloat64(f func(T) float64) Stream[float64] { ... }

    ‘’’

    Then later someone outside the package wants to map a custom type. Too bad! They’ll need to make some custom wrapper that doesn’t follow the pattern.

    With the genetics approach the semantics are defined once and usable in all scenarios. You don’t need to keep adding methods; instead the caller can provide the mapping function. Common mapping functions could be pre defined for convenience.

  • This is the kind of shit why they probably didn't want generics in the language.

    This is like building a very crude general-ish DSL inside the language. Because the tools are intentionally limited (as to limit the scope of the feature), the result looks ugly. Also, like with C++ templates, people find exploits to do what the designers didn't want them to, with even more elaborate workarounds.

    I liked Go before generics. It had a clear identity. If you wanted to get cute, you could use go generate and generate code. They should've made that much more convenient and ergonomic, if they wanted to make the language more powerful (and the nice thing is that it still sits outside of the language).

    I think the point Go was making is that these complex things generally have little use in application code, and 99% of the time they're there for people who want to show how smart they are, at the expense of code readability, and accessibility.

  • It's not a great example.

    I think it's trying to show a mapping operation for a generic container where the container values are of one type and the mapping function is allowed to return a container with values of a different type.

    Without generics, something along the lines of the following (with runnable example at https://go.dev/play/p/KHBI1uAhbO0):

      type MySlice []int
    
      // Map maps from a slice of ints to a slice of float64s.
      func (s MySlice) Map(f func(int) float64) []float64 {
         var out []float64
         for i := range s {
             out = append(out, f(s[i]))
         }
         return out
      }
    
    From a quick search, this seems to be better explanation of this new 1.27 feature:

    https://www.gopherguides.com/articles/golang-generic-methods

    (That uses an example that seems similar in spirit to the Interactive Tour's example, but with a more useful type of a Stack[T] and corresponding explanation seem clearer.)

  •     type IntBox struct { v int }
        type StrBox struct { v string }
    
        func (b IntBox) MapToStr(f func(int) string) StrBox {
            return StrBox{v: f(b.v)}
        }
    
    (Please forgive any typos I made on mobile.)

    It wasn't a great example because "Box" isn't really a useful type. But the point is that you no longer need to define a separate "MapToXXX" method for every type you might want to map to; now you can have just one type-generic "Map" method.

  • This: "(b Box[T]) Map[U any](f func(T) U) Box[U]" is the type of cognitive weight I was happy that Go avoided.
  • Is it worse than having to create endless functions for each type pair?

        (b IntBox) MapToStringBox(f func(int) string) StringBox
        (b IntBox) MapToBoolBox(f func(int) bool) BoolBox
        (b StringBox) MapToIntBox(f func(string) int) IntBox
    
    Etc etc etc?

    The T, U, and f names are the cognitive load here, because they are meaningless variables. For a specific solution, those would have meaningful names that would make it easier to understand.

  • Maybe it's just familiarity, but I think it would look a lot more comprehensible with some punctuation. Just because a syntax is formally unambiguous doesn't mean it looks that way to humans.

        func (b: Box[T]).Map[U: any](f: func(T) -> U) -> Box[U]