Hacker News new | past | comments | ask | show | jobs | submit login

They were not advised against Go but against cgo. Part of what they want is incremental conversion and cgo is at the same time not-go[0], costly[1] and complex[2], and then you still need to manage the Go runtime (GC & al) from within your C system. That makes integrating the two difficult, especially when you want to replace the existing system piecemeal.

A pure-Go rewrite might be an option (in fact Tor seems pretty firmly in Go's use cases), but that's not what the Tor team is trying to do.

[0] https://dave.cheney.net/2016/01/18/cgo-is-not-go

[1] a cgo->c call is ~100 times more expensive than a go->go call, and ~400 times more expensive than a c->c or rust->c call https://www.reddit.com/r/golang/comments/3oztwi/from_python_...

[2] https://www.cockroachlabs.com/blog/the-cost-and-complexity-o...




go -> C calls have gotten way way cheaper in newer versions of Go. There's still overhead but it's not as bad as it used to be.


I love that the Rust core team is defending Go in a thread ostensibly about Rust and Tor.


It's still absolutely terrible in terms of ergonomics. You're forced to perform manual memory management, etc. I've done it a few times and I absolutely don't recommend it.


I'm not making any value judgements here; just saying that the times have decreased significantly since the links that were posted.


Finalizers help with memory management in the simple cases.


But C code may not keep a Go pointer that persists between calls (because GC). I can imagine that this is a problem for gradually converting code bases.


Sure but that's not what I was replying to? I was only talking about Go->C FFI. If someone didn't know about finalizers, then I've might be trying to insert `free` calls everywhere in their Go code, which could become quite annoying.

But yes, Go pointers in C code is bad juju.


Sure but that's not what I was replying to? I was only talking about Go->C FFI.

Sorry, my reply was too brief. I wanted to add that the ergonomics are bad, not just because of freeing memory (for which the inconvenience can indeed be reduced with finalizers and/or Close() methods plus defer). But rules such as this one make Go->C FFI unergonomic as well. To give one example: many linear algebra libraries (e.g. Tensorflow) have their own wrappers around raw arrays to represent tensors (with their dimensionality) [1]. As a consequence of this rule, one cannot just a pointer to the first slice element to such functions (since a pointer to a Go object would be stored in a C struct), but have to malloc an array and copy over data from the slice to the C array.

[1] There are other issues, such aligning slice memory to 16-byte boundaries.


Ah yes, you are absolutely right. I actually modified Rust's regex C API in part because of this problem in Go. I can't remember the details, but they were similar to your example where the only way to work around it was an unavoidable additional allocation.

(Of course, I think the change led to a better overall API. Go just helped me get there in a circuitous way.)




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: