5,648 karma · joined March 31, 2021
Not even gonna comment on "message passing".
Those are actually mechanisms for achieving polymorphism.
Inheritence inherently (heh) consists of "inheriting" parent class' internals and having ability to extend them. It is basically composition, polymorphism and monkeypatching in a trench coat.
Somehow, it leaked out and convinced everyone that it is a good thing on its own.
If a language makes this more convenient than doing it right, one could argue that the language design is at fault.
It may be easier to just add the "?" operator everywhere (and we are lazy and will mostly do what is easier), but it often leads to problem explained in the article.
But it is already established in the industry, and fighting it is unlikely to yield any positive outcomes.
It's actually quite easy to create a C bindings for a Go library, using CGo and -buildmode=c-shared.
I'm not sure what effect the Go runtime has on the overall application, but it doesn't seem like it would be "less possible" than with Java.
First is the Google's manpower. Google somehow succeeds in writing fast software. Most Google products I use are fast in contrast to the rest of the ecosystem. It's possible that Google simply did a better job.
The second is CPython legacy. There are faster implementations of Python that completely implement the API (PyPy comes to mind), but there's a huge ecosystem of C extensions written with CPython bindings, which make it virtually impossible to break compatibility. It is possible that this legacy prevents many possible optimizations. On the other hand, V8 only needs to keep compatibility on code-level, which allows them to practically switch out the whole inside in incremental search for a faster version.
I might be wrong, so take what I said with a grain of salt.
But I deeply dislike that solution. Personal responsibility beats authoritarive control in almost all cases.
Which complicates the initial premise that
> capabilities are the simplest model in the world. You hand out objects. You can call methods on the object. What that method call has access to depends on the permissions on the object, not your permissions.
Which is exactly what the parent said. Capabilities sound simple at first, but require complex machinery to work.
Thanks for the clarification.
mutex.Lock()
defer mutex.Unlock()
And if you need to unlock the mutex in one of multiple places, you can wrap it into a sync.Once.There must be a reason Rust doesn't do something similar...
Not necessarily. If you create a diamond (or a spiderweb :) inheritence pattern, the amount of places the method can be called and overriden grows fast.
Virtual = subclasses can override them.
So basically, any subclass can call the method, and that method may be overridden in any other subclass.
It may seem like single-threaded execution doesn't need mutexes, but it is a fact that async/await is just another implementation of userspace threads. And like all threads, it may lead to data races if you have yield points (await) inside a critical section.
People may say what they want about bad design and reactive programming, but thread model is inherently easier to reason about.
And which NTP servers are those pools synchronized to?
There was a proposal for a similar feature in Go [0], but it was abandoned due to technical infeasibilty.
What exactly are the rules for when a thread is garbage collected in W++?
[0] github.com/golang/go/issues/19702
Obligatory xkcd: https://xkcd.com/1053/