Go 1.22 - Fixes For Loops | Prime News

แชร์
ฝัง
  • เผยแพร่เมื่อ 20 ก.ย. 2023
  • Recorded live on twitch, GET IN
    / theprimeagen
    Reviewed article: go.dev/blog/loopvar-preview
    Authors: David Chase and Russ Cox
    MY MAIN YT CHANNEL: Has well edited engineering videos
    / theprimeagen
    Discord
    / discord
    Have something for me to read or react to?: / theprimeagenreact
    Hey I am sponsored by Turso, an edge database. I think they are pretty neet. Give them a try for free and if you want you can get a decent amount off (the free tier is the best (better than planetscale or any other))
    turso.tech/deeznuts
  • วิทยาศาสตร์และเทคโนโลยี

ความคิดเห็น • 120

  • @queueue_
    @queueue_ 10 หลายเดือนก่อน +165

    Just starting to get into Go, glad they're fixing this before I have to deal with it 😅

    • @d1ngd0
      @d1ngd0 10 หลายเดือนก่อน +11

      I frankly have never ran into this…. Knowingly 😰

    • @MyroslavSuprun
      @MyroslavSuprun 10 หลายเดือนก่อน +7

      Yeah, I am currently learning Go as well and I ran exactly into this problem yesterday and it took me almost 2 hours to solve it.
      Good no-one is going to experience it any more.

    • @miracleinnocent2649
      @miracleinnocent2649 10 หลายเดือนก่อน

      Unless you’re writing 5 thousand lines everyday you won’t encounter this mistake more than 4 times

    • @yash_renaissance_athlete
      @yash_renaissance_athlete 10 หลายเดือนก่อน +1

      this is a pretty chill thing to be honest. I am not very impressed or certainly happy with this fix but yeah I am just biased because recognising and catching this potential bug is on my muscle memory.
      But yeah, I can see how this bug could have been a mess to deal with by a person newly getting into Go.

    • @Nenad_bZmaj
      @Nenad_bZmaj 5 หลายเดือนก่อน

      When you learn Go without this ''fix'', you shall not make these stupid mistakes, anyway.

  • @vikramkrishnan6414
    @vikramkrishnan6414 10 หลายเดือนก่อน +87

    10/10 move. The first time you are working with goroutines and encounter this, some malding occurs. Fixing this is a major win for DX

    • @michelians1148
      @michelians1148 10 หลายเดือนก่อน

      Only took 16 years.

    • @PhilipAlexanderHassialis
      @PhilipAlexanderHassialis 10 หลายเดือนก่อน +1

      Same thing happens with Tasks in C# - where you have to capture the loop variable value. It's a classic issue and a classic interview question.

  • @rosehogenson1398
    @rosehogenson1398 10 หลายเดือนก่อน +56

    This is a great change. Almost everyone runs into this issue at least once when they're starting out.

  • @Propherex
    @Propherex 10 หลายเดือนก่อน +6

    1:32 You make mistake - skill issue.
    2:33 I make mistake - its a bug.

  • @thomasw.4298
    @thomasw.4298 10 หลายเดือนก่อน +38

    There is definitely somebody on the Go team saying "told you so" right about now. You should interview this chad and see what other ideas he wants to fix

    • @advertslaxxor
      @advertslaxxor 10 หลายเดือนก่อน +2

      if err := Something(); err != nil { ... }
      blah, err := foo()
      Hopefully.
      The first case should just be:
      if err := Something() { ... }
      The second, conflicted. I think we can have another := that returns default values and the error if it fails.
      blah ?= foo()
      Translates to:
      blah, err := foo()
      if err != nil {
      return ..., err
      }

    • @advertslaxxor
      @advertslaxxor 10 หลายเดือนก่อน +1

      Also I want to steal 'with' from python.
      with foo, err := Open(something) {
      // err is nil
      // implict defer foo.Close()
      } else {
      // err is not nil
      }

    • @looncraz
      @looncraz 10 หลายเดือนก่อน +1

      @@advertslaxxor I want an or keyword for this :
      err := Something() or return err
      err := Something() or {
      log.Error("...", err)
      return err
      }
      Or, better yet, automatic capture of the first error-type return value or the first returned value if no error type given:
      Something() or return error

  • @charliesta.abc123
    @charliesta.abc123 10 หลายเดือนก่อน +40

    So happy they're fixing this before I even stumbled into it as I'm still learning Go

    • @enkiimuto1041
      @enkiimuto1041 10 หลายเดือนก่อน +3

      Same here. I can see myself spending hours not understanding what is happening lol

    • @ruanpingshan
      @ruanpingshan 10 หลายเดือนก่อน +1

      Same here. C# fixed this over a decade ago, so I would've assumed that Go worked the same way.

  • @Tresla
    @Tresla 10 หลายเดือนก่อน +21

    Even after programming in Go for the past 7 years, this one still trips me up on occasion. Definitely a welcome change!

  • @scheimong
    @scheimong 10 หลายเดือนก่อน +49

    Rust casually going: "oh it's impossible for us to have this problem by design". All hail the glorious borrow checker.

  • @mikereynolds1368
    @mikereynolds1368 10 หลายเดือนก่อน +3

    Damn I was hoping for a Prime breakdown example of the issue, the fix, and the correct way to actually do the loop.

  • @EskoLuontola
    @EskoLuontola 10 หลายเดือนก่อน +7

    I was complaining about that back in February 2010, that there was no reasonable code which would depend on the original behavior, but that the feature was a pure footgun. Finally they fixed it. 🎉

    • @hackebeil20
      @hackebeil20 9 หลายเดือนก่อน +1

      yeah. still so many things unfixed since forever. I was really excited for Go at the beginning. not so much anymore after I've seen many stupid design choices and weird things in the stdlib.

  • @narekasadorian
    @narekasadorian 10 หลายเดือนก่อน +2

    Rust: standing on the shoulders of giants
    Go: laying in a ditch with an empty 40oz

  • @a_maxed_out_handle_of_30_chars
    @a_maxed_out_handle_of_30_chars 10 หลายเดือนก่อน +5

    when learning go there was always a warning regarding this and the work around
    glad it's been fixed :)

  • @l3ss1sm0r3
    @l3ss1sm0r3 10 หลายเดือนก่อน +4

    Thats why immutability by default is a thing I guess ... and feels so nice to work with imo

  • @NicholasKoukoutsis
    @NicholasKoukoutsis 10 หลายเดือนก่อน +8

    This was a rollercoaster of emotions for me. At first, I PASSIONATELY thought the same - this is a skill issue. And then I had the gottem moment. 10/10 move from Go. Gotta say though, you feel pretty big brained knowing this, and telling some junior that tHe sCoPe oF a VaRiAbLe iS tHe LoOp, and bestowing that knowledge in a PR review...but getting caught in that mess is not certainly not worth it. I only hope that if there are performance implications like GC on the iteration of the loop or something, and that if there are, compiler is clever enough to use the old method if no references are passed around

  • @codephobia
    @codephobia 10 หลายเดือนก่อน +3

    Great update. I would always forget about this gotcha after a while and do it again and again.

  • @Zed_Oud
    @Zed_Oud 10 หลายเดือนก่อน +3

    This is fundamentally why Python 2->3 happened: to limit or even eliminate ambiguity over a core feature.

  • @tokiomutex4148
    @tokiomutex4148 10 หลายเดือนก่อน +2

    That one always catches me, can't wait for 1.22 to come out

  • @Yay295
    @Yay295 10 หลายเดือนก่อน +2

    I haven't used Go, but I was surprised this was even a thing, considering this had been a known issue in JavaScript for years, and JavaScript fixed it in 2016 with let/const.

  • @ruanpingshan
    @ruanpingshan 10 หลายเดือนก่อน +1

    This takes me back to 2012, which is when C# solved this exact problem by copying the loop variable behind the scenes.
    Java got closures in 2014, and right from the start it's been a compiler error if you didn't copy the loop variable before capturing.

  • @a-yon_n
    @a-yon_n 10 หลายเดือนก่อน +1

    I can’t imagine so many people in the comments saying that they had never encountered this issue. I ran into the problem the first week I learned Go. Back then I just thought that Golang generally didn’t support scoped variables in condition statements and I had to use IIFE to avoid the problem. Glad that they admitted that it was an issue and tried to fix.

  • @cariyaputta
    @cariyaputta 10 หลายเดือนก่อน +3

    The classic tc := tc in parallel tests.

  • @x0z59
    @x0z59 10 หลายเดือนก่อน

    Yey, Go is going bigger and more popular!

  • @ant1fact
    @ant1fact 9 หลายเดือนก่อน

    Thanks for the insights.

  • @mayur9876
    @mayur9876 10 หลายเดือนก่อน +3

    Lesson learned. Use rust.

  • @GearsDatapacks
    @GearsDatapacks 10 หลายเดือนก่อน

    Great change. Love this

  • @om3galul989
    @om3galul989 10 หลายเดือนก่อน +2

    It's night and day diff when a language is being managed by experts who know wtf they're doing and not just shoving the language with shiny things.
    That's why I believe in Go's future, competency is beautiful isn't it.

    • @ddotmars
      @ddotmars 10 หลายเดือนก่อน

      lmao so true

    • @SimonBuchanNz
      @SimonBuchanNz 10 หลายเดือนก่อน +2

      This is literally the exact same issue that JavaScript had to fix. So basically Go is created by people just as expert as the people that made JavaScript.

    • @linearz
      @linearz 10 หลายเดือนก่อน

      ​@@SimonBuchanNzyeah, lol

    • @theodorealenas3171
      @theodorealenas3171 10 หลายเดือนก่อน

      It sounds like a huge milestone to be able to make GO, it sounds odd that they would be ignorant or unskilled.

  • @heathkuntz8638
    @heathkuntz8638 10 หลายเดือนก่อน

    Hilarious that I ran into this very thing just two days ago.... great change.

  • @jaysistar2711
    @jaysistar2711 10 หลายเดือนก่อน +10

    You couldn't have that problem in Rust, since the variable would have to be immutable, or copied/cloned.

    • @softed
      @softed 10 หลายเดือนก่อน

      Wow really no way

  • @To1ne
    @To1ne 10 หลายเดือนก่อน

    I wish I was there on stream to see how happy he was with that endong

  • @Sindrijo
    @Sindrijo 10 หลายเดือนก่อน

    This is such a common 'oopsie' in many languages. This exact same issue was fixed in C# 5 almost 10 years ago.

  • @crrodriguez
    @crrodriguez 10 หลายเดือนก่อน +1

    Rust : It ain't happening under the watch of the borrow checker !

  • @DryBones111
    @DryBones111 10 หลายเดือนก่อน +1

    I'm ashamed to admit that I've never considered what the scope of a "foreach" variable is. I certainly didn't consciously consider it to be the same as the indexer of a typical "for" loop. Now I am a tiny bit wiser.

  • @edantas
    @edantas 10 หลายเดือนก่อน +3

    Ah the classic headache that every go beginner goes through

    • @theodorealenas3171
      @theodorealenas3171 10 หลายเดือนก่อน

      I trust that, but it sounds odd that it's a Go thing. Do other languages help better? I've only written parallel stuff in C for Uni.

  • @RandomGeometryDashStuff
    @RandomGeometryDashStuff 10 หลายเดือนก่อน +3

    for _, v = range values {
    vcopy := v
    }
    is value copied twice (from array to v and from v to vcopy)?

    • @BenVisness
      @BenVisness 10 หลายเดือนก่อน +1

      No, the extra copy is optimized away. You can see that this is true if you enter your example into godbolt. (TH-cam won’t let me paste a link, I think, but you can Google it.)
      Notably, no extra copying occurs even when the variable is captured for use in a goroutine.
      I’d be happy to try and explain the assembly if you’re unfamiliar btw, I know it can be dense!

    • @BenVisness
      @BenVisness 10 หลายเดือนก่อน +1

      @@anon_y_mousse I meant that the second copy is optimized away - that there would not be a copy both from the slice to v and then from v to vcopy.
      In my opinion a single copy is completely reasonable. I would expect the loop variable to behave like v := array[i], not v := &array[i].
      The issue you’re concerned about isn’t one of copies but one of lifetime. Is the lifetime of the loop variable considered to be the lifetime of the entire loop or a single iteration? This does not affect performance as you seem to claim, but only the semantics of which memory locations will be accessed when the variable is captured by another function.

  • @aaronevans6442
    @aaronevans6442 10 หลายเดือนก่อน +1

    If Golang is getting close to implementing loops, they'll probably have proof of concept variables working soon.

    • @SimonBuchanNz
      @SimonBuchanNz 10 หลายเดือนก่อน +1

      Ironically, this issue was actually due to the fact the variables are a lot more complicated than people expect.

  • @theodorealenas3171
    @theodorealenas3171 10 หลายเดือนก่อน

    I think I ran into such a bug yesterday, in C. It introduced really weird errors, segmentation faults before main starts.
    I should try go a little because I don't understand this code at any level.
    Are "func" lambdas and [] fat pointers? Is

  • @hamzzak
    @hamzzak 10 หลายเดือนก่อน

    someone in the chat: Go is great, but the more it goes the better it is, it's a fine wine
    lmao

  • @vaniusrb
    @vaniusrb 10 หลายเดือนก่อน

    "...even the expert of experts at Go can't write it correctly". That was epic! What is the cost of a bug in production? Maybe dealing with Rust's difficult mental model will be worth it in the end, who knows.

  • @spacelem
    @spacelem 8 หลายเดือนก่อน

    This reminds me of a change they made in Julia 1.0 where `x = 0; for i in 1:10 x += i end` would leave you with x==0 (instead of the expected x==55) unless you modified it to `global x = i` (otherwise inside the for loop was a new scope and a new local x).
    After many many complaints they later decided that you'd get the expected behaviour in the REPL, but when called from a script it would give you a warning. Just to make this even more confusing, if you wrap that code in a function, you get the expected behaviour again, which is a real hassle if you're prototyping the internals of a function in global scope.
    Ah Julia, love the language but that is such a horrible surprise for people new to it.

  • @blarghblargh
    @blarghblargh 10 หลายเดือนก่อน +1

    code coverage doesn't say anything about quality of coverage. it is useful to tell you what you're entirely missing, and that's about it. more a floor than a ceiling

  • @sohn7767
    @sohn7767 10 หลายเดือนก่อน +1

    Very cool, about time languages fix this mistake… lots of other languages still suffer from the same fate and will continue for to do for eternity

  • @thingsiplay
    @thingsiplay 10 หลายเดือนก่อน +4

    Is Pokemon Go written in Golang?

    • @ոakedsquirtle
      @ոakedsquirtle 10 หลายเดือนก่อน +2

      Probably Java for android

    • @thingsiplay
      @thingsiplay 10 หลายเดือนก่อน +2

      @@anon_y_mousse Not sure what the state nowadays is. But wouldn't it be a national crime to call it Go, if it is not written in Golang?

    • @Nenad_bZmaj
      @Nenad_bZmaj 5 หลายเดือนก่อน +1

      @@thingsiplay Go is a 2500 years old famous Chinese game.

  • @asdfghyter
    @asdfghyter 9 หลายเดือนก่อน

    this is an excellent change and how all languages should do it. this is how humans would intuitively expect it to work anyways and there is really no use case where you would need the old behaviour

  • @MrWorshipMe
    @MrWorshipMe 10 หลายเดือนก่อน

    Why are they taking range and ignoring index? Is that how you're supposed to write for loops in Go?

  • @hereallyfast
    @hereallyfast 10 หลายเดือนก่อน

    IN foooor MA!

  • @aziz0x00
    @aziz0x00 10 หลายเดือนก่อน

    someone else uploaded this while Prime is live on twitch actually?

  • @Im_Ninooo
    @Im_Ninooo 10 หลายเดือนก่อน

    W change

  • @yurcchello
    @yurcchello 10 หลายเดือนก่อน

    CHRO-O-O-O-T!

  • @theohallenius8882
    @theohallenius8882 10 หลายเดือนก่อน

    I just got into go... what did I get myself into..

  • @nitsugaorom1091
    @nitsugaorom1091 10 หลายเดือนก่อน +1

    coconut oil

  • @dennywong2408
    @dennywong2408 10 หลายเดือนก่อน +1

    For a GC-ed language like Go, wouldn't this create a variable per iteration requiring GC, as opposed to

    • @BenVisness
      @BenVisness 10 หลายเดือนก่อน +1

      It only matters if the lifetime of the variable escapes the loop, such as in the goroutine examples. In those cases there will be more GC, yes, but you wanted that anyway because you wanted each goroutine to have its own variables.

    • @Nenad_bZmaj
      @Nenad_bZmaj 5 หลายเดือนก่อน

      @@BenVisness But when it doesn't escape, and your loop has 100 million iterations, how big the stack grows?

  • @magne6049
    @magne6049 10 หลายเดือนก่อน

    2:25 it's funny how it's not a skill issue once oneself is involved ;-)

  • @heyjitendra
    @heyjitendra 10 หลายเดือนก่อน

    I never knew this existed.
    Damn I ain't creating anything good...

  • @Diego-Garcia
    @Diego-Garcia 10 หลายเดือนก่อน

    The name is Thebuggygen

  • @complexity5545
    @complexity5545 10 หลายเดือนก่อน +1

    All of this is starting to look like perl and other languages had figured out 18 years ago.
    It amazes me that the same problems in everyone's new features and newer programming languages keep repeating the same mistake over and over again. After I punted Rust, I am back into C++ crazy template stuff. Same mistakes in all language designs.

    • @theodorealenas3171
      @theodorealenas3171 10 หลายเดือนก่อน

      I feel this way about CSS scoping, when we've got Unix.
      Also today's editors and Emacs.
      Like people want to add, not preserve.

  • @Nenad_bZmaj
    @Nenad_bZmaj 5 หลายเดือนก่อน

    And what if I don't use go routines and don't want to modify the element of slice, but just use it as a source of values? With the old compiler I'd write:
    type record struct {
    Name string
    Age int
    }
    func main() {
    ages := []int{15, 20, 25, 40}
    names := []string{"John", "Mary", "Peter", "Sophie"}
    records := make([]record, len(names))
    for i := range names {
    records[i].Age = ages[i]
    records[i].Name = names[i]
    }
    for _, rec := range records {
    fmt.Println(rec)
    }
    }
    and the iteration vars 'i' and 'rec' were reused in each iteration. Now they get saved in each iteration. This is BAD. In the best scenario for the second loop, the new compiler instructs the runtime to save only index iteration var and to use it as a reference to the element in the array. But this can still be 100 milion of ints saved per loop, if the slice is that long.

  • @IvanKravarscan
    @IvanKravarscan 10 หลายเดือนก่อน

    Min and max on any type of a number, eh, even Kotlin doesn't have that...

  • @hackebeil20
    @hackebeil20 9 หลายเดือนก่อน

    "go is becoming a really good modern language" - true. my only gripe is: why did they have to repeat all the stupid mistakes from other languages first? things like generics and package management existed way before golang. They could have just started with that right off the bat. Same goes for proper error handling, logging, flag parsing, and being able to return an effing return code from main().

  • @rickdg
    @rickdg 10 หลายเดือนก่อน +1

    So I guess that the “Go is boring” arc is over now.

  • @nexovec
    @nexovec 10 หลายเดือนก่อน

    What the frick, I had to open my go program because I had this bug there.

  • @u9vata
    @u9vata 10 หลายเดือนก่อน +1

    This indeed seemed like pretty bad design from Go originally. I honestly prefer writing out indexed for look though and many people not understand why: why? Because in all random languages always harder to fuck it up - both perf-wise and semantics-wise and also known to everyone from first sight.

  • @window.location
    @window.location 10 หลายเดือนก่อน +1

    Absolute based move by Go team, can't wait for 1.22

  • @rewplaypark
    @rewplaypark 10 หลายเดือนก่อน

    Glad to see this get addressed. The reason why this is such the pain is that Go doesn't have Optional type. We need to use things like *int to represent Optional type so it become abundant in the code and hard to catch on the fly.

    • @theodorealenas3171
      @theodorealenas3171 10 หลายเดือนก่อน

      Wait, people make integers be garbage collected so they can return Null? I haven't tried GO but that's what I get

    • @rewplaypark
      @rewplaypark 10 หลายเดือนก่อน

      @@theodorealenas3171 basically yes, especially when interacting with ORM, JSON serializing, etc.

  • @vitorguidorizzzi7538
    @vitorguidorizzzi7538 10 หลายเดือนก่อน

    1.22
    over 1.0
    fixing for loops
    lmao

  • @elderofzion
    @elderofzion 2 หลายเดือนก่อน

    i use go, rust to difficult for me

  • @Alex-hr2df
    @Alex-hr2df 10 หลายเดือนก่อน

    Sorry Rust, but Go is the most practical language for BE, hands down.

  • @anybody4802
    @anybody4802 10 หลายเดือนก่อน

    please somebody explain

    • @janAkaliKilo
      @janAkaliKilo 10 หลายเดือนก่อน +1

      array = [1, 2, 3]
      for i in array:
      list.add(closure that uses i)
      closures in the list == (3, 3, 3)
      You expect to see different i for each item in array, but clojures close over variables and not values. So every closure you added to the list - remembers the i variable, and not the value.
      How go fixed this: now address of 'i' is unique per iteration, not per loop, so every closure will see the unique variable, that won't change with next iteration.

    • @theodorealenas3171
      @theodorealenas3171 10 หลายเดือนก่อน +1

      ​@@janAkaliKilowhat I don't get is, isn't the counter a primitive type? Why is it passed by reference?

    • @janAkaliKilo
      @janAkaliKilo 10 หลายเดือนก่อน +1

      @@theodorealenas3171 because it is unique behaviour of closures. They never explicitly copy values, closures keep the reference to the address of variable.
      That is practically the definition of closure.

    • @theodorealenas3171
      @theodorealenas3171 10 หลายเดือนก่อน

      @@janAkaliKilo oh I see. I thought closure and lambda are synonyms.

  • @hakuna_matata_hakuna
    @hakuna_matata_hakuna 10 หลายเดือนก่อน

    Your excitement about go seems like a bit you've managed to commit to for this long

  • @johannes-vollmer
    @johannes-vollmer 10 หลายเดือนก่อน

    Honestly, pretty embarrassing to create a NEW language with such a flaw. Wow. Great job, Go.

  • @morphles
    @morphles 10 หลายเดือนก่อน +1

    As I said in more than one video, I thing go is just bad language. And that such crap can happen, is just another stone in their garden. Well eventually in like 10 years they might become decent, just look at PHP, it's now IMO one of the better languages at least by DX. PHPUnit for testing is hands down best thing I actually used for testing, symfony debug stuff is quite ahead of say nextjs. Exceptoins and fail fast is super nice when you get good stack traces. As opposed to errors that provide no traces, or god forbid you missed that function returns error, and it occurs, you are in for some real fun time.

  • @lungfish
    @lungfish 10 หลายเดือนก่อน

    Would not happen in Rust

  • @Nenad_bZmaj
    @Nenad_bZmaj 5 หลายเดือนก่อน

    Fixing the proper language just to let ignorant speakers talk, or: a new auto-correct.

  • @user-tv4fu9wd7u
    @user-tv4fu9wd7u 10 หลายเดือนก่อน

    c programmer: so weak

  • @Tony-dp1rl
    @Tony-dp1rl 10 หลายเดือนก่อน

    Go is such an ugly language for a new creation. I mean, did they really need to make the syntax that ugly in order to get the same amazing features?

  • @zhamed9587
    @zhamed9587 10 หลายเดือนก่อน +4

    golang is such a badly designed language. Now fix generics, interfaces, null pointers, add immutable types, add pattern matching with exhaustiveness checks, proper error handling, and then maybe it can be worth looking into

    • @a-yon_n
      @a-yon_n 10 หลายเดือนก่อน +1

      Others may be optional, but generics is a pain in the ass in Golang.

    • @annoorange123
      @annoorange123 10 หลายเดือนก่อน

      What is "proper error handling" for you?

    • @zhamed9587
      @zhamed9587 10 หลายเดือนก่อน

      @@annoorange123 Being able to compose/chain functions that return errors easily. Having errors that are not strings. Errors that are not easily ignored by mistake.

  • @vanillaface6097
    @vanillaface6097 10 หลายเดือนก่อน

    Golang - the trash of programming languages which is being praised for new features everyone else had ages ago.

  • @JorgeMartinez-xb2ks
    @JorgeMartinez-xb2ks 10 หลายเดือนก่อน

    C@@L

  • @user-kw9cu
    @user-kw9cu 10 หลายเดือนก่อน

    LETS GO LETS GO ELSETS SGO GL ELTSET LETS GOOOOOOOOOOOOOOOOO