A final proposal for Rust await syntax - <AUTHOR> https://boats.gitlab.io/blog/post/await-decision/ <comment><USER2> I figure the reason the proposed syntax looks gross is because other languages have been using a prefixed await for many years. The Rust decision seems well thought out though, enough to make me wonder if perhaps other languages have been doing it wrong.

My first experience with futures was in the form of QFuture ([https://doc.qt.io/qt-5/qfuture.html](https://doc.qt.io/qt-5/qfuture.html)), and there you call .result() to block and wait for the result. This postfixing is intuitive.

Rust's "?" operator is neat. I don't know if I've seen a postfix operator anywhere else yet. It's certainly possible Rust got this language aspect wrong, but as a user it feels pretty right.

Given the existence of the "?" operator, and the fact that futures resolution via postfix is intuitive (and not a new thing either), IMHO the best course of action probably is postfix. I'm not sure if literally ".await" is the best, but it's in the ballpark.

<comment><USER3> IMO it's awkward for the following reasons:

(1) It looks like a field access, and field accesses are "cheap", method invocations aren't. This breaks the 'conceptual weight' model when you look at a line of code. Field accesses are simple and understood. It becomes impossible to gauge the 'cost' of a line by looking at it unless you're intimately familiar with the workings of 'await' and there's no visual cue.

(2) If we create new such postfix operators in the future we'll have to break yet more source code by reserving yet more field names in all structs in all existing code. This whole postfix thing is proving itself nice to work with so I'd prefer a path of less destruction if we do lean more into it.

(3) It's a one-off that's different from everything else in the language that's being shoehorned into existing syntax.

IMO, it's either break existing syntax by introducing something new or break semantics of existing syntax. I'll always lean towards the former over the latter. I like it being postfix, it's very much in the '?' family of ergonomics which has shown itself quite nice to work with. I'd prefer postfix "@await" or "!await".

<comment><USER4> > there's no visual cue.

There is. Your editor is going to show the await keyword in a different color. (Unless you happen to be Rob Pike.)

<comment><USER3> There's nothing else in Rust that requires me to use an editor for a semantic cue, is there? Why start here? You are correct of course, it's more a question of Rust being just as useable right now with or without syntax coloring, this small change breaks a lot.

</comment></comment></comment></comment><comment><USER5> It seems they've settled on using a postfix approach. I can't help but feel this is a mistake. Rust is already a weird language to come to from the likes of python, Java, or Javascript, and it feels to me like this relatively unknown approach of putting the operator at the end is a mistake that will add another confusing aspect of the language.

I feel like the committee has worried about the wrong things when considering postfix vs prefix. Their main concern seemed to have been the extra syntax required to make prefix work with . And ? (i.e., (await foo).bar() ), but while avoiding this makes for a more optimized language I'm concerned they've missed the impact this will have on new people.

Or maybe I'm just a Luddite :)

<comment><USER6> > Rust is already a weird language to come to from the likes of python, Java, > or Javascript

Every time I see a statement like this, I remember a (paraphrased) statement from Rich Hickey: "[musical] instruments are made for people who can play them!".

I think unless you are specifically designing a beginner language (like Scratch), you should not take into consideration "ease of use" or "familiarity" arguments.

<comment><USER7> I wouldn't use a programming language whose designer had this attitude.

<comment><USER6> Would you also refuse to play a musical instrument, because the designers had this attitude? Pretty much all musical instruments are "hard to play" and you have to learn them, sometimes for many years.

<comment><USER8> Professional grade, expensive instruments are highly playable compared to the junk.

</comment></comment></comment></comment></comment><comment><USER9> "It has also devolved into a situation in which many commenters propose to reverse previous decisions about the design of async/await on which we have already established firm consensus, or otherwise introduced possibilities we have considered and ruled out of scope for now. This has been a major learning experience for us: one of the major goals of the "meta" working group will be to improve the way groups working on long-term design projects communicate the status of the design with everyone else."

I'll be pretty intrigued to see what they come up with for that. I've been up closer to the Go developer's attempt to connect with the community, and while I'm not going to say they've done everything perfectly on their end, I've also been sort of frustrated by the way that they'll put up a request for comments about something in particular, and a good chunk of the community replies basically throw away _everything_ they're talking about and rewrite arbitrary amounts of the language from scratch. By "everything", I don't just mean the direct proposal under discussion, but the goals of the proposal, the discussion of alternatives from other languages and how they are and are not relevant, as alluded to above the things already proposed and rejected for solid reasons, the context around the runtime and how it interacts with that... that is, not just the proposal itself, but _all_ the thought and reasoning around it too. That wasn't really the question, so to speak. This frustrates everyone, on all sides, in various ways.

A lot of the problem is structural to what is being done; there's a lot of impedance mismatch between the core designers and the community at large for any language. It would be interesting to see some explicit thought around how to address that, from a community with Rust's experiences.

<comment><USER10> It's just means there is lack of trust to core designers. They haven't proven themselves to users, that they are capable of addressing their problems and align with their interests. Obviously core devs of Google backed language cannot do better. They can only gain that trust from users within Google, not outside of Google. Not sure about Rust though.

<comment><USER11> It does not necessarily mean a lack of trust. It could be different incentives or priorities.

For example, some users might desire major redesigns of past work but not bear the cost of the rework. As such, they might perceive some small improvement without any (direct) cost.

Personally, I think some groups have moved so far in the direction of community involvement that they forget the practical implications of diversity. Leadership is hard for many reasons — one big reason is that leading sometimes means making some people unhappy. Still, this is much better than inaction.

<comment><USER12> Could you please give some examples? I think I follow Rust pretty well, but have no idea what/which-improvements/who/which-groups you could mean.

<comment> dj-wonk I don't want to name any particular people or groups, because everyone makes mistakes and has limitations.

I will say this: in my personal experience, I've been a part of groups that struggle in dealing with complex decisions. Many times they get bogged down when they don't find a clear answer that satisfies everyone or all criteria. In many cases, such groups don't have a clear leader or the leader lacks the skills, experience, and character to do what is necessary; namely, choose (and communicate) the least-worst decision that keeps the ball moving forward.

In such cases, it is not necessary (and unrealistic to expect) that everyone agree with every aspect of every decision. A leader needs confidence and persistence to make tough decisions, as opposed to abdicating leadership. Some examples of the latter include (1) ignoring a choice until some default decision is made implicitly or (2) simply choosing the idea from the most vocal person.

Put more broadly, in this context, leaders must balance four aspects: (a) scoping and framing a decision; (b) gathering diverse points of view; (c) building some degree of consensus or buy-in; and (d) making a decision. It appears to me that the Rust language team handled all four comprehensively.

</comment></comment></comment></comment></comment><comment><USER13> > Its very easy to build a mental model of the period operator as simply the > introduction of all of these various postfix syntaxes: field accesses, > methods, and certain keyword operators like the await operation. (In this > model, even the ? operator can be thought of as a modification on the period > construct.)

I like this explanation.

But this whole post could really use some more concrete examples of the at the very least the final style being used in various situations. Not just mainly `expression.await`.

Keep up the work on this, I'm excited to use this in my projects.

<comment><USER14> My dislike for the "dot keyword" syntax has been strong, but if it _is_ selected, hopefully it's at least generalized to other keywords in the future, so that `.await` doesn't stay a lone awkward exception to what dot notation means. In particular, I wouldn't mind if in the future `expr?` could be spelled `expr.try` for consistency (even at the expense of introducing redundancy).

<comment><USER15> I wonder if I would ever find something like

        my_iter
            .foo()
            .bar()
            .return

more appealing than

        return my_iter
            .foo()
            .bar();

I could see it happening, but I'll definitely need some time to get used to it.

<comment><USER13> See, now this is _exactly_ my issue with this syntax, I generally expect to be able to "chain" things with the "." notation.

<comment><USER16> You can chain .await, though.

        let n = future_of_future_of_int
            .await
            .await;

<comment><USER17> Curiously, will there be limitations to where it can be used? Eg, imagine a `foos.iter().map(|f| f.await).collect::<Vec<_>>()`?

That seems crazy, think it'll be possible?

<comment><USER18> Not as things are currently designed. This is similar to how you can't use things like the `?` operator, break, return, etc. inside a lambda and expect it to affect the outer function: it doesn't work because lambdas are treated as their own functions. Personally I think it would be cool to pursue an extension to lambdas that would allow some of those things to work, but I'm not a Rust team member or anything, just an interested observer.

<comment><USER19> Technically, `?` can work in lambda's if the return value is a `Result` - though it won't work like it's being called as part of a normal loop or whatever. That's largely mitigated by the combinators available on an interator of `Result`s.

So I think we'll just need similar tooling for lambdas - perhaps an `async` modifier for them? That (I think) would lift await stuff up to `?` in terms of lambda support.

<comment><USER18> Yep, and in fact async lambdas are already a thing on nightly. But, while I may just be nitpicking, `.map(async |f| f.await)` wouldn't do anything useful. Applied to an Iterator of Futures, it would be a no-op, kind of like (since you mentioned `?`) `.map(|x| Ok(x?)). Instead you'd probably want some combinator to turn it into whatever "Iterator but async" trait Rust eventually standardizes on – futures-rs has Stream for this purpose, but std doesn't have anything yet. That trait would have its own collect() method which would return a Future<Output=Vec<T>>, and you'd then await on that.

Yeah, I guess I'm nitpicking.

<comment><USER19> Thanks for the nitpick! I hadn't thought it through all the way. I was mostly thinking about doing async stuff with the inner stuff, but you're definitely right. I'm glad you commented because I've had to rethink it.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER20> Super excited to see async/await finally get close to MVP and landing. I am not a huge fan of ".await", but there isn't much more to be said -- my personal preference of "#await" or "@await" _does_ look like line-noise and I think there's no perfect answer to this one (await{} was too messy and no better than prefix-await, and (await foo))? had too many brackets).

I also appreciate that this proposal was insanely bike-shedded and so really, any decision is better than no decision. I would've been happy with "await << f()" if it meant we could get this feature (lots of Rust projects I'm interested in are waiting on async/await before focusing on further development).

<comment><USER21> Wouldn't "await expr" or "await@expr" (if you hate whitespace) make more sense compared to "expr await"?

        let db_conn = await pool.connect()

(Which is what e.g. Python uses, with the downside that you tend to need to parenthize more because await has very low precedence).

vs

        let db_conn = pool.connect() await

.await is not soo bad, kinda method-y

        let db_conn = pool.connect().await

<comment><USER20> I don't think "expr await" would be a good choice but that isn't the decision that was made, and I wasn't arguing for it in the first place. TFA says that using alternative punctuation was decided against because it would lead to line-noise and I don't think there's much more to discuss -- I understand that position and respect it.

My main issue with .await is that it does look method-y rather than keyword-y. But while I like Python's "await expr" syntax _in Python_ the existence of ? and chaining of methods in Rust justifies having a different syntax for it.

<comment><USER22> Python also chains methods. And having to write (await (await (await foo).bar()).baz()) is annoying.

<comment><USER23> That doesn't look like well written async code at all... You're not supposed to use await literally everywhere and especially not multiple times in a single line.

Javascript already has an answer to this (Hint it was inspired by Monads but it isn't one):

await foo.then(f => f.bar()).then(b => b.baz())

<comment><USER22> What happens if f.bar() throws an exception asynchronously?

</comment></comment></comment></comment></comment></comment><comment><USER24> Nice insight into the amount of thought going into this design proposal. It's always tricky to introduce new syntax to a language and re-using the field access notation here isn't as icky an approach as it first looks.

I don't know enough about rust to understand how this would operate during compile time w.r.t if a user tries to define a field named 'async'. Is that no longer allowed or would the compiler be able to disambiguate?

<comment><USER25> Disambiguation is easy when `await` is a keyword. [0] ;)

        error[E0721]: `await` is a keyword in the 2018 edition
        --> src/lib.rs:2:5
        |
        2 |     await: i32
        |     ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`

[0] [https://play.rust- lang.org/?version=stable&mode=debug&editio...](https://play.rust- lang.org/?version=stable&mode=debug&edition=2018&gist=b3999aad31966f91af75d501358d02bd)

<comment><USER26> Programming languages didn't used to have reserved words:

[https://en.wikipedia.org/wiki/Reserved_word](https://en.wikipedia.org/wiki/Reserved_word)

> Not all languages have the same numbers of reserved words. For example, Java > (and other C derivatives) has a rather sparse complement of reserved > words—approximately 50 – whereas COBOL has approximately 400. At the other > end of the spectrum, pure Prolog and PL/I have none at all.

I don't really know why modern programming languages bother with reserved words. Yes, it would be confusing to have a variable named 'if', but compared to all of the other ways to write confusing code in, say, C, that's barely a drop in the bucket. Plus, it's something good tooling (highlighting, for example) could obviate, as it's entirely possible to use a grammar to show exactly what role each token is playing in a statement.

<comment><USER27> I don't know about PL/I but Prolog kind of cheats, in my opinion, about the reserved words. It is very strict about naming conventions, which is (IMO) worse than having reserved words.

<comment><USER26> PL/I is syntactically like Algol, or Pascal, or C with more words and fewer brackets. At heart, it's a "normal" block-structured procedural programming language, which proves that a C clone could adopt the same basic idea.

<comment><USER22> XQuery is probably a more recent example of that. No reserved words there, just syntax.

[https://www.w3.org/TR/xquery-30/#nt-bnf](https://www.w3.org/TR/xquery-30/#nt- bnf)

</comment></comment></comment></comment></comment></comment><comment><USER28> I'm anxiously awaiting this.

I just finished overhauling a rather involved Tokio/Future based project, and having await/async in the language spec will be a big step forward (and I'm hoping the compiler errors improve as well).

As always, kudos to the Rust team for making decisions that are well-reasoned and documented and in a way that looks to the future of the language (and not just meeting a feature deadline)!

<comment><USER29> If the way async/await has fundamentally changed how you write JavaScript code is any example, this will be a tectonic shift, especially for event-driven code like you use with Tokio.

<comment><USER30> I agree that it's an important addition to the language, but I think it will be less impactful for Rust than for JavaScript because server-side JS is almost always in a domain that benefits from async IO, whereas Rust exists in many domains where async IO isn't a performance priority.

<comment><USER29> It's an important concurrency model. Perhaps Rust doesn't have a lot of async code because it's been really annoying to do it. This could change that dramatically.

</comment></comment></comment></comment><comment><USER31> While there might be a better syntax if you only care about this one feature, async/await needs to fit into an existing language, and this syntax makes sense with the rest of Rust.

This syntax makes it clear that's it's not a function or macro invocation, works the same way as '?', and allows for clear and concise chaining.

</comment><comment><USER32> Reading this feels like a person with no good choices trying to convince themselves there's no other way than their best bad one.

"This is the best proposal, except the syntax doesn't make sense, we don't know if we can implement it, and conversation has broken down to the point where we are running in circles and we don't expect to have any more ideas."

I am curious what the current way to do non-blocking code in Rust is and why it's so bad that they'd introduce this much confusion to the language design to fix it.

<comment><USER33> If every choice was obvious, there would be no need for a designer in the first place.

<comment><USER32> Who said any choice was obvious?

(Also would love your take on the question in the last line of my comment. My gut as an outsider is that the best solution may be cultural not technical, except Rust is struggling to implement cultural projects now that the community is scaling fast. But you know what I don't.)

<comment><USER33> Heres the most straightforward answer I can give: [http://aturon.github.io/2018/04/24/async- borrowing/](http://aturon.github.io/2018/04/24/async-borrowing/)

</comment></comment></comment></comment><comment><USER34> At this point I don't really care how the syntax looks. I just want to use it, been waiting soo long for this.

Problems with differentiating .await from .member can easily be solved by using syntax highlighting. Also, Rust is already strange to write, this is just one more quirk one will get used to.

</comment><comment><USER35> The designers of Kotlin also had an interesting point: await (synchronous call) should be the default, non-awaited (asynchronous) code should have a keyword indicating that it is async.

<comment><USER36> This would have been my favorite approach, and there was a discussion about doing it in Rust: [https://internals.rust-lang.org/t/explicit-future- constructi...](https://internals.rust-lang.org/t/explicit-future-construction- implicit-await/7344)

There were two main objections:

First, a Rust async function like this (using explicit lifetime annotations for exposition purposes only, normally they would be elided)...

        async fn f<'a>(r: &'a i32) -> i32 { ... *r ... }

...desugars to a sync function whose return value closes over its arguments:

       fn f<'a>(r: &'a i32) -> impl Future<Output = i32> + 'a { ... }

Sometimes you want the future to live longer than the arguments, so you write that desguaring yourself:

        fn f<'a>(r: &'a i32) -> impl Future<Output = i32> {
            let i = *r; // Deal with the reference *now* before constructing the future.
            async { ... i ... }
        }

Ideally, functions could switch back and forth between these two forms _without changing their API_ , for backwards compatibility reasons. This means you can't just auto-await calls to `async fn`s like Kotlin does- it would need to be a more complex rule.

Second, a lot of users want suspension points to show up in the program text the same way `?` does. This is nice for managing invariants- you know when you might be interrupted. (Personally I don't think this is a good reason; the borrow checker and async-aware synchronization primitives would solve the problem with less noise, but it is what it is.)

<comment><USER35> I wonder about an altenate timeline where Rust kept its lightweight threads. Marking async calls explicitly instead of marking synchronous calls with await is a step in that direction, because that's also the syntax you have with lightweight threads. What would problem 1 look like in that alternate timeline?

In that case the concept of async functions disappears and your first function becomes a normal function. The second function remains a Future building function. So I'm tempted to conclude that this problem might be a non-problem, caused by a confusion between async functions and Future building functions. Even though an async function desugars to a Future building function, they are conceptually distinct in the lightweight threads model. With lightweight threads, all functions are async functions. A future building function explicitly builds a delayed computation. The types _should_ be different.

An async function is just like a normal function, except that it may call async APIs (i.e. other async functions). Calling an async function from a normal function is an error; it does not return a future. The programmer never sees that async functions are implemented with Futures under the hood. In particular, an async function is _not_ syntactic sugar for wrapping its body in an async block. We rename the async { ... } keyword to future { ... }, which constructs a future out of the block. You may call async functions in a future block. So if you want to call an async function inside a normal function, you must do future { foo() }, making it syntactically clear that the call is delayed _even when the call is made from inside a normal function_. The programmer no longer needs to think about how async functions work at all. Don't tell them that future{ foo() } actually will just call foo(), and foo() returns the future, they don't need to know that. The only thing they need to remember is that async functions can only be called from within async functions or future blocks. In all other respects they behave the same as normal functions. All delaying of computation and running computation in parallel is explicit.

IMO, problem 1 only occurs to programmers that have been told that async fn = Future returning function. That's a leaky abstraction; it's syntactic sugar. If you prevent them from developing this notion, the problem simply doesn't occur. To understand the main proposal for async/await you basically have to understand what desugaring the compiler is doing. With the "Explicit future construction, implicit await" you can use async functions and futures without understanding how they work under the hood. It's a non-leaky abstraction.

IMO, problem 2 is a problem for the IDE. The IDE can easily show which function calls are async and which are not.

<comment><USER36> I tried to lean pretty hard into "this syntax is just like threads" in that internals.r-l.org post, when I wrote it, proposing almost exactly what you describe here. Unfortunately problem #1 is not a result of confusion or unnecessary conflation, but a fundamental question of lifetimes- the exact same problem _already exists_ with normal OS threads just as it would with lightweight threads.

That is, a function is always allowed to hold onto its arguments until it returns. If its execution is deferred (e.g. `|| the_function(and, its, arguments)`) for whatever reason (e.g. spawning a lightweight thread or async task), the borrow checker has to consider that those arguments may stick around indefinitely.

Of course, it is 100% doable to force people to work around this just by giving future-building functions a different type. But as I described, this means callers have to add or remove an extra `.run()`/`.await()`/etc. if the API ever switches between the two. This is accepted in the world of threads, but not in the world of futures, because _we already have a solution_ which is "just switch to a future-building function, everyone's already awaiting it."

(Personally, while I certainly see it as a real problem, I would rather we just live with it. It's not hard to work around, and we already do it in the world of threads when necessary, which is rarely.)

<comment><USER35> I still don't understand why #1 is a problem.

> But as I described, this means callers have to add or remove an extra > `.run()`/`.await()`/etc. if the API ever switches between the two.

Switches between what though? When you want to do something asynchronously, you indeed build a future and later .await() it. Suppose you then want to build that future in a different way, for example by transforming future { foo(x) } to making foo(x) itself return the future (i.e. moving the future{} block inside foo), possibly because you want to dereference x before building it. Well, the .await() was already there, and doesn't need to be changed. The future{} ... await() pair gets introduced when you want to making things asynchronous, which is exactly as it should be?

Furthermore, isn't that the same with the main async/await proposal? It is indeed true that when you make things async you only have to mark a function as async, and then all the calls to it automatically become async. However, at the end of the day you still need to await those futures or else they won't do anything. So when you switch from sync to async you still need to add those awaits.

The difference seems to me the other way around: with the main proposal you need _more_ awaits (namely, at all points where you want to stay synchronous). With your proposal you need more async/future blocks (namely, at all points where you want to switch to asynchronous).

I think that using the same keyword for async fn and async{} block is a source of confusion, because it makes it seem like async fn is basically like wrapping the body in an async{} block. It's what makes people think that an async fn is like an automatically awaited future, which is a confusing way to think about it and makes it hard to see why this proposal is a good idea (even if it's actually implemented like that under the hood). I think it becomes a lot clearer if you use a different word for these two concepts (like async fn and future{} block), and remove the ::new() and only use future{} syntax.

This proposal does raise another question: why not just green threads, and remove the concept of async functions entirely?

<comment><USER36> > This proposal does raise another question: why not just green threads, and > remove the concept of async functions entirely?

Making another reply because this is completely unrelated...

Rust already tried that. The problem is that Rust has a hard requirement as a systems language to _support_ , at least, native I/O APIs, and the green threads implementation added a pervasive cost to that support because all standard library I/O had to go through the same machinery just in case it was happening in a green thread.

That overhead made green threads themselves basically no faster than native threads, so they were dropped before 1.0 to make room for a new solution to come along eventually. Futures and async is that solution, and it turns out to be much lighter weight than green threads ever could have been anyway- no allocating stacks, no switching stacks, no interferering with normal I/O.

The syntax could have been different, but the implementation is far better this way.

<comment><USER35> Couldn't green threads in principle be implemented the same way as your async proposal? The compiler could infer which functions need to be marked async. To support separate compilation it might need to compile two versions of each function, an async one and a normal one. You'd have exactly what you have in your proposal, except you never have to write async fn. You could still have blocking & non-blocking IO. It wouldn't totally unify green threads with OS threads, but Futures/async/await don't do that either.

<comment><USER36> Yes, though you probably wouldn't call them green threads anymore at that point. (I mean, Rust async/await is implemented that way modulo syntax and it's not called green threads. But that's beside the point.)

In fact Rust has already thrown out separate compilation with its monomorphization-based generics, so making functions "async polymorphic" in the same way wouldn't be anything new.

And while that's somewhat unlikely from what I can tell, Rust _is_ getting a little bit of that "effect polymorphism" somewhere else- generic `const fn`s can become runtime functions when their type arguments are non-const. So maybe someday we'll be able to re-use generic functions in both sync and async contexts depending on their type arguments.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER3> After reviewing the syntax writeup, I've reached my own decision on what color the bikeshed should be.

I like the "Unusual other syntaxes: Use a more unusual syntax which no other construction in Rust uses, such future!await." [1] (or future@await). It makes sense because it is in fact something different than what exists anywhere else in Rust so it should receive a commensurate syntactic treatment. This was written off pretty quickly in [1] but it appears the most consistent with language philosophy -- specifically because it's inconsistent with any other language features it should get inconsistent syntax. I think that's what's throwing people off in this process: an attempt to impose 'consistency' on something that just isn't. As such, it'll never feel natural to co-opt existing syntax. Let's embrace it's inconsistency and introduce new syntax.

It supports '?' and '.' natively, and offers a path forward for new similar kinds of postfix operators without making more field names off-limits -- even the expr@match { .. } postfix expression thrown around would fit well. The @-prefixed postfix operator would return a value like all other expressions.

tl;dr: Either the syntax is inconsistent or the semantics are, and IMO, the former is preferable to the latter.

Either way, cool to see this feature moving along! Looking forward to using it no matter how it's spelled out haha.

[1] [https://paper.dropbox.com/doc/Await-Syntax-Write-Up-- AcIbhZ1...](https://paper.dropbox.com/doc/Await-Syntax-Write-Up-- AcIbhZ1tPTCloXb2fmFpBTt~Ag-t9NlOSeI4RQ8AINsaSSyJ)

<comment><USER37> I'd tend to agree with you, except for the fact that Rust reserved words are reserved _everywhere_. Even if the syntax were changed, you still couldn't name a field "async" or "return". Since it's no _extra_ burden on the namespace, I'm less opposed to it.

I'm on the fence about disambiguation via unique punctuation, vs avoiding Perl-like line noise.

</comment></comment><comment><USER38> The syntax feels a bit Ruby-ish, doesn't it? Here's an example from the article of how they could expand the syntax in the future:

      foo.bar(..).baz(..).match {
        Variant1 => { ... }
        Variant2(quux) => { ... }
      }

Compared to some Ruby:

      5.times {
        puts "Hello world!"
      }

Note I'm by no means an expert in Ruby or Rust, this is just what I thought of when I saw the syntax.

<comment><USER39> A .match "method" just opens the dam to "why stop there?"

I prefer Kotlin's general approach of .let and similar:

        number = foo.bar().baz().let {
          match it {
            A => 1
            B => 2
          }
        }

Now anyone has the general tool for chaining without needing library authors or language designers to create the API for them.

<comment><USER31> Neat! When working with Options/Results/Iterators, you can use `.map` [1] for exactly this purpose. It would sometimes be convenient to have something like `.map` / `.let` on unwrapped values as well.

[1] [https://doc.rust- lang.org/std/option/enum.Option.html#method...](https://doc.rust- lang.org/std/option/enum.Option.html#method.map), [https://doc.rust- lang.org/std/result/enum.Result.html#method...](https://doc.rust- lang.org/std/result/enum.Result.html#method.map), [https://doc.rust- lang.org/std/iter/trait.Iterator.html#metho...](https://doc.rust- lang.org/std/iter/trait.Iterator.html#method.map)

</comment></comment></comment><comment><USER40> Here's a question that may sound a little naive but I'm behind on where the Rust async stuff is shaping up and I don't know what to search for to answer it.

You can of course already do async things in Rust the same way you do in C: by passing around function pointers and either passing around a handle to the event loop or, more commonly, using a single global handle. But you theoretically could run multiple event loops (one per core, say) and could pass around a pointer to which event loop you wanted to work with and a lot of libevent examples do this. (IMO it's the only correct way to do it, but I have sympathy for wanting to have the global variable.)

This is a little different to Javascript where the event loop is part of the language/runtime. Javascript's "the event loop" model means you can't run more than one event loop per runtime, so it's kind of nonsense to want to pass it around explicitly.

Rust is more like C in this regard. So if I wanted to mix threads and events, or run an event loop per core, or have an event loop that my Fancy HTTP Library manages itself but exposes a blocking interface to, do I lose access to the new fancy `.await` syntax? There's nowhere in this syntax to say which event loop I'm registering myself with. Is there just one global one? Does it get globally registered on runtime boot, and everyone references it? Or is there a thread-local variable for the "current" event loop that this thread knows about?

Even more concerning is how to make _other_ libraries do this than the one I'm writing. If I'm calling into an async library how can I tell that library that I want it to use "an" event loop instead of "the" event loop?

What should I be googling for to answer this? :)

<comment><USER33> You do not lose access to it.

A short version of the answer is that at its core, you create a chain of futures, and then place them on an executor. The executor is responsible for executing them.

Async is sugar for creating a chain of futures. Doing that stuff is a property of the executor. Completely different axis.

(And tokio today has a multi-threaded, work-stealing executor, for example.)

<comment><USER40> I see, so the "root" Future in the chain is bound to an executor and that's where the "which event loop" part is specified

</comment></comment></comment><comment><USER41> Wow, this is the only suggestion I really didn't like. I'm really happy that it's progressing forward, but I can't help but feel that staying with the macro and postponing the decision would've been a better choice.

A language should, in my opinion, not depend on syntax highlighting.

<comment><USER42> What good will postponing do? The blog post implies that it's already been debated for a long time and all the arguments seem to have already been brought forth. You can't just keep punting it forever; it has to get stabilized at some point.

<comment><USER41> It's been debated, but there's hardly any code using it. After seeing how it's being used by most people, it'd be easier to make a choice.

<comment><USER33> Because it's been clear that what exists is not stable, many people are waiting until it's stable to try.

There were a number of people who converted code to the various proposals, so that helped.

</comment></comment></comment></comment><comment><USER43> The process for how this feature is being handled is fantastic, and a great example of what I love about Rust and its community.

</comment><comment><USER44> I'm sold. This post did a good job of addressing my concerns with the syntax, plus a couple others. I'm now looking forward to postfix match.

I still kind of want postfix macros, though. I saw a couple other neat use cases like `file.write!(...)`

<comment><USER45> User definable postfix macros might be nice, I don't know.

But we don't need user definable postfix macros to have a single `expression.await!()` as a magical macro. There are already magical macros, and to most Rust users `foo!()` means "magic here, read the docs". It would have been syntactically consistent to have `await!()` also mean "magic here, read the docs".

100% of Rust users will recognize the inconsistency of overloading field access syntax. Only a portion of Rust users will dig deep enough into macros to recognize that `expression.await!()` is special and is not defined as a normal macro. By the time a user digs deep enough to realize that, they are ready to understand why that inconsistency was necessary.

With `expression.await` new users may ask about the inconsistency and the answer will be "because reasons you can't understand right now".

</comment></comment><comment> lachlan-sneff I'm curious as to why the mandatory prefix syntax wasn't chosen (`await {...}`). It's less magic than a magic field and it fits into preexisting syntax better.

<comment><USER46> I'm not sure why it wasn't chosen, but I can give you some arguments against it. The braces introduce line noise. They introduce a new scope. I believe that rustfmt will currently put a newline after the opening brace. And it has the general problem that it can't be read from left to right.

(P.s. I'm not trying to start a debate, just trying to answer the question.)

</comment></comment><comment><USER47> I wonder why similarly to the existing `yield` keyword operator in the experimental generators support doesn't rate highly in the decision making here. Maybe they plan to revise generators to `expression.yield`, too? Also `expression.return`?

Control flow from a dot-access rubs me just a bit the wrong way - honestly, I'd rather the syntax be a bit cumbersome because if I saw multiple nested `await`s in a single expression, I'd think the code was suspect and review it more, while I'm probably not going to have quite the same reaction for `x.await?.await?.foo.await?`, just because it _looks_ like normal property chaining.

</comment><comment> james-mcelwain Really don't like the magic field access syntax.

<comment> apk-d Having done most of my work in C# and TypeScript the Rust syntax felt _weird_ when I read about it, but on the other hand, I always felt bad being unable to readably chain awaits, least they become

      var result = (await (await obj.DoSomething()).SomeOperation()).SomeValue;

In the end, all syntax is magic that you need to get used to, I guess.

<comment><USER48> Do notation solves that problem!

<comment><USER49> Came here to say that. I think do notation (and applicative idioms) are easily one of the most-underappreciated features outside the Haskell community.

<comment><USER50> Scala has had monadic do-notation (called 'for-comprehensions') for a long time and OCaml has recently gained both monadic and applicative 'do notation' (called various things, but mostly 'let+ syntax'). Edit: Oh and F# has also had computation expressions for a long time.

</comment></comment></comment></comment></comment><comment><USER51> This is way way off-topic but: I have never seen the word "postfix" used in this way. "Suffix" is the normal/common English word for this as far as I've always been aware.

A quick search has it listed it as a synonym, but I can't find any usage outside tech and it sure seems like a tech-industry/coding erroneous neologism trying to balance the seemingly logical "post" -vs- "pre".

Am I way off the mark here?

<comment> dj-wonk Yes, "postfix" is commonly used. See [http://www.cs.man.ac.uk/~pjj/cs212/fix.html](http://www.cs.man.ac.uk/~pjj/cs212/fix.html) or [https://en.wikipedia.org/wiki/Reverse_Polish_notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation)

<comment><USER51> Reverse polish notation is an entirely different usage: not the same meaning as used in this proposal.

It's also commonly used as the name of a piece of email software, but that's also an unrelated usage to this.

<comment> dj-wonk No.

RPN and postfix notation refer to the same core idea. From Wikipedia: "Reverse Polish notation (RPN), also known as Polish postfix notation or simply postfix notation, is a mathematical notation in which operators follow their operands, in contrast to Polish notation (PN), in which operators precede their operands."

Can you please explain why you wrote "Reverse polish notation is an entirely different usage"? With a citation, preferably.

<comment><USER51> Reverse polish notation is a term used in mathematical notation for an a alternative operator syntax to the more common "infix" notation.

The article describes affixing the word "await" to methods in a programming language as a "postfix" and explicitly contrasts it with a "prefix", which is a linguistic term for affixing words, commonly contrasted with the term "suffix".

<comment> dj-wonk I don't see any reference nor any clear argument supporting your claim that RPN and postfix notation are different.

Again, RPN and postfix notation mean the same thing.

Here are some more references that show how these terms are commonly used:

1\. [https://en.wikipedia.org/wiki/Infix_notation](https://en.wikipedia.org/wiki/Infix_notation)

2\. [https://en.wikipedia.org/wiki/Polish_notation](https://en.wikipedia.org/wiki/Polish_notation)

3\. [https://en.wikipedia.org/wiki/Postfix_notation](https://en.wikipedia.org/wiki/Postfix_notation) (which redirects to a page on RPN, which is very strong evidence that your claim is incorrect)

Ok, onto the next thing. You wrote:

> The article describes affixing the word "await" to methods in a programming > language as a "postfix" and explicitly contrasts it with a "prefix", which > is a linguistic term for affixing words, commonly contrasted with the term > "suffix".

I'm not getting your point. I don't think you are summarizing the language accurately. Perhaps you could quote the section of the article at length.

Here is one quote from the article: "The lang team proposes to add the await operator to Rust using this syntax: `expression.await` This is what's called the "dot await" syntax: a postfix operator formed by the combination of a period and the await keyword. We will not include any other syntax for the await operator."

Here is another quote: "Our previous summary of the discussion focused most of our attention on the prefix vs postfix question. In resolving this question, there was a strong majority in the language team that preferred postfix syntax. To be concrete: I am the only member of the language team that prefers a prefix syntax. The primary argument in favor of postfix was its better composability with methods and the ? operator."

These usages of "prefix" and "postfix" are consistent and idiomatic.

I hope this clears it up.

</comment></comment></comment></comment></comment></comment><comment><USER52> I trust that they've made the best decision.

</comment><comment><USER53> They dismiss the best option - choosing another symbol instead of a period with hardly a though because they don't lke "line noise".

Just as `?` was introduced, I don't see a good reason ("line noise" doesn't even count as a thought) that they wouldn't introduce postfix notion with `@` `#` `$` or any thing else similar.

