Jokes aside, semantically "implore" and "swear" are actually really good primitives for static analysis. "swear" is only dangerous because there's a chance it gets out of sync with the code it's swearing for.
HN user
first_amendment
One is a requirement, the other is a promise. The promise "result >= 0" is necessary because the compiler may not be able to prove that on its own.
I'm not talking about unikernels. I'm talking about the VMs that isolate them from each other. The VM isolation mechanism is considered secure enough to isolate malicious users, while the container isolation mechanism isn't (at least Linux-based containers).
Unfortunately containers aren't considered secure enough for malicious users while VMs are.
Hard work and smart investing sustained over a period of 30 years.
As it stands now, adding threading to JS has a negative expected value. There is more potential downside than potential upside. It's illogical and irrational to undertake the effort under those conditions.
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.
JavaScript can already do concurrent searching. Concurrent is logical, parallel is physical.
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.
C++11 allows you to write natural "value-oriented" code without paying a copying cost. This is thanks to RVO (return value optimization) and move semantics.
I made an argument. What's yours? You just made a statement of opinion without any justification.
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.
For your parallel search example, the data set has to be extremely large for parallel searching to have a significant improvement.
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.
This isn't about "paternalistic caution," it's about purposeful and sensible engineering. JavaScript wasn't designed for threading, and it's a less natural fit for it compared to a language like C, so this is understandably a pretty serious undertaking.
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?
I just don't think that we have sufficient evidence to conclude that using type systems to aid the development of concurrent code actually leads to better concurrent code.
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.
JavaScript is already concurrent. It isn't parallel though.
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?
It's unfortunate that the new version still creates __new__ using exec(). Doesn't seem necessary at all. Instead of generating the method as a string with the argument names filled in, why not use use a combination of * n and * * kw?
Only versions 1.4 and below. Versions 1.5 and above do not require an X server. Version 1.5 has been available for 5+ years: https://ariya.io/2012/03/pure-headless-phantomjs-no-x11-or-x...
Feistel is a permutation. That means it's a 1:1 mapping between a 16-bit # to another 16-bit #.
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.
You should time it :)
Always love seeing applications of Feistel cipher. Used it with AES as the PRF for implementing FPE in legacy systems.
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.
Erlang occupies a similar space compared to Haskell, in terms if it being a functional language with M:N green threads.
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.
I approximately agree with you but there are lots of reasons I'd prefer Rust over Haskell. All data is thunked and boxed in Haskell, it's all heap-allocated and garbage collected, and polymorphism is through indirect pointers. Rust allows for "zero-cost" abstractions with a powerful memory-safe aware type system.
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.
Interesting. The problems section isn't really convincing to me though.
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.
I wonder if Rust could support pluggable concurrency models (with the accompanying runtime support). That's what Haskell does and it seems to work. At the outset that seems like a better approach than creating an incompatible sub-language. The rust-facing side of the standard library already abstracts away many platform details.
async/await is nice duct tape to integrate cooperative concurrency into a thread-based concurrency model but it has the drawback of creating an incompatible sub-language for functions within the parent language. Now every time you call a function, you have to check if it is a "coroutine"/ returns a promise or if it's a synchronous function.
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.
You essentially agree with me. Aborting with a stack trace is still an abort. It doesn't need to be catchable.
Unbelievable this is downvoted. Do people not approve of the patent system? It has been in place for decades as a battle-tested way of incentivizing innovation and creates a natural process for getting trade secrets into the public domain.
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?
Patent the idea, Publish a paper, submit it to a robotics conference. Some big company with deep pockets will buy the rights to your patent for a sum of money that will be large to you and small for them.
A runtime exception is fine to handle. Like ENOENT, etc. these are expected and your program can be designed to handle these errors.
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?
If that's what Linux does, that seems fully intentional and the possible consequences on kernel state are probably well-thought out. Are you claiming what Linux does normally is unsafe and could possibly corrupt kernel state? Like every EFAULT? If that's not your claim, then the analogy doesn't hold and you're entirely missing my point.
Just because Rust has safe guards for lock usage during unwinds doesn't mean it prevents all high level data structure inconsistencies or even just plain old bugs.
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().
I trust the code as long as it's behaving correctly, when it encounters a bug I no longer trust it and I shut it down before it can do further harm. A modular HTTP server should do the same.
The OS/process analogy doesn't hold here. The process has completely isolated state from the kernel.