I've seen Hack used in a multi-tens-of-MLOC codebase to gradually insert types. It made huge differences in the kinds of changes that were possible; you can, e.g., rename a class or method, or change the order of its arguments, with confidence comparable to that in a C++ codebase. Most developers hack-ified everything they could get their hands on, and did all new work in Hack, without any external encouragement.
Dealing with the parts that aren't Hackified, though, is horrific. Complex codebases with no types are just ridiculous.
In terms of Hack as a language, it's very similar to the JavaScript->TypeScript relationship. It's still mostly PHP, but it doesn't quite get the new PHP features as quickly, and there is the chance that there could be incompatibilities in the future which could cause new PHP code to start looking and acting differently than Hack code.
The XHP plugin[0] (which you can include as a Composer dependency, but you have to be able to run Composer directly under the HHVM daemon and not PHP) allows XML to act like a first-class citizen. No more interpolating between HTML strings and having to escape all of your variables, you can now just do
echo <b>{$possibly_evil}</b>;
and it just works (and auto-escapes.) You can even extend the XML root object to create your own tags[1]. Combined with Hack's native autoloader[2] (which allows whitelisting constants, functions, tags and types) Hack provides a lot of the features PHP developers will find standard in most templating frameworks, without the overhead of the actual framework.Another benefit (possibly) is that improperly formatted XML will break with an error, so it's guaranteed that if your document renders, it's correct.
[0]https://docs.hhvm.com/hack/XHP/introduction
[1]https://coderwall.com/p/3leegq/getting-stuck-in-with-xhp
[2]https://docs.hhvm.com/hack/other-features/autoloading
Hack allows generics, type hinting and aliasing[3-5]. These only apply when running the typechecker, however, when the code is running, everything decays to basic PHP primitives. I've been bitten a couple of times by this, because you might expect that you could use an aliased type as a typehint - you can't. You can define it as a return type, though.
Collections, like Maps and Vectors (oh, it has maps and vectors), can have immutable types[6].
[3]https://docs.hhvm.com/hack/generics/introduction
[4]https://docs.hhvm.com/hack/types/type-system
[5]https://docs.hhvm.com/hack/type-aliases/introduction
[6]https://docs.hhvm.com/hack/collections/introduction
Hack also supports "async" functions[7], which really aren't asynchronous. I found it a bit difficult to get this to work with curl and SQL the way I want to, but anything that helps remove the bottlenecks of database and network requests is welcome.
[7]https://docs.hhvm.com/hack/async/introduction
To me, Hack just feels like a better more sane PHP. All of the strictness is optional, but it still feels very good to have it there, and it has features users of more modern languages would certainly find welcome.
My pitfalls, so far, are mostly the result of my own ignorance of Vagrant and what the best practices for a workflow should be. I'm still debugging stuff in nano because I don't know any better.
Also, it seems OpenShift has a HHVM module, but you can't run Composer through HHVM on it, and as a result can't run a Hack project with XHP, because of Composer dependencies that require being run under HHVM. I asked StackOverflow what to do three months ago and just got utter silence and a single downvote[8]. I'm assuming that means I either have to learn how to write my own OpenShift cartridge or pay for an account.
[8]https://stackoverflow.com/questions/38111369/using-hhvm-and-...
Which brings me to my biggest sort of pet peeve about Hack - there doesn't seem to be the sort of community around it that PHP has, and a dearth of information on certain topics.