Things about programming I learned with Go
1–10 of 157 posts
Re: Things about programming I learned with Go
#2Well, if you're using immutable data-structures, then structural sharing can be very useful. You can then pass large data-structures in constant time, and of course you can "modify" them efficiently using immutable techniques.
As long as you don't perform any writes in a shared data-structure, the memory hierarchy should be perfectly happy and no delays or locks should be necessary.
Of course, as you start scaling across multiple machines, there will be different trade-offs, as there will not be a shared memory bus.
Re: Things about programming I learned with Go
#3> Don’t communicate by sharing memory, share memory by communicating. Well, if you're using immutable data-structures, then structural sharing can be very useful. You can then pass large data-structures in constant time, and of course you can "modify" them efficiently using immutable techniques. As long as you don't perform any writes in a shared data-structure, the memory hierarchy should be perfectly happy and no d…
Which may not even be desirable: despite being built entirely upon immutable data structures, Erlang only share large binaries between processes (AFAIK even the new maps are copied despite being HAMT) to ensure process heaps and thus garbage collections are completely independent.
Re: Things about programming I learned with Go
#4Except that you can't. "You "cannot define new methods on non-local type[s],". You have to compose them. That makes the struct function definition syntax a bit moot in my opinion.
Re: Things about programming I learned with Go
#5> Authors of Go wanted to give users more flexibility by allowing them to add their logic to any structs they like. Even to the ones they’re not authors of (like some external libraries). Except that you can't. "You "cannot define new methods on non-local type[s],". You have to compose them. That makes the struct function definition syntax a bit moot in my opinion.
func *Receiver.method(arg int)
instead of func (r *Receiver) method(arg int)
The advantage is that you get to name the receiver instead of having to use a keyword name like `this` or `self`. I've come to like this design decision.Re: Things about programming I learned with Go
#6When I came to go from OO (ruby), and before I learnt to use embeddings, something blew my mind : I could always say where a function was coming from, and which functions were available in the current scope. No need to grep anymore to find from which parent class or which included module a method was coming from.
And after I started using embedding all over the place, I realized that problem was back again. Go made me love the idea of "simplicity, not easiness" and the fact that I can get what code was doing immediately, without wondering where parts were coming from. Today, I prefer to avoid embedding altogether. I use function parameters instead of types, and this also has the advantage of avoiding initialization problems (and if I omit a parameter, I'm immediately warned by compiler).
Re: Things about programming I learned with Go
#7> Authors of Go wanted to give users more flexibility by allowing them to add their logic to any structs they like. Even to the ones they’re not authors of (like some external libraries). Except that you can't. "You "cannot define new methods on non-local type[s],". You have to compose them. That makes the struct function definition syntax a bit moot in my opinion.
I've never thought of that syntax as conveying a particular statement. They could also have done func *Receiver.method(arg int) instead of func (r *Receiver) method(arg int) The advantage is that you get to name the receiver instead of having to use a keyword name like `this` or `self`. I've come to like this design decision.
You can't have:
func (r *otherPackage.Receiver) method(arg int)
Re: Things about programming I learned with Go
#8Today we're still running on go and we're more or less "ok" with it now, but it was a difficult path to get there and while it's fun to use a new language (or new anything) it's probably not the best choice for a startup product. Also when you need to hire people.
We've summarized our experiences here:
- https://bugfender.com/blog/one-year-using-go/
- https://bugfender.com/blog/go-pros-cons-using-go-programming...
- https://bugfender.com/blog/three-years-bugfender-9-5m-users/
Re: Things about programming I learned with Go
#9> It is possible to have both dynamic-like syntax and static safety
Well, you can learn that one by coding in C#, too. In fact, I have the feeling this is a general trend across several relatively popular languages these days - provide as much as possible of the benefits of dynamic typing while keeping the benefits of static typing.
I sometimes think how nice it would be if I could write my code entirely without type declarations and have the compiler or some preprocessor figure out as much of the type information as possible.
> It’s better to compose than inherit
It depends, really. Personally, I think composition is the simpler solution more often than inheritance, but sometimes it is not.
I completely agree about the error handling, though - at first it was very tedious to handle all errors explicitly, but after I while I came to appreciate it. Once I had fallen into the habit of checking for errors without having to think about it too much, detecting errors became much easier, and deciding if I could "deal" with some error or escalate it (possibly to the point of terminating my program) became more straightforward, too.
Re: Things about programming I learned with Go
#10I know that this is just a restatement of the "composition, not inheritance" mantra in Go, but it still makes about as much sense as "product types, not sum types". A more meaningful statement would be: "use inheritance to express sum types, use composition to express product types." There's no "better" relation between the two concepts, each has its own distinct purpose.
Yes, inheritance has traditionally sometimes been abused to implement a limited form of product type (for example, to work around Java's lack of proper value types), but that's a misunderstanding of what inheritance is used for.
> Go doesn’t have the concept of inheriting structs by design.
Go has automated delegation, and as we know, (automated) delegation IS inheritance [1, 2]. Some implementations of delegation are a bit more limited, some are a bit more expressive, but fundamentally they have the same purpose.