tyoverby
Arizona Iced Tea does this and they're very successful.
You could say the opposite about Go.
1. Your PR is tested with the merge against Master. All green!
2. Another PR is tested with the merge against Master. All green!
3. The other PR goes in first. All good!
4. Your PR goes in (merge happens, but introduces a bug). Oh no!
Many languages have exceptions, but with shift/reset, you can implement your own exception handling behavior trivially, including things like resumable exceptions.
Some languages have async/await, but almost all of those implementations are state-machine based, which means that they don't compose well when used with more complex language features like generics and higher order functions.
But more than that, in continuation-based asynchronous programming, "async" functions are just normal functions that execute in an async prompt. Here's an example of a multi-user asynchronous TCP echo server in my toy language with tagged delimited continuations:
async {
loop {
let conn = accept_connection("localhost", 9999)
async {
loop {
let data = conn.next_data()
conn.send(data)
}
}
}
}
Where all of those asyncrhonous constructs (including `async` itself) are really short wrappers around delimited continuation machinery.You'll notice that the nested calls to `async` indicate that there are two asyncrhonous contexts
1. Connection acceptance happen on their own "thread" of control
2. Each connection gets their own context in which everything is internally asyncrhonous
There are actually plenty, it's just that they're usually found on-prem at a company.
> I wonder if this sort of vulnerability is possible in Rust
Rusts borrow checker is designed for the more general case of "use-after-invalidation" and `free` is treated as a simple invalidation of what happens to be a heap allocated structure.
Interestingly, the borrow checker also prevents invalidations that are still common in memory-safe languages such as iterator invalidation.
If you actually manage to get your library included, then we can compare how long it takes to update your library.
git clone <project name> && cd <project name>
<build tool> build
And have it fetch all of that projects dependencies, and then build the entire system.Anything that requires machine-wide package installation is immediately disqualified (user-wide package installation is almost as bad).
It's just like how SQL decided to write all their queries backwards making it impossible to do good autocomplete.
If you used an s-expression based grammar that still had fields and methods, then you'd get the exact same experience.
foo.bar. <- autocomplete here
vs (foo.bar.)
^ autocomplete hereIt might be true that s-expressions would make people prefer certain semantic decisions that would be difficult to analyze for autocomplete.
(Just kidding, we still do them internally too)
* Incremental re-parsing. If a user in the IDE changes the document, we need to reparse the file, but we want to do this while using as little memory as possible. To this end, we re-use AST nodes from previous parses.
* Better error reporting. Parser generators are known for producing terrible errors. While you can hack around this, by using recursive-descent, you can get information from further "up" the tree to make your more relevant to the context in which the error occurred.
* Resilient parsing. This is the big one! If you give our parser a string that is illegal according to the grammar, our parser will still give you a syntax tree! (We'll also spit errors out). But getting a syntax tree regardless of the actual validity of the program being passed in means that the IDE can give autocomplete and report type-checking error messages. As an example, the code "var x = velocity." is invalid C#. However, in order to give autocomplete on "velocity", that code needs to be parsed into an AST, and then typechecked, and then we can extract the members on the type in order to provide a good user experience.
My personal opinion is that everyone should just use s-expressions. Get rid of this whole debate :P
I view my blog as an extension of my memory. When I write things, I do it mainly for myself, rather than to appeal to other readers. Because of this, my blog gets practically no traffic. I'm happy with github hosting my ramblings for free.