Hacker News new | ask | show | jobs
by rcme 1243 days ago
If you don’t await, how do you get the result? Go returns the result even if you pass in context.Background(). Another subtle difference is that most functions take a context in Go. AFAIK, most functions in Rust are synchronous functions.

Also, changing an immutable reference to a mutable one in can land you in a world of hurt in Rust.

2 comments

> Another subtle difference is that most functions take a context in Go. AFAIK, most functions in Rust are synchronous functions.

I'm fairly certain that most functions in Go don't take a context. There are tons of helper functions like those in the fmt or strings package that don't, for instance.

Oh and let’s not forget about… basic IO. In order to apply cancelation to IO you have to create a new goroutine, wait for the cancelation, and then interrupt the io. Oh, and you need to remember to not leak that goroutine.
There are tons of helper functions in the standard library, but the standard library is quite small compared to all Go code in existence. You also can't really change the standard library, so it's unlikely you'd suddenly start needing a context in fmt.Sprintf
context.Background() is typically only used when one doesn’t care about the result. If you did care about the result, you should be passing the parent context to preserve the circuit breaker timeout in case the operation takes too long.

I think the level of pain you experience from mutable references in Rust depends on if you’re coming from an OOP or FP background. I have a FP background and so the patterns I use to build code already greatly restrict mutation. You can usually change code that updates data immutably (creating a new copy of it) with mutable code in rust because the control flow of your program already involves passing that new version back to the caller which also satisfies the borrow checker in most situations.

It’s like the ST monad in Haskell; if you modify an immutable value but no one is around to see it, did you really mutate it?

> context.Background() is typically only used when one doesn’t care about the result. If you did care about the result, you should be passing the parent context to preserve the circuit breaker timeout in case the operation takes too long.

Not true in my experience. You would use context.Background in a test situation. It's also commonly used for short-lived applications like a CLI. You can see kubectl uses context.Background quite a lot: https://github.com/kubernetes/kubectl/search?q=context.backg...

> I think the level of pain you experience from mutable references in Rust depends on if you’re coming from an OOP or FP background. I have a FP background and so the patterns I use to build code already greatly restrict mutation. You can usually change code that updates data immutably (creating a new copy of it) with mutable code in rust because the control flow of your program already involves passing that new version back to the caller which also satisfies the borrow checker in most situations.

There has to be a better solution other than needlessly copying data.

> There has to be a better solution other than needlessly copying data.

Sorry I don’t think I explained myself very clearly.

What I’m saying is Rust allows you to optimise FP style patterns by replacing copying data with in place mutation because the control flow required for handling the flow of immutable data is also well suited to satisfying the borrow checker i.e. explicitly returning the data back to the caller. Because FP patterns can’t automatically communicate through shared mutable references they also lend themselves well to Rust but without the overhead of copying data because an in place mutation can be used instead.

> Not true in my experience. You would use context.Background in a test situation. It's also commonly used for short-lived applications like a CLI. You can see kubectl uses context.Background quite a lot:

My experience with Go is entirely within the context of API and microservice design where circuit breakers are very important which is why my experience with context propagation may be different than your own.

It’s also not surprising to see context.Background() used within tests because it’s being used precisely as I described above to “discharge the constraint” because you can’t propagate the constraint to the caller because test functions in go can only take one parameter `*testing.T`.