Re: [go-nuts] defer vs. Python's with

420 views
Skip to first unread message

Ian Lance Taylor

unread,
May 10, 2013, 9:04:06 PM5/10/13
to s...@box.com, golan...@googlegroups.com
On Fri, May 10, 2013 at 4:47 PM, <s...@box.com> wrote:
>
> My question revolves around the design of defer. Specifically, upon learning
> about defer, I thought about the connection to Python's with statement,
> which at first glance seemed superior to me.

Go has chosen an approach that is dynamic rather than syntactic. You
can call defer in a loop. You can call defer conditionally. The
defer statement lets you defer closing a file you just opened. Both
approaches have their advantages.

Ian

Tad Glines

unread,
May 10, 2013, 9:17:50 PM5/10/13
to golang-nuts
You can construct your own "with" style patterns in Go.


Notice the second call to with() will panic, but that the "Thing" is still exited.

-Tad


On Fri, May 10, 2013 at 4:47 PM, <s...@box.com> wrote:
Hi there,

Note: This is not meant to be a waaaah-why-don't-you-have-my-feature email. I'm primarily trying to learn context, to see if I'm missing something, and also to understand the thinking behind 'defer'.

My question revolves around the design of defer. Specifically, upon learning about defer, I thought about the connection to Python's with statement, which at first glance seemed superior to me. Illustrated below:

In Python:

def insert_into_db(val):
with DbConnection() as db:
db.insert(val)
// do other stuff with db ...
// automatically cleanup db connection on with leaving 'with' block

DbConnection() would be an object which basically looks like this:

class DbConnection:
def __enter__(self):
// setup the connection
return self
def __exit__(self):
// tear down the connection
...

'with' automatically calls __enter__ on block enter, and __exit__ on block exit. From my perspective, this approach seems to reduce cognitive load on the developer (the API handles cleanup implicitly for you), and prevents incorrect use of the function.

In Go:

func insertIntoDb(val string) {
conn, err := db.Connect(val)
if err != nil {
return
}
defer conn.Close() // need to remember this every time.
conn.Insert(val)
return
}

The defer statement seems to add cognitive load and increase the chance that the developer will do the wrong thing.

I'm sure I'm missing something here - there must be a reason why the latter pattern is generally preferred over the former for general cases. Could someone inform me as to why defer was the chosen pattern? Thanks!

-- 
Sam

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages