* HAL embeds child documents recursively, while JSON API flattens the entire graph of objects at the top level. This means that if the same "people" are referenced from different kinds of objects (say, the author of both posts and comments), this format ensures that there is only a single representation of each person document in the payload.
* Similarly, JSON API uses IDs for linkage, which makes it possible to cache documents from compound responses and then limit subsequent requests to only the documents that aren't already present locally. If you're lucky, this can even completely eliminate HTTP requests.
* HAL is a serialization format, but says nothing about how to update documents. JSON API thinks through how to update existing records (leaning on PATCH and JSON Patch), and how those updates interact with compound documents returned from GET requests. It also describes how to create and delete documents, and what 200 and 204 responses from those updates mean.
In short, JSON API is an attempt to formalize similar ad hoc client-server interfaces that use JSON as an interchange format. It is specifically focused around using those APIs with a smart client that knows how to cache documents it has already seen and avoid asking for them again.
It is extracted from a real-world library already used by a number of projects, which has informed both the request/response aspects (absent from HAL) and the interchange format itself.
Well, I'm guessing your second and third point could be tacked on to HAL.
I see your point with the first one, although I must say in our APIs we have rarely encountered duplication. And the recursive nature of HAL makes it really easy to generate on the server-side.
(By the way, we've introduced a sideloading convention that only when you pass along ?embedded=author,comments those sub-resources will be present under _embedded. This way the clients can easily request only what's needed.)
Wouldn't (most of) the shortcomings of HAL you mention, be overcome by Collection+JSON [0]? It seems better suited as an already existing media type that accomplishes what you try to do with JSON API.
http://stateless.co/hal_specification.html