If they are looking forward to expanding postfix synax for things like `match`, then this would provide them with the most flexibility and essentially provide a new namespace for those features.

"Line noise" isn't a reason. APL had it right in that consistent syntax (Perl doens't count as consistent) is useful.

</comment><comment><USER54> Since `await` is a keyword reserved for this purpose, could `(await expression)` ever mean anything else? What is the cost of ripping off the bandaid and starting there, as at least an alternative syntax that is consistent with the language?

      match expression
      await expression

It feels like a future proposal, to allow these keywords to be chained more conveniently with a postfix. It's cool that this can possibly be generalised for chaining ergonomics.

      expression.match
      expression.await

      expression<-match
      expression<-await

<comment><USER30> I expect a proposal of this nature to pop up relatively soon. If I had to guess, I'd say the reason they're not doing this now is because they only want to choose one option for the MVP, and they've decided that they prefer this option to that option, and that the chosen option fortunately does not preclude the future option.

Also, I would expect `await` to have mandatory braces, just as `match`, `if`, `for`, etc. do.

</comment></comment><comment><USER55> As an old salty programmer, I don't understand why people are upset at this. Sure the syntax is unusual, but they had good reasons for it, and people are adaptable and get used to things.

Personally I like the fact that ".await" emphasizes that you are dealing with something fundamentally different from other language constructs, because futures _are_ fundamentally different.

