Live data from Hacker News

More Gotchas of Defer in Go, Part II

blog.learngoprogramming.com

11–20 of 55 posts

Re: More Gotchas of Defer in Go, Part II

#11
post #8

It's indefensible that defer works on the function and not on the scope.

Well I think the function scope the most useful, but wish there was block scope available too.

So what I really wish was that languages used dot notation to go up scope eg ..name is that name two blocks out. This was one of the good parts of VB syntax which I miss in other languages. Think how much nicer it is than python's nonlocal and global, for example!

Re: More Gotchas of Defer in Go, Part II

#12
post #8

It's indefensible that defer works on the function and not on the scope.

Well I think the function scope the most useful, but wish there was block scope available too. So what I really wish was that languages used dot notation to go up scope eg ..name is that name two blocks out. This was one of the good parts of VB syntax which I miss in other languages. Think how much nicer it is than python's nonlocal and global, for example!

It's true that defer is more powerful at function scope. You can always recover block scope with an unnamed func. But it doesn't fit with normal lexically scoped constructs. You get gotchas.

I would love to be able to explicitly affect other scopes as you mention, for example to define two classes at the same time.

Re: More Gotchas of Defer in Go, Part II

#13
post #8

It's indefensible that defer works on the function and not on the scope.

Well I think the function scope the most useful, but wish there was block scope available too. So what I really wish was that languages used dot notation to go up scope eg ..name is that name two blocks out. This was one of the good parts of VB syntax which I miss in other languages. Think how much nicer it is than python's nonlocal and global, for example!

What's the use case for function scoped defer? I have never once needed function scoped RAII in C++ or any other language.

Re: More Gotchas of Defer in Go, Part II

#14
post #5

#4 can also be fixed with: for i := 0; i

This is too sneaky and seems like poor form. I'm curious what good use-case there is for this, that the language bothered to support and allow this to even compile. Duplicate variable name declaration + referencing in the same scope is unintuitive at best, and just seems wrong .

Shadowing can be useful if you want to make sure the "old" variable is never referenced again in the same scope.

The reason why this idiom feels "weird" is that the loop construct of the language really ought to automatically make a fresh instance of the loop counter for each trip through the loop.

Re: More Gotchas of Defer in Go, Part II

#15
post #5

#4 can also be fixed with: for i := 0; i

It would be nice if Go made a new i for each iteration of the loop.

Lua 5.0 made just one loop variable per loop, like Go apparently does. When I first ran into this behavior, I thought that, although it wasn't what I expected, it made at least as much sense as what I was expecting. Since then, every single time I've been in a situation where the two ways of doing it gave different results, I've wanted the "separate variable for each iteration" behavior, so I was glad when Lua's creators changed loop variables to work like this in Lua 5.1.

(Before this change I would just do the Lua equivalent of your "Creates a new `i`" line.)

Re: More Gotchas of Defer in Go, Part II

#16
post #5

#4 can also be fixed with: for i := 0; i

It would be nice if Go made a new i for each iteration of the loop. Lua 5.0 made just one loop variable per loop, like Go apparently does. When I first ran into this behavior, I thought that, although it wasn't what I expected, it made at least as much sense as what I was expecting. Since then, every single time I've been in a situation where the two ways of doing it gave different results, I've wanted the "separate…

C# also switched to a new i for each iteration.

Re: More Gotchas of Defer in Go, Part II

#17

Earlier quoted context omitted.

Well I think the function scope the most useful, but wish there was block scope available too. So what I really wish was that languages used dot notation to go up scope eg ..name is that name two blocks out. This was one of the good parts of VB syntax which I miss in other languages. Think how much nicer it is than python's nonlocal and global, for example!

What's the use case for function scoped defer? I have never once needed function scoped RAII in C++ or any other language.

Collecting tasks from all iterations to await before returning.

Re: More Gotchas of Defer in Go, Part II

#18

Earlier quoted context omitted.

Well I think the function scope the most useful, but wish there was block scope available too. So what I really wish was that languages used dot notation to go up scope eg ..name is that name two blocks out. This was one of the good parts of VB syntax which I miss in other languages. Think how much nicer it is than python's nonlocal and global, for example!

What's the use case for function scoped defer? I have never once needed function scoped RAII in C++ or any other language.

It's not terribly uncommon for larger functions to do something like

    func someSQLStuff() {
        tx, err := createTx()     
   
        defer func() {
            if err != nil {
                tx.Rollback()
                log(err)
            } else {
                tx.Commit()
            }
         }()

         rows, err = tx.QueryContext( ... )

         // more SQL
    }
Basically, function-scoped cleanup. Like closing opened files.

Re: More Gotchas of Defer in Go, Part II

#19

Earlier quoted context omitted.

What's the use case for function scoped defer? I have never once needed function scoped RAII in C++ or any other language.

It's not terribly uncommon for larger functions to do something like func someSQLStuff() { tx, err := createTx() defer func() { if err != nil { tx.Rollback() log(err) } else { tx.Commit() } }() rows, err = tx.QueryContext( ... ) // more SQL } Basically, function-scoped cleanup. Like closing opened files.

But that defer is already lexically at the function scope, so block-scoped defer would do the same thing.

Re: More Gotchas of Defer in Go, Part II

#20
post #17

Earlier quoted context omitted.

What's the use case for function scoped defer? I have never once needed function scoped RAII in C++ or any other language.

Collecting tasks from all iterations to await before returning.

Fair enough. But it's something like 5 lines of code to write that manually, and writing it explicitly is clearer. With implicit function-scoped defer, someone might refactor the code to inline the body of the function into its caller and break it.
Post reply on HN