67 karma · joined August 19, 2017
This should be an industry driven decision. Wait for the users of SAB to say it's not meeting their needs, and for them to provide clear reasons why (not hypothetical limitations, not vague falsely-equivalent comparisons to Firefox). Then we can tangibly weigh the pros against the cons.
Right now this is a solution looking for a problem. Your analogy comparing the JS runtime to iOS runtime isn't appropriate, no single company controls the web platform. Mozilla or Google or Apple or Microsoft can push for JS threads if the arguments for it make sense. Compare to WebAssembly.
In fact the evolution of WebAssembly is a good example of how this ought to happen. Imagine if the creator of emscripten opted to instead first propose a new VM/IL for the web? It would never happen because JS was already good enough. It was more natural to use JS first then create the VM with the goal of addressing the limitations encountered with the JS approach.
Let the tangible shortcomings of SAB bubble to the surface. Then we can sensibly design something that effectively addresses those shortcomings. Not a pattern-matched solution looking for a problem.
Efficient parallel GC is non-trivial to implement. In the most common implementation, you have to pause all threads before you can collect. That will often negate the performance benefits of having independent parallel threads running, especially if they are thrashing the heap with shared objects as you suggest.
Additionally your opinion is wrong, by simple counter example. Rust's type checker already has the ability to prevent data races: https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.h... This works today.
When does a client-side JS app have access to many GBs of local data that would justify a parallel algorithm? It seems exceedingly rare but maybe you can imagine an example.
If you're talking about a server side app, if your goal is speed, why would you choose JS over C++? It seems more sensible to write the parallel database search in C++ in that case.
As for appropriateness of threading for C over JS: I think the fact that JS is garbage collected makes a threading implementation a nightmare. A naive GC implementation otherwise kills performance: imagine running a parallel computing and having to "stop the world." GC at a conceptual level is inherently "single-threaded" and it will always be a bottleneck in one way or another.
Your point is that this may enable some currently unimplementable application in JavaScript. The assumption is that Firefox couldn't have existed without a free-for-all shared state thread model, which is very likely false.
I ask you, what applications does free-for-all shared state make possible that SharedArrayBuffer doesn't make possible?
This is like saying we don't have evidence that evolution is real.
Type systems are proof systems. If a type system encodes concurrency safety, and a program is valid under that system, then you can be 100% certain that program doesn't have a race condition bug due to shared state between threads.
If a type system can prove buggy concurrent code is invalid code, then by definition it leads to better valid concurrent code.
Is there any real world application that currently cannot exist without this feature? It seems like a solution looking for a problem.
I can see needing the ability for parallel JS for highly-parallel compute-heavy applications but those already seem serviced by SharedArrayBuffer.
So... why?
You run Feistel for each number 0->65535 (corresponding to the "stage" of the FizzleFade) and out comes the pixel to redden at that stage. Since it's a 16-bit number, some values will fall outside of 320x240 resolution, and you ignore those.
Just want to note that this approach (regardless of PRF) probably wouldn't have worked in 1991. Recomputing the cipher state at every pixel is probably ~10x slower than the single shift + xor in the iterative LFSR approach.
It is possible, there are many stack swapping libraries in C that don't use garbage collection/excessive heap allocations as proof (e.g. libpth). The RFC is trying to figure that out with rust, but their approach currently requires manually annotating functions with "async," creating an incompatible calling convention with existing Rust code.
Erlang occupies a similar space.
Go is another option that's less like Haskell/Erlang but its type system is lacking/ inconsistent and it requires garbage collection.
So Rust has a real opportunity here that's not currently occupied by other languages.
Especially, indirect function calls for IO functions seem fine since IO is usually much slower than a function call. Also binary size increase may not be a problem for people writing web-scale servers.
It would be great if the Rust compiler infrastructure provided the necessary hooks for re-implementing std::/using a different concurrency model and independent projects could make those "problems" trade-off decisions on a individual basis. Rust-core could just only support/ship the native threaded model to lower maintenance burden for themselves.
This divides the language ecosystem and makes it hard for library writers to support both concurrency models.
Ask anyone who has done significant async/await coding in C#/Python. It gets messy fast.
Async/Await works a little better in JS because it always has had a cooperative concurrency model, standard library functions usually don't block (except sometimes in Node). Though it's still annoying to have to check whether a function returns a promise or not.
Languages that do this right are Haskell and Go and probably Elixer/Erlang. This usually requires eschewing LibC (which usually assumes a threaded concurrency model) and writing your own runtime.
The patent system allows small inventors / startups to be competitive with large monopolies. It creates a safe space for free innovation. What is wrong with that?
It's the equivalent of having laws against stealing. How could a shop keeper run a business if stealing was not illegal?
A programming error is a sign that your program is not operating the way you expect. No correct program should ever call sqrt(-1) or overflow arithmetic.
Outside of effectively aborting the process, what other way is there to safely handle a programming error (aka bug) when encountered?
Doesn't matter how you choose to handle invalid semantic forms, either via undefined behavior, error code, exception, or assert, as long as you silently ignore it, your code is unsafe. Rust doesn't have undefined behavior but that doesn't mean it doesn't suffer from silent errors. E.g. Returning NaN from sqrt(-1) or signed integer overflow wrapping.
That's my entire point.
As a programmer your intent is to use APIs in the manner they expect. An invalid use is an invalid program. Garbage in, garbage out. No amount of subsequent error handling is going to help you. Better to abort().
The OS/process analogy doesn't hold here. The process has completely isolated state from the kernel.