</comment><comment><USER56> To me, this syntax feels like a "magic" method call (like in languages where a field access can go through a getter method). That is, if you can think of "x.await()" as a compiler-implemented method call on x which does some stuff and returns a value (plus some magic to allow you to omit the parenthesis), this syntax looks intuitive enough.

<comment><USER14> Except that, as described in the article, `await` is fundamentally a control flow construct and too magical to be ever considered a "sort of a method call". It's not really a useful mental model. No function is supposed to be able to reach outside its definition and _rewrite the control flow_ of its caller.

</comment></comment><comment> Const-me Language syntax and futures is only a half of the problem. IMO actual async IO implementation is harder.

Too many incompatible platform-specific APIs: epoll and AIO on Linux, kqueue on BSD and OSX, IOCP and new thread pool API on Windows. I'm pretty sure I forgot couple others, and each of them have non-trivial amount of quirks, bugs, and performance-ruining edge cases. Also these APIs are not directly compatible to each other.

To be usable, async IO needs to be integrated into the rest of IO. You can't just place that on top, e.g. Java did that, IMO didn't work particularly well.

The combination of the above makes creating good cross-platform abstraction for async IO challenging.

Not saying impossible, but it's very hard to do.

I've tried once in C++, for that project I needed epoll and iocp, but I wasn't able within reasonable time. Ended up swapping relatively large IO-related parts of my app depending on platform.

