Zero Cost Abstractions - <AUTHOR> https://boats.gitlab.io/blog/post/zero-cost-abstractions/ <comment><USER2> An interesting post. I have two thoughts.

The first is in response to:

> I think to some extent Rust has tried to cheat this by making non-zero cost > abstractions actively unpleasant to write, making it feel like the zero cost > abstraction is better.

This idea is closely related to a comment by estebank just yesterday[1]. I disagree - I think Rust makes non-zero-cost abstractions _obvious_ to the author. If you want to do something in a way that's costly, the language surfaces that information. It puts it right in your face and makes you deal with it. That's a _good thing_. It makes for better code. If you want to use dynamic dispatch, you can't pretend you're not.

The second is to add a place where I think Rust has gotten zero cost abstractions right: zero-sized generic types. I use them extensively in embedded code to build things like states. I can use trait methods and associated consts in _really_ powerful ways to encode complicated relationships that constrain the operation of a peripheral at compile time, and it compiles down to a single register access. That's crazy powerful. Using C structs and type punning can do the same thing, but without the safety. Using C++'s classes can give me some type safety, but at the cost of real method call overhead. I get giddy every time I think about writing something like

        struct Adc<PIN: AdcPin, MODE: AdcMode>();

        let adc = Adc(adc_pin, AdcModes::8Bit);

and the compiler will let me know if my `adc_pin` isn't the right type.

