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 • .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, Map • Generics: A, foo(T $x): T • Constraints: foo(T $x): T DEMO Static Typing -> Dynamic Language

• 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