<comment><USER46> Most of the work you're talking about has been completed for a long time in the crate "mio". It abstracts out all of the platform dependent async io operations into a single consistent interface.

<comment> Const-me Are you sure about that?

I've looked at the library, it doesn't support anything besides epoll and IOCP, i.e. no BSD or OSX support, no AIO on Linux (the kernel one, not POSIX).

You probably don't want to consume IOCP API on Windows anymore, Vista introduced higher level and easier to use StartThreadpoolIo and friends.

Also on Windows, even with IOCP, you don't want to split async IO from thread pool. The OS kernel manages them both at the same time. Work stealing or other custom scheduling is usually slower than what kernel does.

<comment><USER46> It says that it is also backed by kqueue and supports FreeBSD , NetBSD, and OS X.

I found this issue where they're discussing rewriting the Windows implementation using the library `wepoll`.

[https://github.com/tokio-rs/gsoc/issues/3](https://github.com/tokio- rs/gsoc/issues/3)

What would be the advantages of supporting AIO on Linux?

<comment> Const-me > rewriting the Windows implementation using the library `wepoll`.

Interesting idea but I don't like it too much. While removing the huge complexity of manually managing IOCP and required resources, It's an undocumented API. New Vista+ threadpool-based IO also removes that complexity, removes complexity of implementing thread pools in the higher level in Tokyo. It's documented and supported, and Rust has issues with WinXP support anyway.

> What would be the advantages of supporting AIO on Linux?

Faster async disk IO for the apps which are OK with the limitations, i.e. which read/write complete blocks of O_DIRECT files. Databases come to mind.

BTW, io_uring feature coming into Linux kernel removes most limitations of AIO while also improving performance.

</comment></comment></comment></comment></comment><comment><USER57> It was glossed over why `await expr` isn't in the running; I take it it's because the language team doesn't like the necessity of adding parentheses any time you want to do postfix expressions on the await results e.g. `(await foo()).bar()`?

<comment><USER36> That was discussed in a previous post, but yes that's why. And in Rust, the biggest postfix expression is the extremely common `?` operator, expected to be used with _most_ futures.

<comment><USER57> I haven't really been following along very much. I take it from your comment that await in Rust will not automatically propagate errors upwards like it does in JavaScript? So you have to use `foo.await?` in the normal case if you only want to handle successful results?

<comment><USER36> That's correct. In a sense Javascript await isn't the thing that propagates errors, that's just the language's usual exception behavior plumbed through the Promise.

<comment><USER57> That's actually a really good point, I never thought of it that way.

</comment></comment></comment></comment></comment><comment><USER3> Serious suggestion, and I assume you have -- have you considered ".await?" as an alternative? It won't conflict with field names and cribs on the fact that "?" changes control flow.

<comment><USER57> That conflicts with `.await` + the ? postfix operator. Namely, if `.await` returns a Result, the ? operator could then be used like it is in code today. In fact, this was referenced in the article:

> _The primary argument in favor of postfix was its better composability with > methods and the ? operator._

<comment><USER3> Yeah, I thought that through after, and revised my thoughts. I wrote it up top-level but I think the best way forward is embracing that this isn't consistent with anything else in Rust and introducing new syntax, specifically '!await' or '@await' postfix operator. The reason there isn't a good answer that's consistent is that the behavior is inconsistent. As such, it needs new syntax.

Either the syntax is inconsistent or the semantics are, and IMO, the former is preferable to the latter.

</comment></comment></comment><comment><USER58> I'm very conflicted. In one hand I'm happy that becoming practical, on the other hand: await and async is the best these awesome PhDs could come up with? They where really in the forefront in so many regards that I kind of expected something mindblowing.

</comment><comment><USER59> I wish more language constructs used postfix notation. It looks so natural to me when reading from left to right. Consider:

[a+2 for a in as if a > 3]

Vs

as.filter(a -> a > 3).map(a -> a + 2)

Sometimes I even wonder why variable assignment has to precede the assigned expression.

<comment><USER30> _> Sometimes I even wonder why variable assignment has to precede the assigned expression._

I think there's a good discussion to be had on preferring either prefix or postfix operators, but the answer to this question (which is also the answer to the question "why are we so accustomed to prefix keywords?") is easy: because ALGOL did it.

</comment></comment><comment><USER60> Don't forget to consider dot-dot-await (EXP..await)as well.

</comment><comment><USER61> Postfix works because Rust doesn't have piping or do-notation. I don't care either way though, I'm welcoming await to the family & excited to use it.

</comment><comment><USER62> Why doesn't Rust just implement HKT and then make a Future a monad. It seems to me that Rust has too many special things that arise from a lack of expressiveness as it is.

HKT would make things considerably nicer.

<comment><USER33> [https://twitter.com/withoutboats/status/1027702531361857536](https://twitter.com/withoutboats/status/1027702531361857536)

</comment></comment><comment><USER63> In the off chance that some Rust developers are looking at this thread, I'd like to put forward a counter-proposal:

1\. Use a postfix ?! instead of .await

2\. Use a postfix ?? instead of .await?

3\. Use the await keyword only in the "for await" construct

Then the common case becomes:

        let resp = http::get(url)??.to_string()

Which, imo, is a bit easier to parse than:

        let resp = http::get(url).await?.to_string()

This would make it easier to follow the core logic in async code, the same way that ? made error handling so much cleaner in Rust.

<comment><USER64> I think the ?? can be already used for Result<Result<_,_>,_>.

I agree that the syntax should have `await' somewhere, and the observation that it "clearly" is not a field access is actually credible to me. This also open the possibility to have other kinds of postfix keyword e.g. .try or .match</comment></comment>


Widespread Weak Keys in Network Devices - <AUTHOR> https://factorable.net/

<comment><AUTHOR> Linus merged a patch from Ted Tso to address this discovery:

 _""This patch series contains a major revamp of how we collect entropy from interrupts for /dev/random and /dev/urandom.

The goal is to addresses weaknesses discussed in the paper "Mining your Ps and Qs: Detection of Widespread Weak Keys in Network Devices", by Nadia Heninger, Zakir Durumeric, Eric Wustrow, J. Alex Halderman, which will be published in the Proceedings of the 21st Usenix Security Symposium, August 2012. (See <https://factorable.net for more> information and an extended version of the paper.)"_

[http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git...](http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=3e9a97082fa639394e905e1fc4a0a7f719ca7644)</comment>


3d cube spinning in pure CSS - <AUTHOR> http://www.paulrhayes.com/experiments/cube-3d/index.html

<comment><USER2> Well, maybe it is my renderer (Chrome in Mac OS), but it looks like a rotating plane. Not a cube.

<comment><USER3> Chrome with windows is the same...</comment></comment>


Bernie Sanders wants Elon Musk to pay a one-time $27.5B tax - <AUTHOR> https://www.teslarati.com/elon-musk-bernie-sanders-one-time-tax/ <comment><USER2> Contrary to the title, the proposal is not only endorsed by Sanders and does not single Musk out.

Official write-up[1] proposes taxing billionaires for their gains made only during the pandemic.

For those not in the US, you should know that this proposal has no chance of being passed (even if Democratics take control of all three branches of the federal government next year). It's an attempt to point out the disparity between those suffering and those gaining from the pandemic.

1\. [https://www.sanders.senate.gov/newsroom/press- releases/sande...](https://www.sanders.senate.gov/newsroom/press- releases/sanders-colleagues-introduce-tax-on-billionaire-wealth-gains-to- provide-health-care-for-all-)

</comment><comment><USER3> How about he donate one of his mansions.

<comment><USER4> He would be targeted just the same as everyone else. He didn't gain one of his mansions during the pandemic as a result of the government printing massive amounts of money in order to "secure a stable market" while letting the average taxpayer fend for themselves.</comment></comment>


Eve Dev Diary (August 2016) - <AUTHOR> http://incidentalcomplexity.com/2016/08/31/august/ <comment><USER2> I was really confused when I saw this that the Eve Dev Blogs, [https://community.eveonline.com/news/dev- blogs/](https://community.eveonline.com/news/dev-blogs/), were being posted on HN. For others this is a new programming language called Eve and is completely unrelated to the video game Eve.

<comment><USER3> Here I was hoping others were getting as excited about clone states (free to play) as I was.

</comment></comment><comment><USER4> What's interesting to me is that the more Eve develops the more it seems to be returning to its LightTable roots. This isn't a bad thing, there's still plenty of life in the LightTable approach, but my impression of Eve before was that it was designed to be a tool that non-programmers would use. Based on this latest blog post, it appears that may be of less importance. I still hope Eve continues to develop in its current direction, I'd like to see how the immediate feedback and flexibility of Eve can continue to be refined.

<comment><USER5> A programming language that non-programmers can use is like a written language that illiterate people can read: it's an oxymoron. (The minute you can use it, you're a "programmer"; the minute you can read, you're "literate")

<comment><USER6> Not everyone who writes is necessarily a writer. In the same vein, not everyone who wants to tell a computer what to do wants to be a programmer.

<comment><USER5> but when people say "that non-programmers can use" they don't mean "that people whose job title isn't 'programmer' can use." They mean "that people who can't program can use." it's a bit confusing and I suppose I could be wrong. (They could mean "people whose job title isn't 'programmer.'")

<comment><USER7> Somebody who makes a spreadsheet is telling a computer what to do. Are advanced users of Excel programmers?

Businesses occasionally express the business rules in the form of spreadsheets to be directly implemented into code.

Spreadsheets even double as unit tests.

<comment><USER8> > Are advanced users of Excel programmers? Yes.

Edit: here's a previous discussion about a Turing Machine in excel - [https://news.ycombinator.com/item?id=6416631](https://news.ycombinator.com/item?id=6416631)

</comment></comment></comment></comment></comment></comment><comment><USER9> You can do the same style of programming using the ClojureScript libraries reagent/posh/re-frame/datascript. Why not just use those?

It isn't clear to me what Eve offers that those don't.

<comment><USER10> To me your comment reads like the infamous "why not use FTP and this hodgepodge of CLI tools" comment on the original Show HN for Dropbox. Eve is trying to bring everything together into a unified, standalone package, with the goal of being more accessible to non-specialist developers (think people who write Excel macros).

[http://www.witheve.com/](http://www.witheve.com/)

<comment><USER9> Hmm, I don't think the situations are even remotely comparable when you look at the actual projects.

With Eve, you still have to learn their home-grown programming language. That is non-trivial. If you didn't have to learn a completely new programming language along with its own non-standard terminology and idiosyncrasies then I would agree.

I am aware of what they are trying to do -- I've been following the team for the last 4 years. I liked their approach of starting from first principles, but at some point they lost the plot.

<comment><USER11> Out of curiosity, would you say the same thing about Clojure? It's also a home-grown language with its own non-standard terminology that is non-trivial to learn. Any fundamentally interesting change in programming will fit that description. Rust, Go, even Typescript, add a bevy of new syntax constructs and a whole set of terminology that isn't shared with other languages (borrowing, type definition files, goroutines). Every library brings with it new semantics and new terminology to deal with. It's not like datascript is inherently obvious to folks.

The important bit from that line of thinking is that there's a cost to adopting it and the benefits have to outweigh that cost. We haven't talked much about what those benefits are, so I get where you're coming from - it may indeed look like we've "lost the plot." :) Most of our content is geared toward people who are already interested in what we're doing and want to follow along with the work. It's very much not a pitch at the moment, that will be coming in a couple of months. You can pick up on some of it from what we _have_ shown though:

\- Eve programs are naturally tiny (no tricks/golfing/epic one liners). The CLJS libs you mentioned all have TodoMVC implementations that are ~5x as large as Eve's (just 63 lines!).

\- There's no incidental ordering in the language, which means you're free to organize your program however you want. As a result, it enables truly literate programming.

\- Another result of a lack of ordering is that programs grow very organically through composition. Want to react to an event on a thing someone else created? Write a block that matches for it. Want to add some fake data into the system? No changes needed, add a block that adds some data. Want to visualize where all the active users are in your app? Write a block anywhere.

\- Eve programs aren't talking to a database, they _are_ the database. That means no plumbing, no impedance mismatch, and no extra infrastructure is needed. A practical example of this from one of my tweets[1]: I can take our todomvc add three @global tokens (changed from "all") and we now share todo lists. No server setup, no client->server transport, etc.

\- Eve's semantics were built for concurrency, asynchrony, and distribution. There are no promises, or thread synchronizations, or borrows.

\- Correctness can be defined globally through integrity constraints, allowing people to safely contribute to an application without worrying about checking every possible invariant locally. No more null checks and Joey can't check something in late at night that allows people to have a negative salary.

\- _Everything_ is data. The file system, http requests, the DOM... That means everything can be queried and everything can be reacted to. Want to be alerted when the machine you're on is running low on memory? Write a match against the machine's memory and commit an email when it dips below a certain threshold. Want to know how many open http requests there are? It's just a query away. With no indexing, no passing things around, no real effort at all, you can ask any question about your system you want.

\- Since everything is data, we can provide amazing tools. A very simple example here: [2].

Excitingly, the list continues on, we're just focusing on making Eve a lot more real before we tell people about it. It's up to us to prove and communicate what Eve brings to the table and we're taking that very seriously. My blog post about Light Table was never meant to be a big deal - I did it on a whim. Eve, on the other hand, is deliberate, well researched, and well grounded. As you suggest, it will take a lot to convince folks that there's a net gain to the switch and so we're collecting lots of evidence. Amusingly enough, in some ways we're actually returning to the original "plot" \- one of the demos I want to do in October is a recreation of the LT demo. We finally have a language with the semantics necessary to fulfill that vision. :)

[1]: [https://twitter.com/ibdknox/status/755450540104884224](https://twitter.com/ibdknox/status/755450540104884224) [2]: [https://twitter.com/ibdknox/status/760963855296016384](https://twitter.com/ibdknox/status/760963855296016384)

<comment><USER9> Thanks for the response.

> Out of curiosity, would you say the same thing about Clojure? ...

Fair enough. :)

What is the largest thing you've written in Eve? I've found that Clojure strikes an amazing balance between semantics that help you reason clearly about problems and the flexibility to do things that the language creators didn't imagine. I guess I just haven't seen that with Eve.

However! If you tell me to stay hopeful about Eve, I will. :)

</comment></comment></comment></comment></comment><comment><USER12> I was really hoping to see more happen in line with the interactive database querying tools and demos. Slicing and dicing data, some simple analytics, maybe a little about how to get the data in and out to/from other systems. Something to show that it's almost at a practically usable point - then I'd be on board.

That's the kind of thing I could use _now_ for my projects, but I get the idea that it's not the focus, with this new effort on the programming language. I was really a bit shocked and disappointed to see Flappy Bird to tell the truth, I felt that the project has maybe lost its focus.

After some reflection, it makes _some_ sense, because I guess it's showing how the database is used for state in the background, so it's showing the close integration that's possible. OK cool - now please back to the data exploration/querying/analytics focus!

</comment><comment><USER13> I tried to read the documentation, but I didn't quite get it.

What would I use Eve for?</comment>


ApexCharts – JavaScript Charts - <AUTHOR> https://apexcharts.com/ <comment><USER2> Very clean, definitely going to dig in to these. FYI: the github link in the footer is broken.</comment>


Ask HN: What's the quickest and cheapest way to de-risk my startup? - <AUTHOR> I have a little startup doing $10K+ MRR and I've done nothing on the legal front in terms of having a lawyer review the business or my site. I haven't written a terms & condition on my website.
I don't have any insurance.
I haven't incorporated, etc. I run it as a sole proprietor & have no employees.
So, I'm wondering what's the minimum effective dose to de-risk my business. I'm looking for an 80/20 solution to minimize my legal risk without dumping a bunch time & money into lawyers.
Any suggestions? <comment><USER2> Incorporate an LLC ($500 or less). Consider getting liability insurance, depending on what your site does. It will cost below $2k per year. Lightly adapt the ToS of Wordpress (which is OSSed) or similar for your purposes (free as in beer).

Then sleep easy.

I would advise involving a lawyer if you're in a particularly risky space. If you are, you probably know it.

</comment><comment><USER3> IAAL.

You don't say what your business does. That is critical. No one can answer your risk mitigation questions until you identify (most of) the risks. Ask yourself "What could possibly go wrong?" And then deal with each risk with a surgical strike. It's a combination of targeted and broad spectrum antibiotics you need here.

Incorporation. These cheap outfits that set up corporations or LLCs are fine but that's like me wanting to be a programmer and buying a laptop and saying "Right, what next?"

You have to be anal retentive in the maintenance steps with your corporation or LLC. If you are not rigorous in this step any half-alert lawyer will blow through it. What's the saying, "security is a process?"

That means never ever using the company's money to buy personal stuff. That means doing all of the paperwork annually to maintain the entity of your choice.

The least brain damage for you will be an LLC, if you live in the USA. Company formalities are minimal, it doesn't have any tax impact, it is easy to understand.

Don't optimize for tax. I am a tax lawyer. :-) There is not enough potential savings to make it worth your while. Optimize for income. Optimize for sale of your company. Hire a bookkeeper to keep the finances immaculate and an accountant to review the bookkeeper's work.

The opportunity cost for you doing this work is astronomical. If you have crap financial records you can't show an acquirer how well your product is doing. They don't buy your company. You lose all your money. You are pushing a shopping cart in the street while your grandchildren curse your name. OK slight hyperbole there. :-)

</comment><comment><USER4> Incorporate. That's by far the biggest bang for your buck you can do. Without that, you're personally liable for everything your startup does. If you get one disgruntled customer, they sue _you_ instead of your startup, and all your assets are at risk.

Incorporate.com offers standardized Delaware incorporation for $79, and (YC- backed) Clerky offers it for $99. I haven't used either of these personally, so YMMV may vary, but they seem legit.

</comment><comment><USER5> IANAL, but at minimum I was say to form either an LLC or S-Corp. Your costs will be at most a couple hundred dollars, but if something should happen down the road it can greatly reduce the risk of personal loss if a customer comes after you.

Not sure what your business is, or what you are doing for customers, but you may also want to get the lawyer to draw up a simple terms/conditions or contract (depending on your business). This lays the groundwork for preventing problems with customers. If something does happen and your case goes to court it is your word against theirs and without anything in writing their word is most likely going to be a lot more believable to the court system unfortunately.

Other than that, I would keep finances separate. If you form an LLC or incorporate open a business bank account and keep that money separate from your personal money. No cost in doing this and it will make things easier should the tax man come digging into your finances.

</comment><comment><USER6> You should probably incorporate into at least an LLC. Various other posts here have mentioned this but while they mentioned the "couple hundred dollars" of fees to start an LLC, also keep in mind that in some states you may pay a minimum yearly tax as an LLC. If you register your LLC in California (YMMV elsewhere) it costs $800/yr in taxes to maintain the LLC, even if you don't earn a dime from it.

</comment><comment><USER7> Best 80/20 solution is to form an LLC in your state through legalzoom.com. Actual incorporation (i.e., forming a corporation, usually in Delaware) is usually only necessary once you're ready for equity investment.

Learn more about LLCs here: [http://www.nolo.com/legal-encyclopedia/llc- basics-30163.html](http://www.nolo.com/legal-encyclopedia/llc- basics-30163.html)

</comment><comment><USER8> If your business has no profit, no revenue and no employees, and there is not much personal worth to protect - change nothing and focus on business.

When any of the above change - incorporate.

Most likely you would want to start with S-corporation or LLC.

IANAL.</comment>


Engineering Interviewing at Strava - <AUTHOR> https://medium.com/strava-engineering/engineering-interviewing-at-strava-4d395728eeb5 <comment><USER2> This article doesn't actually have much interesting content. It's pretty typical high-level boilerplate, to my eyes.

I'd be more interested in the actual content of the interviews. Instead of simply writing "three hours of technical interviews and one or more of other" it would have been helpful to see what the technical interviews might consist of.

For example, after reading this I have no idea if Strava's technical interviews are "implement X on the whiteboard", where X is something out of a CS textbook, or if there is any actual engineering content to them, or a mix of both.

<comment><USER3> Howdy, author here! When someone is getting ready to come onsite, we give the more detailed information about what the onsite will look like, as this varies team by team. Our iOS and Android interviews both do 90 minutes of pair programming. Roles that we're not hiring many people for typically do not have pair programming interviews.

But our focus in interviews isn't CS textbook experience. It's the types of things you actually need to know to do the job.</comment></comment>


In Support of Free Speech – Tobias Lütke, CEO  Shopify - <AUTHOR> https://medium.com/@tobi/in-support-of-free-speech-275d62670203#.jinabgqsp <comment><USER2> I totally agree with this position. I understand the arguments to cut of their funding but I don't think it is the right position. First of all, it won't work. They will just move somewhere else where they will continue to do what they had before. And secondly it isn't your place. This is what the law is for. If they are truly doing something wrong the justice system should deal with it.

</comment><comment><USER3> If no laws are being broken then let the free market police itself. If there are enough people that are "buying" what Breitbart is "selling" and if it's lawful then what's the problem?

</comment><comment><USER4> While I largely agree with the positioning and much of the reasoning, this statement is so false as to be farcical:

"All solutions necessarily have to come from the middle ground. "

Just no. All good solutions should be taking in the perspective of both sides, but the best solution will often be from a totally unanticipated direction that is far from the middle ground of the status quo.

</comment><comment><USER5> I have just checked Breitbart's store and didn't see any offensive product. Why should they ban them?

</comment><comment><USER6> I agree! +1</comment>