Hack for HHVM
• Very large codebase (> 10,000 millions) • Engineers have access to the entire codebase • Culture where everybody moves fast • At this scale, everything changes: – Performance is very critical – Security – Refactoring WHY PHP? PHP • Available everywhere • Very fast development cycle • Very easy to learn • Many libraries • Request based model
OK but … WHY PHP? Because …
PHP: a FAST feedback loop
FAST dynamic
g++ -02 - Type
whatever checking
static C++ Linking
./a.out How do we move forward? Just use Scala!
• … Or whatever your favorite language is … • Are we going to convert 10+M lines of code to another language? – The runtimes are incompatible – The object model is different in subtle ways – Very impractical at this scale Making things better
• HPHPc • XHP (inline HTML) • Generators • Lint rules HHVM
• A JIT compiler for PHP • 5X to 9X faster • Supports modern PHP • HHVM now supports a new language: HACK • hhvm.com/repo What is at stake?
• Consequence of subtle bugs: – Corrupt database, etc … • Consequence of difficult APIs: – Copy pasta, hard ramping up time • Consequence of difficult refactoring: – Bad APIs stay bad HACK (or Hack for HHVM) Hack
• A statically typed language for HHVM • Compatible with PHP: – Interoperates with no overhead – Same representation at runtime • Evolved from PHP: – If you know PHP, you know Hack! • Designed for incremental adoption: – Gradual typing
The type checker in action! DEMO Hack Type System
• What must be annotated? – Class members – Function parameters – Return types • What is inferred? – All the rest Hack Types
• All PHP types: int, MyClassName, array • Nullable: ?int, ?MyClassName • Mixed: anything (careful) • Tuples: (int, bool, X) • Closures: (function(int): int) • Collections: Vector
• PHP wasn’t designed to be statically typed. • Example of things that are expected to work: Hack Type Inference (1)
• Let’s infer the type of $x: Hack Type Inference (2)
• How does a type-system normally work? – Type-variables are introduced – A unification algorithm solves the type-variables (usually noted α)
type($x) = α if (…) { $x = new A(); unify(α, A) => α = A } else { $x = new B(); unify(α, B) => α = B } ERROR Type inference in Hack
• Hack introduces unresolved types (noted U)
type($x) = α = U() if (…) { $x = new A(); $x = α = U(A); } else { $x = new B(); $x = α = U(A, B); }
takesAnIFace($x); $x = α = U(A, B) = IFace with (A ≤ IFace, B ≤ IFace) Hack Type Inference: Generics (1)
• Should this work? Hack Type Inference: Generics (2)
• Yes, because of this: Hack Type Inference: Generics (3)
• But this won’t work: Error messages
• We can’t expect the user to understand all the type-inference • The solution: keep the reason why we deduced a type and expose it to the user
HACK CONVERSION Facebook now runs on HACK
• Majority of our codebase is in Hack • Organic adoption • Automated conversion, 4 kinds of tools: 1. Static analysis (credit: Josh Watzman) 2. Refactoring (credit: Yoann Padioleau) 3. Runtime monitoring (credit: Alok Menghrajani) 4. Codebase monitoring (credit: Gabriel Levi)
Hack Adoption • Facebook developers using Hack Coverage MAP (credit: Yoann Padioleau) DEMO What’s next?
• PHP 5.5 compatibility • Open-sourcing
Questions? HACK ARCHITECTURE Working at scale: Classic Approach
• A compiler: takes input files produces .o • A Makefile: recomputes the object files when something changed • A linker: produces a binary file from .o • IDE: talks to the compiler • This design came to be for historical reasons Working at scale: Hack
• We knew we wanted an IDE from day one • Big code base • The solution, a server: – The server type-checks all the files – Keeps track of the dependencies – Re-computes types when something changed