[1] [https://news.ycombinator.com/item?id=19920945](https://news.ycombinator.com/item?id=19920945)

<comment><USER3> Why would a C++ version involve method call overhead?

Wouldn't C++ actually be more straightforward with its value-typed template parameters?

<comment><USER2> With C++, wouldn't I need to either use a virtual base class with a typed template parameter (to emulate interfaces), or need to use duck-typed parameter and lose type safety?

<comment><USER4> Which of the two template arguments are you talking about? The enum-typed template argument will lead to a optimized specialization of the template. C++ does, however, have an unfortunate problem with restricting type parameters to types with certain properties/guarantees in ways that won't make the compiler explode in obtuse error messages.

<comment><USER5> static_assert, enable_if or just plain not providing default implementation and only specializations, as everything in C++ error messages is something you can customize to high extent...

</comment></comment></comment></comment></comment><comment><USER6> There is one major problem with -- or, rather, cost to -- zero-cost abstractions: they almost always introduce accidental complexity into the programming language originating in the technical inner workings of the compiler and how it generates code (we can say they do a bad job abstracting the compiler), and more than that, they almost always make this accidental complexity viral.

There is a theoretical reason for that. The optimal performance offered by those constructs is almost always a form of specialization, AKA partial evaluation: something that is known statically by the programmer to be true is communicated to the compiler so that it can exploit that knowledge to generate optimal machine code. But that static knowledge percolates through the call stack, especially if the compiler wants to verify — usually through some form of type-checking — that the assertion about that knowledge is, indeed, true. If it is not verified, the compiler can generate incorrect code.

Here is an example from C++ (a contrived one):

Suppose we want to write a subroutine that computes a value based on two arguments:

        enum kind { left, right };

        int foo(kind k, int x) { return k == left ? do_left(x) : do_right(x); }

And here are some use-sites:

        int bar(kind k) { return foo(k, random_int()); }
        int baz() { return foo(left, random_int()); }
        int qux() { return foo(random_kind(), random_int()); }

The branch on the kind in foo will represent some runtime cost that we deem to be too expensive. To make that "zero cost", we require the kind to be known statically (and we assume that, indeed, this will be known statically in many callsites). In this contrived example, the compiler will likely inline foo into the caller and eliminate the branch when the caller is baz, and maybe in bar, too, if it is inlined into its caller, but let's assume the case is more complicated, or we don't trust the compiler, or that foo is in a shared library, or that foo is a virtual method, so we specialize with a "zero-cost abstraction":

        template<kind k> foo(int x) { return k == left ? left(x) : right(x); }

This would immediately require us to change _all_ callsites. In the case of baz we will call foo<left>, in qux we will need to introduce the runtime branch, and in bar, we will need to propagate the zero-cost abstraction up the stack by changing the signature to template<kind k> bar(), which will employ the type system to enforce the zero-cosiness.

You see this pattern appear everywhere with these zero cost abstractions (e.g. async/await, although in that case it's not strictly necessary; after all, all subroutines are compiled to state machines, as that is essential to the operation of the callstack — otherwise returning to a caller would not be possible, but this requires the compiler to know exactly how the callstack is implemented on a particular platform, and that increases implementation costs).

So a technical decision related to machine-code optimization now becomes part of the code, and in a very intrusive manner, even though the abstraction — the algorithm in foo — has not changed. This is the very definition of accidental complexity. Doing that change at all use sites, all to support a local change, in a large codebase is esepcially painful; it's impossible when foo, or bar, is part of a public API, as it's a breaking change -- all due to some local optimization. Even APIs become infected with accidental complexity, all thanks to zero-cost abstractions!

What is the alternative? JIT compilation! But it has its own tradeoffs... A JIT can perform much more aggressive specialization for several of reasons: 1. it can specialize speculatively and deoptimize if it was wrong; 2. it can specialize across shared-library calls, as shared libraries are compiled only to the intermediate representation, prior to JITting, and 3. it relies on a size-limited dynamic code-cache, which prevents the code-size explosion we'd get if we tried to specialize aggressively AOT; when the code cache fills, it can decide to deoptimize low-priority routines. The speculative optimizations performed by a JIT address the theoretical issue with specialization: a JIT can perform a specialization even if it cannot decisively prove that the information is, indeed, known statically (this is automatic partial evaluation).

A JIT will, therefore, automatically specialize on a per-use-site basis; where possible, it will elide the branch; if not, it will do it. It will even speculate: if at one use site (after inlining) it has so far only encountered `left` it will elide the branch, and will deoptimize if later proven wrong (it may need to introduce a guard, which, in this contrived example will negate the cost of the branch, but in more complex cases it would be a win; also there are ways to introduce cost-free guards -- e.g. by introducing reads from special addresses that will cause segmentation faults if the guard trips, a fault which is caught; OpenJDK's HotSpot does this for some kinds of guards).

For this reason, JITs also solve the trait problem on a per-use-site basis. A callsite that in practice only ever encounters a particular implementation — a monomorphic callsite — would become cost-free (by devirtualization and inlining), and those that don't — megamorphic callsites — won't.

So a JIT can give is the same "cost-freedom" without changing the abstraction and introducing accidental complexity. It, therefore, allows for more general abstractions that _hide_ , rather than expose, accidental complexity. JITs have many other benefits, such as allowing runtime debugging/tracing "at full speed" but those are for a separate discussion.

Of course, a JIT comes with its own costs. For one, those automatic optimizations, while more effective than those possible with AOT compilation, are not deterministic — we cannot be sure that the JIT would actually perform them. It adds a warmup time, which can be significant for short-lived programs. It adds RAM overhead by making the runtime more complicated. Finally, it consumes more energy.

There's a similar tradeoff for tracing GC vs. precise monitoring of ownership and lifetime (Rust uses reference-counting GC, which is generally less effective than tracing, in cases where ownership and lifetime are not statically determined), but this comment is already too long.

All of these make JITs less suitable for domains that require absolute control and better determinism (you won't get perfect determinism with Rust on most platforms due to kernel/CPU effects, and not if you rely on its refcounting GC, which is, indeed _more_ deterministic than tracing GC, but not entirely), or are designed to run in RAM- and/or energy-constrained environments — the precise domains that Rust targets. But in all other domains, I think that cost-free abstractions are a pretty big disadvantage compared to a good JIT -- maybe not _every_ cost-free abstraction (some tracking of ownership/lifetime can be helpful even when there is a good tracing GC), but certainly the philosophy of always striving for them. A JIT replaces the zero-cost abstraction philosophy, with a zero-cost _use_ philosophy -- where the _use_ of a very general abstraction can be made cost-free, it (usually) will be (or close to it); when it isn't -- it won't, but the programmer doesn't need to select a different abstraction for some technical, "accidental", reason. That JITs so efficiently compile a much wider variety of languages than AOT compilers can also demonstrate how well they abstract the compiler (or, rather, the languages that employ them do).

So we have two radically different philosohies, both are very well suited for their respective problem domain, and neither is generally superior to the other. Moreover, it's _usually_ easy to tell to which of these domains an application belongs. That's why I like both C++/Rust _and_ Java.

<comment><USER7> Or just use something like ThinLTO. You don't need a JIT just to get cross- module inlining, which is all you're really talking about here. There's no actual "specialization" in play, just basic inlining + dead branch elimination. Trivial to do this statically at build time instead. So much so this is even commonly done in JIT'd languages like Java (Proguard & R8 say hello)

Most JITs also have the downside of they need to optimize for compilation performance, and as such typically do not do as thorough a job optimizing as something like offline LLVM. Or you end up with fourth-tier JITs like webkit's FTL. And now instead of just needing to wait for the JIT to think your function is interesting you now need to wait for a second and finally third JIT pass.

JITs really primarily just shine in the rapid iteration cycle. Conceivably what you really want is a language where debug builds are JIT and release builds are full AOT with LTO. Not entirely unlike Dart's behavior in Flutter. Or even how Java behaves on Android to an extent. There doesn't seem to be any particularly significant reason why this pairing isn't more broadly applicable and used.

There's also no real reason you can't have zero-cost abstractions _AND_ a JIT if you want. Hell, in theory this is what you get with C++ in a webasm environment. This are not exactly opposing technologies.

<comment><USER6> > get cross-module inlining, which is all you're really talking about here.

Not at all.

> There's no actual "specialization" in play, just basic inlining + dead > branch elimination.

Devirtualization + inlining + dead branch elimination _is_ an instance of specialization, and an extremely effective one at that, but other forms of specializations apply.

> Trivial to do this statically at build time instead.

No. Some things are undecidable and/or would lead to code explosion. E.g., it's often hard to statically prove that a subroutine that takes an int would always receive the number 2, and specializing it for all ints would cause code explosion (again, contrived example but with real-world counterparts).

> There's also no real reason you can't have zero-cost abstractions AND a JIT > if you want. Hell, in theory this is what you get with C++ in a webasm > environment. This are not exactly opposing technologies.

Of course. But I was talking about two very different philosophies that greatly affect language design.

<comment><USER7> > Not at all.

For your example? Yes, it was.

> Devirtualization + inlining + dead branch elimination is an instance of > specialization

Your example did not involve any devirtualization.

> No. Some things are undecidable and/or would lead to code explosion. E.g., > it's often hard to statically prove that a subroutine that takes an int > would always receive the number 2, and specializing it for all ints would > cause code explosion (again, contrived example but with real-world > counterparts).

Again, your example did not have any such issues.

And if it was hard to statically prove a subroutine that takes an int always receives 2 then guess what? A JIT wouldn't do it, either. They don't actually specialize that much for runtime information because gathering that information would destroy performance. Devirtualization? Sure, limited in scope, and huge payoffs to be had for doing it. All arguments analyzed & binned? Good god no. That'd be ludicrous in resource usage required, and the payoffs would be incredibly hard to quantify in any meaningful way.

Take your example - all it would do is eliminate a single branch. If it was so common to take a single avenue that it could be eliminated, then pretty much every branch predictor would do it anyway. So... why specialize it?

<comment><USER8> V8 uses runtime type/value information to specialize methods in some cases[1]. I find it hard to believe that HotSpot doesn't either.

Obviously complex objects are impossible to handle, but branching on an integer that's always the same value isn't. Same for constant folding, if an argument is determined to be constant at runtime then that's going to affect the choices the JIT makes.

1\. [https://ponyfoo.com/articles/an-introduction-to- speculative-...](https://ponyfoo.com/articles/an-introduction-to-speculative- optimization-in-v8)

<comment><USER7> That's specializing on type, not on a given specific value. Being JS the value influences the type, but it's only looking at a coarse binning (int vs. double vs. string etc..) not specializing for a single specific value. A form of de- virtualization if you will.

Hotspot wouldn't even need to bother with that most of the time since it's primarily running statically typed languages for which that doesn't apply in the first place.

</comment></comment></comment></comment></comment></comment><comment><USER9> There are some fundamental optimizations we don't even think about any more. E.g. the first class I wrote in C++ was a simple container for a byte, with a constructor, a getter and a conversion to int. Then in main() I declared one locally, constructed with 'true'. Then I returned that object as the return code.

Imagine my surprise when the generated code was simply

mov AX, 0xFF

ret

Three or four bytes of code! So some abstractions, encapsulation for instance, provide the user with guarantees but can cost absolutely nothing.

</comment><comment><USER10> I really enjoyed the zero cost abstractions in Standard ML achieved by the whole-program optimizing MLton compiler (and I have a t-shirt to prove it). It's amazing how one can define clean, abstract, type-safe module hierarchies that still boil down to very, very efficient machine code that's just inches away from hand-written C code in terms of raw performance.

The zero runtime cost, of course, was paid in compilation time. With some tricks, it wasn't a big problem in practice, though.

<comment><USER11> Pardon my ignorance, but don't that family of languages suffer from the overhead of boxing?

<comment><USER12> They can unbox sometimes, especially compiling with MLton or stalin. There's research papers on specifying boxedness explicitly still in the MLish framework but no real implementations afaik

</comment></comment></comment><comment><USER13> Along these lines is an intermediate language called Morte[0], developed by Gabriel Gonzalez, well known in the Haskell community. It seems to still be getting some love.

The basic idea is to implement a strongly normalizing calculus of constructions which languages can compile down to. That way, equivalent functions provably generate equivalent code. Here's [1] a blog from 2014 that goes into more detail on motivation, examples, and the like.

There's a proof-of-concept frontend called Annah[2]. I'm unaware of any backends though.

[0]:[https://github.com/Gabriel439/Haskell-Morte- Library](https://github.com/Gabriel439/Haskell-Morte-Library)

[1]:[http://www.haskellforall.com/2014/09/morte-intermediate- lang...](http://www.haskellforall.com/2014/09/morte-intermediate-language-for- super.html)

[2]:[https://github.com/Gabriel439/Haskell-Annah- Library](https://github.com/Gabriel439/Haskell-Annah-Library)

</comment><comment><USER14> "Zero cost" is a pet peeve of mine. While I concede that the concept is useful, there is always a cost _somewhere_.

A very concrete example of this was a C++ unit test suite where templates were used to generate several combinations of tasks/backends for verification. At one point our cloud builders ran out of memory. To avoid upgrading the instances at a €€€ cost from all the abstraction, I did some manual type erasure.

So, zero cost typically only concerns run time characteristics. Even then there are elusive pitfalls, like generated code size.

<comment><USER15> AFAIK, no one has even meant "zero cost" to mean "zero compile-time cost".

<comment><USER16> And yet it is called zero cost. Not "zero cost along one particular dimension that we won't name and only sometimes matters."

<comment><AUTHOR> We took it from C++ which has a long history with the term; take it up with Bjarne.

<comment><USER17> Sure he could. And he could take it up with anyone who copies it on a greenfields project too, right? It's a crap name. So what, computing is full of them, assembly language is full of them, C is full of them, C++ is full of them. Sometimes we make a break and don't use one and invent something better. Sometimes...

mov [memory], %register memove(dst, src, size); dst = std::move(src);

eg RAII, SFINAE these are not great names to be copied, I'd be surprised if rust did.

</comment></comment></comment></comment></comment><comment><USER18> As I understand it, examples of "zero cost abstractions" would be std::string or std::map<X,Y> in C++. Reimplementing those in plain C is not a great idea, because the result will be very bug-prone, and will not be (significantly) faster.

The problem with these "zero cost abstractions" is that we're measuring the wrong cost.

The key to efficiency is optimizing _what_ is done, not optimizing each little line of code. std::string is a terrible idea with regards to efficiency. If it works for you chances are you should use Python instead. For anything complex, std::string is slow and has a huge memory footprint (each string has its own buffer, separately allocated from the heap). It also leads to a heavy increase in compilation times. Anecdotally, it can even be painful to depend on it when the standard library is upgraded. If you have anything beyond a few megabytes worth of text data, std::string is about the worst possible technical solution.

<comment><USER19> zero-cost abstractions are abstractions where the hand-written code wouldn't be any better than the abstraction.

An example is how Option<Box<T>> optimises down to a single pointer in Rust — the compiler uses its knowledge of how Box<T> is non-nullable, and coopts the null value to represent the None value for the Option.

<comment><USER20> Is this optimization required by the language semantics or some standard (vs. being only a description of mainline rustc's implemented optimizations)?

<comment><AUTHOR> It's a defined part of the language semantics.

<comment><USER21> Is there actually a formal language semantics definition anywhere? I thought all we had was stuff like [https://doc.rust- lang.org/reference/index.html](https://doc.rust-lang.org/reference/index.html) which is explicitly listed as "not a formal spec".

<comment><AUTHOR> Things have different degrees of guarantees. This is something we've explicitly said is guaranteed.

<comment><USER22> Where are things like this said/defined/collated?

<comment><AUTHOR> We are generally at a point where if it's documented, it's guaranteed. This feature is really easy to describe, and so we have a high degree of confidence that when we say "this behavior is defined", we won't run into an edge case where we'd have to break it.

So, in this case, it's a documented part of Option.

I realize this answer isn't _fantastic_ , but it's where we're at now. It's why we're working on the reference this year!

<comment><USER22> >we're working on the reference this year!

I didn't know this, it's good to hear. Thanks!

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER23> Lisp family of languages have macros which can provide zero cost abstractions for you. For example, the loop facility is really just a macro, and so are the racket for loops.

Not only that: in scheme there is usually a source->source optimisation phase which means you can easily inspect what that abstraction does. That way it is pretty simple to know that an optimisation really is zero cost.

My favourite examples are, as already mentioned, racket's for loops and the various scheme pattern matches out there. The difference between lisp and rust is that these can be added to your language without having to change the compiler and they can be built as a library by anyone.

</comment><comment><USER24> I very much like to see this feature implemented at (Compiler + JIT) level in higher level dynamic languages like Clojure, Erlang, ES8 JS, Python etc.

</comment><comment><USER25> There is a typo under the 'optimal performance' section. "A zero cost _abstractoin_ ought..."

<comment><USER26> Also at the end it says "not non-zero cost". Assuming the double-negative is a mistake, they should delete either the "not" or the "non-".

</comment></comment><comment><USER27> Nice post, but some code examples would have helped to clarify even further the concepts, especially for newbies

</comment><comment><USER28> Good luck with the trait object. I doubt you're going to significantly improve on what the Haskell community has done in 20 years. If you do manage it though, kudos in advance.

<comment><USER29> Noob here: why is the trait object hard to optimize in principle?

<comment><USER30> (disclosure: i know Haskell but not Rust, and haven't actually implemented anything like this in a compiler. please let me know if i'm wrong!)

best guesses:

\- dynamic dispatch usually involves carrying around¹ some function pointers (to your type's implementations of the trait methods). this means that when calling `x.foo()` on a trait object `x` of some trait `Foo`, the actual function/method being called isn't known until runtime, so the compiler can't optimize the call through things like inlining (which require knowing what's being called). also AFAIK jumping to some unknown function pointer is relatively slow on the CPU level

\- since the compiler doesn't know the actual type (and hence layout) of your object, it has to be passed via reference, so there's some indirection overhead and it's probably impossible to e.g. optimize away intermediate values or be smart about the way they're kept in registers.

the problem is that the nature of trait objects (i.e. "i know nothing about this value except that it implements the `Foo` trait) kind of seems to require these things :(

¹ via a vtable or "dictionary passing"

</comment></comment></comment><comment><USER31> The perfect target candidate for zero cost abstractions is a data base api.

With databases as the bottleneck of web development it is not optimal to use such high level apis like SQL to optimize everything. We resort to ANALYZE and strange sql hacks to trick the query engine into performing the right algorithms when the api should explicitly let us choose to use or tweak both zero cost abstractions and/or a query planners.

<comment><USER32> I love SQL, but I strongly agree with this. It would be great to have a platform-specific low-level API for performance-critical queries. (Much like "unsafe" code in a managed programming language.)

<comment><USER33> I think the best analogy would be SQL is to OpenGL what this API would be to Vulkan.

Ability to define the query procedurally or atleast semi-so vs the declarative approach of SQL would allow direct optimisation of very performance critical queries.

<comment><USER34> I disagree. The amount of optimization that a query planner does is vastly more than a web application developer would care for.

We have people who can't be bothered to close database transactions (see that Uber report). I wouldn't trust then to choose the optimal join strategy in a complex query.

<comment><USER35> What Uber report?

<comment><USER34> [https://eng.uber.com/mysql-migration/](https://eng.uber.com/mysql-migration/)

</comment></comment></comment></comment></comment></comment><comment><USER36> So, it's zero cost from the program performance standpoint. User MUST pay something to have it.

It's not zero-cost from user standpoint.

<comment><USER37> How is the user paying for this? Generally the cost ends up being longer compiles and more development time.

<comment><USER38> The user is the programmer in this context, the user of the programming language, not the end user of the program.</comment></comment></comment>


Does it matter what college you go for undergrad? - <AUTHOR>

<comment><USER2> I would try and find a college that has at least some entrepreneurial initiative. For example, at the Univ of Illinois, they have the Academy for Entrepreneurial Leadership and the Technology Entrepreneur Center, plus one of the best ACM (Association for Computing Machinery) chapters around. We had Max Levchin and Jawed Karim speak at our last conference, plus companies like Google, Amazon, EA, Microsoft, etc. are showing up.

The only reason I'm really here is to find some CS students to help me startup. But it wouldn't happen without my connection to the school's CS groups.

In the end, I doubt it matters one way or another where you go. As someone mentioned, many successful founders didn't go to ivy league schools. Jobs dropped out after 6 months at Reed. You'll decide how far you go.

</comment><comment><AUTHOR> Hey guys,

I am 17 and I posted this because I received my admissions letters this week. I got full rides to every state college I applied but I got wait listed at Stanford, MIT, Harvard, and Caltech. I really don't know how to think of this. Can I still start a successful startup? Can I still be more successful than an MIT undergrad? Is there something about these colleges that makes students there better or is it completely dependent on the student's personality, work ethics, etc.. to be successful?

Sorry if the question seems out of whack. I am probably overwhelmed right now by the admissions letters.

<comment><USER3> It won't change your ability to start a startup. It might change how strong a background in CS you get... but again, that depends on what kind of learner you are.

What states?

<comment><AUTHOR> I got into University of Maryland, Purdue, Georgia Tech, and University of Texas, Austin.

<comment><USER4> I have high school friends who graduated from three of these schools. They are all smart people, did well in college, and are doing well after graduating. But none of them are starting a company. The idea doesn't seem to intrigue them either.

If you have the entrepreneurial spirit in you, constantly remind yourself that you have it, regardless of where you are and what people tell you. If you have it as a highschooler, great. The eye for opportunity is a great gift, and colleges do not know how to measure this, nor can they teach you how to acquire it.

I don't think you should worry if a school will turn you into a successful entrepreneur. The greater concern should be people to bounce ideas off of, and potentially work with. Talent is everywhere; train yourself to spot it. That is an asset second to none.

I must agree with pg though. Vibe is very important. It's a lot more enjoyable to build stuff when everybody around you is talking about building stuff too. Where I went to school, people spend more time talking about philosophy :)

</comment></comment></comment></comment><comment><USER5> It doesn't matter for a startup. But it does matter if you want a cushy job or want to get into a top professional school.

</comment><comment><USER6> What is the context of the question? Does it matter for what?

<comment><AUTHOR> I guess I should have added "for a successful startup." Also, if you can tell me how it matters for the comp. science field in general, I would appreciate it.</comment></comment>


NYT: The Decision to Publish Diplomatic Documents (obtained from wikileaks) - <AUTHOR> http://www.nytimes.com/2010/11/29/world/29editornote.html

<comment><USER2> Looks like the NYT are going to dilute it, you can get it all here: <http://www.guardian.co.uk/world/the-us-embassy-cables>

<comment><USER3> This seems like a flawed idea--if anyone publishes the uncensored cables then you can diff it and find the redacting and they have exposed even more information about information priorities.

Keep voting this link up, as important to read as the release itself.

</comment></comment><comment><USER4> I get the idea to publish war documents....it helps shed light on the war, might make it end sooner.

I don't necessarily agree with it, but I understand it.

I _don't_ get the publishing of diplomatic documents. I've not had time to read though the entire contents yet, but this just seems like it might CAUSE war, not end it.

<comment><AUTHOR> The chances of this publication causing a war are close to zero

I think there is a public interest in knowing how many government decisions are made, a public interest in knowing that (as per a source of the American embassy) the Chinese politburo was behind the attack on Google etc.

<comment><USER5> The most potentially war-causing bits are the sensitive bits about Iran.

Having various other countries in the Middle East on the record as saying nasty things about Iran might severely damage intra-middle-east relations, perhaps making war less avoidable in the future. (It _might_ , of course, have completely the opposite effect, but it's still analogous to firing bullets into a crowd at random and hoping they only hit bad guys.)

<comment><USER6> Do you really believe that the Iranian government didn't already know what various other middle eastern governments thought of it? I mean, is your assumption that American government officials, with their outstanding history of sophisticated and successful intelligence gathering in the middle east (read: failure without end) have been more successful than the Iranian regime at local intelligence gathering? That seems...fanciful, and perhaps indicative of western arrogance.

More to the point, this whole notion that the current Iranian regime would start a war for no other reason than because some other government said mean things about it is...not terribly well supported by evidence.

<comment><USER5> _Do you really believe that the Iranian government didn't already know what various other middle eastern governments thought of it?_

Ah, but diplomacy is so often less about who knows what and so often about who has plausible deniability.

Iran knows that the Saudis hate them. And the Saudis know that the Iranians know that they hate them and so forth. But to have it publicly acknowledged and on the record that they hate each other makes things more difficult if they ever need to cooperate.

For instance, now that the Saudis are officially on the record as saying the US should bomb Iran, we can rule out the possibility of using the Saudis as a go-between or an "honest broker" for some kind of negotiated settlement with the Iranians. Not that it was necessarily going to happen, but the possibility is pretty much ruled out due to the embarrassment it would cause all round.

It's not that Iran is going to attack Saudi Arabia because the King said mean things; it's just that the Saudis and the Iranians can no longer pretend publicly that they don't hate each other.

That's just one example, there's any number of other ways that bringing unpleasant truths to the surface can spoil already-weak relationships, as anyone who has ever been in a weak relationship can tell you.

<comment><USER6> _the Saudis and the Iranians can no longer pretend publicly that they don't hate each other._

Why not? Everyone with a brain already knew that the Saudi regime hate the Iranian regime. The cables do nothing to change that. And really, the fact is, Saudi Arabia's King's opinions on Iran have zero bearing on whether the US invades Iran.

I don't see what exactly distinguishes your claims about the probability of war increasing due to this "revelation" from magical thinking.

 _That's just one example, there's any number of other ways that bringing unpleasant truths to the surface can spoil already-weak relationships, as anyone who has ever been in a weak relationship can tell you._

I don't think that one's love life or startup business experience really equips the average person to correctly understand international diplomacy. You say this is just one example: OK, please list some more. Or flesh out this one to the point where it actually makes sense.

</comment></comment></comment></comment></comment></comment><comment><USER7> What I want to know is what US news organizations turned down the offer to publish the information on ethical grounds. My guess: none.

I wonder how the journalists, editors and bosses of the NY Times would like it if a dump of their email server was released on The Pirate Bay. None of their emails are "noforn" or "secret".

<comment><USER8> The New York Times is not part of the government.

<comment><USER7> "To "attack a straw man" is to create the illusion of having refuted a proposition by substituting it with a superficially similar yet unequivalent proposition (the "straw man"), and refuting it, without ever having actually refuted the original position."

<http://en.wikipedia.org/wiki/Strawman>

<comment><USER8> I'm merely pointing out that you can't treat leaking of documents from companies and the government the same way. That's not a straw man, you really seem to claim that government and company leaks should be judged in the same way.

I'm obviously very sure that you are aware that the New York Times is not part of the US government, my point was not that you do not know that, my point was that because of that fact you can't really compare the two.</comment></comment></comment></comment>


The truth about oxygen masks on planes - <AUTHOR> https://www.telegraph.co.uk/travel/travel-truths/truth-about-oxygen-masks-on-planes/ <comment><USER2> It's mostly a design failure once again, not a "stupid user" failure.

Those masks _look_ like they should go over your mouth and like they would be _uncomfortable_ to put over both of your mouth and nose. If it had a longer shape as opposed to a round bowl shape, I bet most people would use it correctly, without even ever having to listen to the flight attendants.

EDIT: Apparently almost everyone said the same thing I did replying to that guy's tweet. It just seems so obvious to me at first glance that the design is wrong. You can't "think" because of the high-stress situation and lack of oxygen. So the design should minimize the amount of thinking needed.

People put it on their chain because the design of the mask most resembles the form of the chin not that of the mouth+nose.</comment>


Australia gets 'deluge' of US secret data, prompting a new data facility - <AUTHOR> http://www.theage.com.au/it-pro/security-it/australia-gets-deluge-of-us-secret-data-prompting-a-new-data-facility-20130612-2o4kf.html

<comment><USER2> _US signals intelligence is also described as "absolutely critical" to Australia's diplomatic campaign to win a seat on the United Nations Security Council.

"Without intelligence support, overwhelmingly provided by US capabilities, we would not have won the seat," one Department of Foreign Affairs and Trade officer recently said._

Spying on other countries is something Australians want our government to do when it can't be avoided, not just because they can and Stalin did worse. Doing it to win an election is wrong. Here's another reason to make these activities as transparent as possible: it's obvious to everyone in Australia, except for Kevin Rudd and a few DSD agents, that we have always gained more by not doing things like this than we could possibly gain from some diplomat sitting on a committee in New York.

</comment><comment><USER3> I don't get it... why does Australia need to store a copy of US secret data? Isn't this why the Defence Industry invented the internet?

<comment><USER4> NSA isn't allowed to spy on its own citizens.

Australia is allowed to spy on US citizens.

US and Australia pool their collected intelligence. The US gives a list of names to Australia and asks if Australia has any information on those names.

This is pretty much how ECHELON worked, with UK, US, Australia, Canada and New Zealand all cooperating.

<comment><USER5> Wow, I'd never thought of that way, We'll spy on your people if you spy ours...

</comment></comment></comment><comment><USER6> Great, now we get access to the worlds corporate secrets too. I wonder which companies will be the beneficiaries..</comment>


Escaping the Chrome Sandbox with RIDL - <AUTHOR> https://googleprojectzero.blogspot.com/2020/02/escaping-chrome-sandbox-with-ridl.html <comment><USER2> I wonder why their Mojo system doesn't use mach ports on darwin platforms? You can pass port rights along to another process but they aren't forgeable. Unless the renderer process itself has a right to send messages to the network process it simply can't, no matter what it knows.

A process can also disinherit its own bootstrap port, preventing it from using most services except for port rights it already holds.

<comment><USER3> Using kernel-provided capabilities (like Mach ports or Unix file descriptors) directly might have too much overhead if the design uses a lot of them. But even if that's true, it should be possible to implement unforgeable capabilities in userland using a trusted broker process.

It's a classic design mistake to represent IPC access rights using secrets instead of capabilities. Secrets _seem_ more convenient to work with: they're just data, which can be encoded and transformed like any other data, whereas capabilities need to be kept separate throughout multiple levels of abstraction, from your IPC wrapper functions down to the low-level message sending primitives.

And secrets are _theoretically_ secure, if you do everything right. After all, in the related domain of network services, there is no trusted broker to represent capabilities, so you have to use secrets in various forms, like MAC- ed and encrypted cookies, or TLS certificates. And it mostly works out in practice.

But secrets are risky. Even with network services, you have the fundamental downside: the security model is compromised if an attacker can merely _read_ data they shouldn't, like the MAC key or the TLS private key, rather than having to _modify_ data. That greatly increases the impact of vulnerabilities that only allow reads – especially if, like in this exploit, you can only read a small amount of random data, rather than whatever data you want.

When it comes to IPC, using secrets is even riskier for multiple reasons. First, an attacker is very 'close' to the target, running on a different process in the same machine, which means they're in a much better position to try to leak memory using side-channel attacks. Although the full power of hardware side-channel attacks has only recently been exposed, weaker side- channel attacks have been a known threat for a long time. There are also pure- software timing side channels, i.e. where the software does a different amount of work depending on a condition, which would let an attacker guess the value of the condition even if the CPU itself executed instructions in constant time. Second, IPC communications protocols tend to be lower-level, e.g. using shared memory, and the trusted side is often written in an unsafe language like (as here) C++. In contrast, network protocols and servers can typically afford to be somewhat higher-level because the network itself introduces a bunch of overhead anyway (something that also makes them more resistant to. But low-level means greater risk, especially for low-level vulnerability categories like memory disclosure (or, for that matter, memory corruption). Not that network services can't be vulnerable to memory disclosure – consider Heartbleed or Cloudbleed – but it's more likely with IPC.

Third, without getting too far into the weeds, the objectives are often somewhat different. With a network service, leaking random data is often a pretty good attack by itself, especially if the service directly handles data for many users. With IPC, the attacker usually needs to use a separate exploit to even get in position to interact with the IPC interface, so 'only' being able to read data is sort of a waste; you really want to escalate privileges. This is only a rule of thumb and isn't always true – sometimes network services are only accessible after compromising a different network service; sometimes IPC is intentionally exposed to untrusted code. But it's a factor.

The most important difference, though, is what I already said: with IPC you don't _have_ to use secrets. They're risky in both network services and IPC, but with IPC you can use a trusted capability broker instead, and so you should. Capabilities are a bit less convenient, not being pure data. but precisely for that reason they're harder to screw up, harder to leak by accident.

</comment></comment><comment><AUTHOR> This is an excellent writeup, even by Project Zero standards.

<comment><USER4> Thanks for sharing! Your posts are awesome as usual!

</comment></comment><comment><USER5> Another issue caused by hyperthreading. It's starting to look more and more like the OpenBSD guys made the right choice by turning it off. At this point, I think the only other option is for OS guys to implement some kind of security-aware scheduler, where threads can request secure execution on a dedicated processor. Though I suppose it might make more sense to execute on isolated processors by default and have threads explicitly permit unsecured execution for non-critical stuff.

<comment><USER6> Indeed,, the multi-process model is the only way to go for security conscious code, and also as mechanism for sandboxing plugins, not only threads.

</comment></comment><comment><USER7> > At the time of writing, both Apple and Microsoft are actively working on a > fix to prevent this attack in collaboration with the Chrome security team.

Why is Apple a contributor to Chromium? I've thought they still use Webkit? Or maybe the bug exists in Webkit too?

<comment><USER8> I'd assume they're working at the OS level since part of the exploit involves the hardware (hyperthreading)...

<comment><USER9> > To protect against attacks on affected CPUs make sure your microcode is up > to date and disable hyper-threading (HT).

I wonder what they can honestly even do beyond disabling hyper-threading by default…

<comment><USER10> > However, the browser process is also using URLLoaderFactories for different > purposes and those have additional privileges. Besides ignoring the same- > origin policy, they are also allowed to upload local files. Thus, if we can > leak one of their port names we can use it to upload /etc/passwd to

My take on it. Chrome has just too many things it uses internally that's exploitable if one finds a a way to trick the sandbox.

The entire point of sandbox seem to be lost when so many stuff happens inside it.

Kick unneeded stuff out from rendering processes, reverting to the original design for them. "The renderer" in their design does way to many things other than just rendering.

Again, WASM will be a bane no matter how you secure it. JIT compilation of unsecure code is a bane. ASMJS has been a source of multiple exploits, it's poorly maintained, it must be axed.

<comment><USER6> WebAssembly advocates keep hand waving the fact that internal memory state inside modules is open to data corruption, because bounds checking only happen at the edges of linear memory segments.

Something like Heartbleed is not preventable on current WebAssembly sandbox model.

So I just keep expecting for the first wave of Flash like exploits to eventually come in, when WebAssembly starts being a valuable target.

</comment></comment></comment></comment></comment><comment><USER9> An interesting fuzzer called fuzzilli two links in: [https://github.com/googleprojectzero/fuzzilli](https://github.com/googleprojectzero/fuzzilli)

<comment><USER5> Swift is an interesting language choice for something like this. As far as I am aware, support is non-existent outside of Ubuntu and OSX, so it seems limiting compared to, say, C.

<comment><USER11> > As far as I am aware, support is non-existent outside of Ubuntu and OSX, so > it seems limiting compared to, say, C.

If it works on Linux, why would it need to work anywhere else?

<comment><USER6> I don't know, maybe just maybe, because not everyone uses GNU/Linux?

</comment></comment></comment></comment><comment><USER8> Any reason P0 doesn't seem to direct some time and energy towards finding zero days in Firefox? Are they mandated to only investigate codebases of interest to Google?

<comment><USER12> (Former Firefox Security Engineer)

I suspect it's because Firefox exploits have looked the same for the last several years -- there has not been a lot of novelty required to implement an exploit, given an arbitrary read/write primitive.

P0 does report vulnerabilities to Firefox though, and they obviously get fixed, they're just not particularly interesting to exploit.

<comment><USER9> > I suspect it's because Firefox exploits have looked the same for the last > several years -- there has not been a lot of novelty required to implement > an exploit, given an arbitrary read/write primitive.

Surely other browsers do not differ from this significantly?

<comment><USER13> An arbitrary write primitive in the chrome render process hasn't been game over for quite some time.

<comment><USER9> I mean, is it on Firefox?

<comment><USER13> Until a year ago(?), yes.

</comment></comment></comment></comment></comment></comment><comment><USER14> I love the work project zero does but I wish google would do some basic security things would android like streamlining the patch system to get to phones and providing more support for their older phones with security updates and more stringent security requirements for android. I feel like project zero is really good PR for them but they could really do more for the security of their apps and phones :/</comment>


Introducing Qt 5.0 - <AUTHOR> http://blog.qt.digia.com/blog/2012/12/19/qt-5-0/

<comment><AUTHOR> This post has more details and informative links on Qt 5, including presentations, compared to the Digia press release.

</comment><comment><USER2> Main discussion at <https://news.ycombinator.com/item?id=4942739></comment>


Getting Started with TDD in React - <AUTHOR> https://semaphoreci.com/community/tutorials/getting-started-with-tdd-in-react <comment><USER2> Good article. Also, you can use mount to test component lifecycle hooks. Article was pretty basic.</comment>


Ingenious James Bond style cheating gadgets confiscated during gaokao - <AUTHOR> http://online.thatsmags.com/post/check-out-these-bond-esque-cheating-devices-confiscated-during-gaokao

<comment><USER2> That glasses looks better than Google Glass. Now if only they could fit in the battery pack and transmitter/receiver in the glasses itself.</comment>


Google Chrome OS to Launch in Autumn - <AUTHOR> http://mashable.com/2010/06/02/google-chrome-os-autumn/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+Mashable+%28Mashable%29&utm_content=Google+Reader <comment><USER2> They're doubting Chrome OS after the Android OS was (and is) so successful. Really? I mean... It's not a surefire win, but let's look back before making reservations going forward.

I think if they put in the effort they did for Android, Chrome OS will be great.

<comment><USER3> I think they're entirely different markets. The iPhone OS needed some real competition, and Google stepped up. What is Chrome's market? Is the competition that bad? What will Chrome bring that its competitors don't?

<comment><USER2> (Hopefully) A free product that does not require command line knowledge. Yeah, current Linux distros up to this point are pretty much at the stage where it's almost comparable with regard to ease of use for standard users, but every once in a while that kernel upgrade goes south or you can't get the wireless driver to work. If Chrome OS can be pre-installed on low-priced, higher-end machines (since Google has a ton of weight to throw around) that has great drivers written, it'll be very good for the market.

</comment></comment></comment><comment><USER4> Wonder how the bumptop acquisition will figure in.

</comment><comment><USER5> Where is the Chrome-based IDE ?

<comment><USER6> have you ever heard of <https://bespin.mozillalabs.com/> ?

<comment><USER5> Actually just tested Bespin today and it needs a lot more work before it becomes an IDE.

Right now it's just a browser-based text editor with some syntax highlighting for Javascript and HTML (XML doesn't work btw).

It needs a few more languages, code completion, code folding just to be a good editor.

Being an IDE implies also talking to some tools to compile stuff, deploy, debug, etc.

Let's say I want to code a Java application for Google AppEngine. Could I use Bespin (or anything else) to do this ? Not right now, and not soon.</comment></comment></comment>


Every Unicode character shown once per frame as a 33-minute movie - <AUTHOR> http://netpoetic.com/2011/04/unicode/ <comment><USER2> I'm surprised that I was able to perceive individual characters. At the beginning when the movie is displaying the alphabet it seems like I can see each letter. Is this really one character per frame (assuming playback at 24 frames per second)?

 _Edit:_

49,571 (characters) divided by 25 (frames per second) comes out to 1,982.84. 1,982.84 seconds is 33.03 minutes. Taking into account the padding at the beginning and end of the video reveals that the video displays 1 character per frame at 25 frames per second.

<comment><USER3> Some people adapt this into a system they claim helps speed read [1], and while I don't particularly believe the speed reading claims it is true that you can actually read quite quickly with words flashing at fairly high rates.

There are various sites online that can help you play with this, but I can't get any of them to work on the machine I'm posting this on (no Java, zapreader.com doesn't work for unknown reasons).

[1]: [http://en.wikipedia.org/wiki/Rapid_Serial_Visual_Presentatio...](http://en.wikipedia.org/wiki/Rapid_Serial_Visual_Presentation)

<comment><USER4> I could buy the speed reading claims, perhaps at _slightly_ slower rates. One of the cool things about language and our brains is you can miss letters and get order mixed up, and instantly guess what was meant with a very high rate of success.

Emxalpe: I persmue you sitll udnr snatd tis?

<comment><USER5> sliverstorm, I don't want to take this too far off topic, but what are the rates you're hearing of that you have trouble believing? I read at a little over 1,300 words per minute (and I keep getting faster). As to comprehension, without taking a test it's hard to say, but by reading a section of material for a few minutes, writing down everything I can remember without looking at the book, then re-reading to see what I've missed, I seem to get roughly 80% comprehension, which I find acceptable for most things (and it keeps getting better through practice).

Disclaimer: That's depending on the material, I read at about half that rate (around 600 wpm) if it's extremely technical or dense, or a good deal faster in anything at or below a high school reading level.

<comment><USER4> What I have trouble believing is that anyone could, using Rapid Serial Visual Presentation (which was the subject of the comment I replied to) process characters (or words) that flash on the screen as fast as (or faster than) 25fps.

Problem with serial presentation is of course, you cannot skip words or process words in parallel. I suspect when you attain 1,300wpm, you are focusing your eyes on half a page or perhaps the entire page, and only skimming sentences and absorbing key words and ideas, rather than processing each word one at a time.

<comment><USER5> Ah, my apologies for misunderstanding your comment. That's what I get for attempting rational thought at one in the morning.

Before I learned to speed read the way I currently do, I tried learning using RSVP. In my personal experience I didn't find it very helpful, and my comprehension rates (when using RSVP) plummeted. I'm in complete agreement there.

As to my 1,300wpm, you're partially correct. 1,200wpm is just about the limit at which I can read word by word, line by line in a book, using my hand as a pacer. After 1,200, I stop dropping conjunctions, pronouns, and prepositions, and anything that can be inferred through context or isn't necessary to the meaning of the sentence (e.g. - absorbing key words and ideas, but still more precise than 1/2 a page at a time).

Here's the book I learned from so you can judge the merits based upon something better than my attempted explanation: [http://www.amazon.com/Breakthrough-Rapid-Reading-Peter- Kump/...](http://www.amazon.com/Breakthrough-Rapid-Reading-Peter- Kump/dp/073520019X?tag=duckduckgo-d-20)

</comment></comment></comment></comment></comment></comment><comment><USER6> "Oh, neat, I found where the Asian characters begin!"

And then they never ended.

<comment><USER7> i personally think it's not very correct to call hieroglyphs characters and assign each of them a code.

i may be wrong but i think that there is an growing number of hieroglyphs as there is an infinite (growing) number of words; and every h. consists of more primitive parts - i think they should be coded so that the sequence of primitives would form a hieroglyph like in european languages letters form words

<comment><USER8> That's an interesting idea, but there seems like there would be a tremendous amount of complexity in encoding how the various strokes or components fit together. In English, there are twenty-six letters that fit together in one linear order, delimited by spaces and a few punctuation marks. How would you write that "down-and-to-the-left diagonal stroke meets unfilled square somewhat above the midpoint of that square's right-hand side?"

<comment><USER9> The granularity doesn't necessarily need to get down to the stroke level. In fact, if you start playing the video at around the 6 minute mark, you'll see that many of the characters are composed of the same elements, known as radicals (see: <http://en.wikipedia.org/wiki/Radical_(Chinese_character)> ).

Unicode does have the concept of "combining characters" in which a string of characters is used to compose one glyph (see: <http://en.wikipedia.org/wiki/Combining_character> ), but currently they generally are only used for adding diacritics. All Chinese characters in the current Unicode standard are precomposed, but it's potentially not out of the question to encode them as a composite of two or more sub-characters. The downside to this is that each character would end up taking several more bytes to encode, but one advantage is that novel characters could be created by combining two or more existing characters, which currently cannot be done without explicitly adding the novel character to the Unicode standard (see: [http://en.wikipedia.org/wiki/Precomposed_character#Chinese_c...](http://en.wikipedia.org/wiki/Precomposed_character#Chinese_characters) ).

The input methods that fedd mentions are just input methods, which translate what the user inputs into encodings of precomposed characters. This is different than having the encoding themselves represent the composition of the characters.

<comment><USER10> This here explains why this has not been done: <http://news.ycombinator.com/item?id=2435708>

</comment></comment></comment></comment></comment><comment><USER11> Fantastic!

What is the sound and how was it generated? It sounds like it might be narrow samples of some voice.

<comment><USER12> It gets higher and higher pitched as the video goes on, so may have to do with the unicode values. But too jumpy to just be that.

<comment><USER13> You're probably right. Not all values have been assigned a glyph yet.

</comment></comment></comment><comment><USER14> It's not _every_ Unicode character, just the ones in Helvetica.

</comment><comment><USER15> I'm curious how the audio was generated. It seems to be somewhat dependent on the character being displayed, as evidenced by jumping between different types of characters (basic letters vs japanese characters)

</comment><comment><USER16> See also: <http://www.youtube.com/user/ffoitl#p/a/u/1/gGiENL4XrjE>

</comment><comment><USER17> Only shows the Basic Multilingual Plane, when does the first sequel come out?

</comment><comment><USER18> I was really hoping to see things ordered by closeness of one character's shape to another so that as it plays it looks like something organic growing and moving around. I'll buy a beer for the person who creates that video.

</comment><comment><USER19> They say characters are the most important element of a story.

<comment><USER20> They're the most important element to a movie, especially this one.

</comment></comment><comment><USER16> Strangely beautiful.

<comment><USER5> It is, isn't it? I found myself thinking, "I'll just watch for a minute to see what this is", then getting lulled in until a distraction broke my reverie.

</comment></comment><comment><USER21> Where were you guys in 2009?

<http://vimeo.com/7489601>

</comment><comment><USER22> This video would be a lot cooler with some good background music.

</comment><comment><USER7> u vee double u ex wye zed now we know the alphabet</comment>


Schools Are Spending Millions on High-Tech Surveillance of Kids - <AUTHOR> https://gizmodo.com/schools-are-spending-millions-on-high-tech-surveillance-1823811050 <comment><USER2> Today I learned about Social Sentinel[0], since both right-twitter and left- twitter are condemning it today. Kind of heartwarming to see everyone (except LE and opportunistic entrepreneurs) agree on something for a change. Anyway, seems the idea is to analyze kids' social media accounts and send minority reports to the police. All too easy to spin it like "nothing to see here" too. Interesting that this company has been around for 4 years and I can't find a single testimonial about any attacks it prevented.

[0] [https://www.socialsentinel.com](https://www.socialsentinel.com)

<comment><USER3> Eventually one of the parties will oppose it more strongly than the other one, at which point the other one will be forced to support it. I believe this is known as "spontaneous symmetry breaking".

Also for what it's worth "minority report" was the term in the film for when one of the precogs disagreed with the other two, so it's not really applicable here. You'd be forgiven for forgetting this fact though, because the plot doesn't actually feature one.

<comment><USER2> It was a play on words.

</comment></comment></comment><comment><USER4> At my high school - a private prep school - we are required to have iPads. All of us were required to install a monitoring program that has access to most of what we do on the iPads (internet searches, messages, etc.). To my knowledge, it hasn't been used to incriminate anyone but it still makes me wary.

<comment><USER5> There will be an entire generation of kids for whom spying on everything they do on their computer till age18 will have been normalized.

What happens when they start participating in denocracy. It's hard to imagine they'll have the same expectations of personal privacy after that.

<comment><USER6> This is just their school issued Ipad. They'd hopefully have a personal computing device of some sort that they'd be free to do what they want on. Assuming they don't have helicopter parents who have to control every aspect of their kids lives, then they're just screwed.

<comment><USER7> Right -- it's the school's iPad, and they can set the terms of use.

Do schools still have libraries? They did when I went, and you can be sure they curated the set of books in the catalog and kept records of who checked out which ones.

<comment><USER8> Even the public libraries started disclosing checkout history to agencies with the advent of the PATRIOT act.

<comment><USER9> [https://www.aclu.org/librarians-nsl- challenge](https://www.aclu.org/librarians-nsl-challenge)

</comment></comment></comment></comment></comment></comment><comment><USER10> Any parent that thinks schools won't end up abusing their newfound surveillance powers is deluding themselves. Look at the example of WebcamGate at Lower Merion High School in 2010.

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

<comment> Digital-Citizen Mass surveillance is an abuse. One could go further in exploring additional abuses by looking into what is done with the data (Where is the data stored? Who else has access? What do they do with the data? Is any of this knowable?) but indiscriminately collecting information on people in the hope it will somehow prove useful is nothing but a cover for seeding people with the notion that it's right and proper to have no privacy.

Consider this excerpt from the article: ""Schools are justified in thinking about safety, both in terms of gun violence and other possible hazards," Rachel Levinson, senior counsel at the Brennan Center for Justice, told Gizmodo. "At the same time, these technologies do not exist in a vacuum; we know, for instance, that facial recognition is less accurate for women and people of color, and also that school discipline is imposed more harshly on children of color.""

Everything Levinson says here is vague and remarkably inarticulate. Being concerned is insufficient and a better written article would have asked Levinson further questions to clarify these claims. Precisely how is a bunch of data like this going to curb gun violence? What other hazards are you referring to, exactly? Why should we be concerned about the details of accuracy of the collected information while we're questioning whether it was ethical and useful to collect this data in the first place? Which school situations where "discipline is imposed more harshly on children of color" will be resolved by watching surveillance footage or examining location data?

All the more reason why people should get their own computers, never use school-issued computers, and make sure that their own computers run only a free software OS, and install nothing but free software on top of that. Also everyone (not just parents and students) need to politically organize to let students use privacy respecting books and (only if strictly needed) computer education that can be used from any computer OS.

</comment></comment><comment><USER11> I don't think I would allow my daughter to have a laptop where the spyware comes pre-installed.

Assuming the school district doesn't abuse it (like webcamgate) what's to stop every hacker from here to Moscow in this day and age?

<comment><USER12> Do parents have rights when it comes to this? What if the only way to compete school work is with a school issued laptop?

<comment><USER7> Change schools, or if public school get involved with the school board and make a stink.

</comment></comment></comment><comment><USER13> Land of the Free ⁽¹⁾⁽²⁾⁽³⁾

⁽¹⁾ No jaywalking ⁽²⁾ Permit 38A required to hold children outside areas designated safe per § 477e of title XVI ⁽³⁾ Civil rights temporarily suspended

</comment><comment><USER14> Do the parents know about this? I can't imaging this happening in my country without massive, nation-wide action to stop it and fire/punish those that tried to implement the system.

<comment><USER15> I'm curious, which country? I'm in Norway and I think would cause an outcry here too.

</comment></comment><comment><USER16> Obligatory Black Mirror reference: S4E2 "Arkangel" [https://www.youtube.com/watch?v=yef_HfQoBd8](https://www.youtube.com/watch?v=yef_HfQoBd8)</comment>


React v16.2.0: Improved Support for Fragments - <AUTHOR> https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html <comment><USER2> Several people had already noted [0] that you could implement equivalent behavior by using a component that simply returns its own children:

        const Fragment = ({children}) => children;

        // later
        return <Fragment><Component1 /><Component2 /></Fragment>;

Nice to see this added as both a built-in component type and a useful syntax extension. (Now if they'd just modify JSX syntax so that we can pass props by matching local variable names similar to how ES6 object literals work, like `<SomeComponent a b c />`, rather than having that become a defaulted-true boolean, I'd be happy :) )

[0] [https://medium.com/@gajus/using-react-v16-to-create-self- des...](https://medium.com/@gajus/using-react-v16-to-create-self-destructing- components-de8e4eb61d0f)

<comment><USER3> To be pedantic, it's not 100% equivalent. You can find the nitty-gritty details about the (intentional) differences here: [https://github.com/facebook/react/pull/10783](https://github.com/facebook/react/pull/10783).

We did mention the author of react-aux in the blog post though :-)

> _Thanks to Gajus Kuizinas and other contributors who prototyped the Fragment > component in open source._

</comment></comment><comment><USER4> Ive started with React recently and strangely the lack of fragments were one of the things that caught my attention in the first days.

Another thing I'm looking for in React as I get started is better styling support. I'm resourcing to React JSS for that, but I feel it should be part of the language. The _web trinity_ if you may is HTML-CSS-JS and React basically left CSS out half-baked into almost unusable style attributes, so I still have to resource to className and CSS. Or am I just being noob-anal?

<comment><USER5> I've found styled components to be a nice attempt at bundling styles with the component. Haven't tried that many options though.

It has out of the box support in Atom and scss (like?) syntax.

[https://github.com/styled-components/styled- components](https://github.com/styled-components/styled-components)

</comment></comment><comment><USER6> I appreciate the addition of Fragments, but I'm not sure if the addition to the JSX syntax was really a good decision.

While it initially took some time to wrap my head around JSX (especially with a lot of JS mixed into it), after that I really started to enjoy JSX for its simplicity. The Fragment syntax adds some additional magic to JSX (which is rarely a good thing), and will also very likely break all the syntax highlighting out there again when used.

<comment><USER7> > The Fragment syntax adds some additional magic to JSX (which is rarely a > good thing)

In: <></>

Out: <React.Fragment></React.Fragment>

WITCHCRAFT!! SORCERY!!

Teasing aside, I don't get what's magical about this. It's a straightforward transform. You can call that "magic," I'll call it "syntax."

<comment><USER6> Sure, we can call it syntax. Of course, for anyone who already knows what it does, it's just a transform, but the problem with extra syntax is that it makes it harder for newcomers to pick it up.

Taking your example when putting it in front of someone seeing it for the first time:

In: <></>

Out (Newcomer): WTF does that mean? Did someone forget to put something in those tags?

<comment><USER3> Same newcomer, in a couple of weeks: "Don't know how I lived without it".

I understand your point, but in practice people love tiny affordances like this, especially when they are needed as often as fragments are.

This is a balance, but it's important to consider the needs of power users too. Beginners don't stay beginners forever. We've thought about this for a few months, and decided that adding syntax would be better. I understand some people will always disagree though, and that's fine :-)

<comment><USER8> Yeah, it seems like the decision to make the fragment a first-class JSX concept has a lot to do with portability between renderers. The post makes it clear you all have given this a lot of thought and care, and I appreciate that (even if it _will_ take me awhile to get used to seeing empty tags, haha).

</comment></comment></comment></comment></comment><comment><USER9> These will be quite nice when wrapping things like css grid components which must be on the same DOM level.

</comment><comment><USER10> Man, although fragments are a pretty useful concept, the implementation is really terrible. It feels so uninspired and without thought of the design, in my opinion. They could have chosen some character instead of an empty tag and it would have been much better, like an asterisk[1], because it would be clear that the tag serves a defined purpose. I would almost argue that if this weird shorthand is necessary to accomplish this task (something that irked me when creating text heavy pages) then JSX should be redesigned to handle it natively without the weird fragment syntax.

1: Like this:

      <*> ... </*>

<comment><USER3> >feels so uninspired and without thought of the design, in my opinion.

Thanks for feedback! I assure there wasn't a lack of thought, in fact we discussed this for several weeks before even beginning to implement this. Your proposal was also considered but it doesn't bring anything over <>, whereas * already has a meaning in JS related to generators. It would be confusing to use it here for a different purpose.

FYI, <> is not original. As mentioned in the post, it has prior art. It already went through standardization once (in E4X). It has also been used for months (maybe over a year) in ReasonML, and its users reported really enjoying this syntax.

You may not like it but it doesn't mean we haven't given this any thought. :-)

<comment><USER10> Yes, technically if the empty tags do suffice, then the asterisk brings no additional value, and it would be potentially confusing to use a character that already serves a purpose in Javascript, although I doubt it since JSX tags don't support generators as an attribute or name. You could replace the asterisk with a different character in that case. My main point is that the empty tag feels, well, empty and made without a real purpose, in part because it's just so foreign compared to HTML (which is what JSX is based on?) as this kind of thing is never found in HTML. While I'm sure that there wasn't a lot of discussion within the React team about this, the inclusion of at least a single character, whatever that would be, would make it feel like it was actually designed properly, and I would also argue that adding something to make the tag feel nonempty would actually have a value (to make the tag explicit and not confusing).

I don't necessarily buy the prior art arguments too because E4X was barely used even though it was a standard and is now deprecated, and ReasonML is pretty specialized and much less popular, as well as has a different set of users, than React. If you had told me a product in the same category as React, like Angular, Vue, Ember, Ractive, etc., used that syntax, I would be much more receptive.

<comment><USER3> _> I doubt it since JSX tags don't support generators as an attribute or name_

Not currently, but we do have some plans regarding do-expressions, generators, and JSX. So * might get a meaning, even though not in attributes but children.

 _> My main point is that the empty tag feels, well, empty and made without a real purpose, in part because it's just so foreign compared to HTML (which is what JSX is based on?) as this kind of thing is never found in HTML._

I think most React users in practice don't touch HTML that often. JSX has quite a few differences with HTML, and we don't really plan to bring it _closer_ to HTML in the future. It is more important to us to make JSX pleasant and convenient to everyday React users than it is to have 1:1 mapping to every HTML concept.

 _> ReasonML is pretty specialized and much less popular, as well as has a different set of users, than React._

I would argue that people using ReasonML today are the same kind of early adopters (and often even the same people) that started using React four years ago when the ecosystem didn't exist (and shaped that ecosystem). I trust their judgment.

 _> If you had told me a product in the same category as React, like Angular, Vue, Ember, Ractive, etc., used that syntax, I would be much more receptive_

By that logic, we could dismiss React when it came out, because it was not like anything else :-) Give this syntax some time. It felt odd to me at first, after living with it for a few months it feels very natural. I'm sure you'll get to like it eventually too. At that point it might feel odd that other libraries _don 't_ provide this syntax.

</comment></comment></comment></comment><comment><USER11> I love to see these small improvements added to React.

Everything is not perfect though, some issues have been here for a looong time. At the moment, my biggest problem is the non-support of passive events [0]. And today, some browsers are starting to make some events passive by default (`touchmove` on Chrome for example), it is quietly starting to become a serious problem for developers to get things working fine cross-browser without anti-patterns.

[0] [https://github.com/facebook/react/issues/6436](https://github.com/facebook/react/issues/6436)

</comment><comment><USER12> I was already thinking "but what about Typescript..." then saw it already supports it :)

Well done react team and contributors.

</comment><comment><USER13> Why can't they automatically wrap every bit of JSX with a <Fragment> tag? That way users would need to include an empty tag when they're returning multiple elements, and they're not it'll be a fragment tag that just contains a single element.

<comment><USER3> Because you don't know where JSX ends and code begins. Don't forget that fragments can include text nodes too.

return <div />

// am I a comment? Or text after div?

<comment><USER13> Ah, hmm... good catch.

</comment></comment></comment><comment><USER14> This is a bit off topic, but does anyone reading this happen to know the status of async rendering in react?

There was chatter about it for version 16, and then nothing really else. I'm curious about what they are testing or at least planning in this area.

Unfortunately i've found it really hard to search for anything related to async rendering for react, as there is just so much other crap about react and "async" it just gets lost.

<comment><USER3> You can track it here. Still plenty of work to do but we are making progress.

[https://github.com/facebook/react/issues/8830](https://github.com/facebook/react/issues/8830)

[https://github.com/facebook/react/issues/11566](https://github.com/facebook/react/issues/11566)

<comment><USER14> Thank you! This is exactly what I was looking for and it seems all search engines have failed me!

</comment></comment></comment><comment><USER15> No mention of prior work? This is part of web platform since forever. See document.createDocumentFragment().

<comment><USER7> We did mention some prior art in the section discussing the new syntax:

> Fragment syntax in JSX was inspired by prior art such as the XMLList() <></> > constructor in E4X. Using a pair of empty tags is meant to represent the > idea it won't add an actual element to the DOM.

You're right that we could have referenced document.createDocumentFragment(), too. Perhaps we'll add that to the documentation. Thanks for the suggestion!

<comment><USER15> Thanks, it's a useful part of the DOM, perhaps somewhat overlooked.

</comment></comment></comment><comment><USER16> I just can't help but sneer. Opinionated document.write() using "jsx".

Working with react has been the worst experience of my life. I had to call a meeting and laid in down in October. If 2018 is React, I am leaving on Dec 31.

So soon I am going swiftly back into the arms of Angular and I can't wait. Honestly, my eyes are blurring as I type this with pure happiness.

Enjoy the fragments guys, it will be good practice for picking up what little is left of your happiness and transferable skill set in years to come.

<comment><USER17> Next time post this kind of stuff on your blog, not HN comments.</comment></comment>


Apple customers can now buy or rent titles directly in the Prime Video app - <AUTHOR> https://techcrunch.com/2020/04/01/in-a-significant-change-apple-customers-can-now-buy-or-rent-titles-directly-in-the-prime-video-app/ <comment><AUTHOR> I can't wait for this to reach the Kindle/Audible apps.</comment>


H-1B Visas Are The Enemies Of Innovation: Vivek Wadhwa Video Interview, Part III - <AUTHOR> http://techdrawl.com/News-Post/Fresh-Voices/Drinks-On-Fifth-Vivek-Wadhwa-Act-III <comment><USER2> 100% Agree. I'm about to finish my PhD in Computer Science, and one of the key reasons I'm not doing a startup is because I need a H1 visa to stay in the US.

<comment><USER3> Actually you have at least 12 months to work on your startup via the OPT. If you can make it work and generate revenue, you can get the startup e-verified and then you would have another 15 months.

</comment></comment><comment><USER4> Go home mixi, the student visa's purpose was for you to upgrade your know-how, then return to your homeland and be of assistance there. Our STEM grads would like jobs in America too. Nobody believes your line of "I'd create a zillion jobs for Americans if they'd let me live here." Liar.

<comment><USER3> Please do not stoop to name calling here.</comment></comment>


Ask HN: Why Somalia has become a safe heaven for pirate? - <AUTHOR>

I thought that the waters of world were safe. People coming on a small boat and hijacking huge ships seemed some years old phenomenon to me. However I am surprised how the Somalian pirates have made news.<p>Hows come the world, so many nations with their Navy can curb these pirates? <comment><USER2> Honestly, I think it has a lot to do with financial issues. This articles was posted earlier today that you may find interesting:

[http://www.wired.com/politics/security/magazine/17-07/ff_som...](http://www.wired.com/politics/security/magazine/17-07/ff_somali_pirates)

I don't think it's entirely true that private security contractors are actually trying to prolong the problem in an attempt to make more money, but I do think it's mainly due to someone's financial/political agenda. Nobody wants to deal with the REAL problems in Mogadishu, and obviously there are few people who find it cost-effective to make such a decisive move against piracy. There's several good documentaries going around on TV that show how difficult it is to deal with the problem without majorly interrupting legitimate trade.

>> However I am surprised how the Somalian pirates have made news.

There's a lot more ships going through that area than the news lets on. The news agencies have there agenda too - if they can make the situation sound more dramatic, it's in their best interests to do so.

</comment><comment><USER3> When I was younger, the waters of Southeast Asia were very dangerous for piracy. It seems to me that piracy arises whenever the governments of countries with strong navies are not united in dealing with it.

</comment><comment><USER4> Some history on the Somalia situation:

[http://www.time.com/time/world/article/0,8599,1892376,00.htm...](http://www.time.com/time/world/article/0,8599,1892376,00.html)</comment>