HHVM and Hack
Might These Be The Droids We Are Looking For?
BYOPL (Build Your Own Programming Language)
BYOPL (Build Your Own Programming Language)
- Microsoft (F#)
- Google (Go)
- Facebook (Hack)
- Apple (Swift)
- what do they have in common?
static typing*
or at least optional static typing
why?
are our current tools so inadequate?
- different time, different context
- FP, type systems, lazy evaluation, CSP, ...
- parallel & async, stability and robustness, security, ...
solution?
rm -rf project/ && git init project/
(not really.)
what's up with PHP?
some very cool stuff
- namespaces
- generators
- traits
- ReactPHP
what's up with PHP?
some not-so-cool stuff
- no OOB multithreading
- too much focus on backwards compat
- not-really-state-of-the-art execution model
- overall slow development, playing catch-up
Facebook to the rescue?
HHVM?
- alternative runtime for PHP (Zend Engine replacement)
- combo: efficient interpreter && JIT compiler
Hack?
- new programming language targeting HHVM
- huge focus on PHP interop
- (optional) static typing
HHVM
what's the fuss, anyway?
multiple implementations are the norm
- Python: CPython, Jython, PyPy, ...
- Ruby: MRI, JRuby, Rubinius, ...
- Clojure: Clojure JVM, Clojure CLR, ClojureScript, ...
- .NET: CLR, Mono, ...
- JVM: HotSpot, OpenJDK, GCJ, ...
different implementations — different focus
- alternative execution models (PyPy)
- speed (V8)
- different target platforms (JRuby)
- additional features (avoiding the GIL)
competition, diversity
History
(disclaimer: not how it actually happened.)
2010: HipHop for PHP
- hphpc: PHP → AST → C++ → x64
- PHP code → static analysis → type inference → C++ code generation
- quickly (~6 mo.) took over the majority of Facebook's web traffic
- up to 6x increase in performance over Zend
2010: HipHop for PHP
- hphpi: alternative interpreter
- motivation: slow compilation process, easier debugging
- uses a different AST
2011 / 2012: HHVM
- base: PHP → hphpc's AST → HHBC
- then: HHBC → x64 JIT
- but also: HHBC → interpreter
- initially, only used as a replacement for hphpi
late 2012: HHVM performance beats hphpc
Y U NO JIT?
HHVM Exec Model
- trace-based (vs. method-based)
- basic block: tracelet
HHVM Exec Model
- interpreter & JIT working together
- interpreter as an execution engine of "last resort"
- JITter support for HHBC not 100% complete
HHVM Exec Model
- one tactic: run the code with the interpreter a couple of times
- gather type information from the interpreter
- help JIT predict types & create larger tracelets (perf++)
HHVM vs. Zend
- framework support: Doctrine2, Drupal, Laravel, PHPUnit, ...
- software support: WordPress, MediaWiki, phpbb3, phpmyadmin, ...
- included extensions: APC, cURL, DOM, ImageMagick, JSON, MCrypt, Memcache(d), MySQLi, PDO, SPL, XML, ...
- Composer: 1447 + 1053 packages (out of ~11600)
<?hh
"The goal of Hack to offer developers a way to write cleaner, safer and refactorable code while trying to maintain a level of compatibility with current PHP codebases. The primary way that this goal is achieved is to provide developers a way to annotate PHP functions and classes with type information, providing a type checking tool to validate those annotations."
Key Features
Type Checking
- type annotations
- "type checking server" (instant checks)
- type checker - before runtime (no compilation step!)
Type Checking
<?hh
function x(int $a) {
return $a * 2;
}
print(x(2));
// 4
Type Checking
<?hh
function x(int $a) {
return $a * 2;
}
print(x(null));
// Fatal error: Argument 1 passed
// to x() must be an instance of int,
// null given in /mnt/hhvm/index.hh
// on line 5
Hack Modes
- // strict
- // partial
- // decl
- // unsafe
Cup<T>
- generics
Cup<T>
<?hh
// deceptively useless example
class Box<T> {
public T $value;
public function __construct(T $v) {
$this->value = $v;
}
}
// there are no typed references
// in Hack. yet, objects are
// passed by reference.
Nullable
MOAR NULLZ!!!111
Nullable
<?hh
function setAge(int? $age, Person $p) {
if (is_null($age)) {
$p->setAge(Age::UNKNOWN);
} else {
$p->setAge($age);
}
return $p;
}
Type Aliases
<?hh
type Age = int;
function setAge(Age? $age, Person $p) {
$p->setAge($age);
return $p;
}
// we can pass a regular int here
setAge(21, $person);
"Opaque" Type Aliases
<?hh
// one.php
newtype myInt = int;
function dbl(myInt $i) { return $i * 2; }
// two.php - type checker balks
function triple(myInt $i) { return $i * 3; }
actual usage for Type Aliases
<?hh
type Point2D = (int, int);
function quux(Point2D $p) { return $p; }
// instead of...
function quux((int, int) $p) { return $p; }
Proper Lambdas
<?php
$param = true;
// "use": explicit closure wannabes
$x = array_map(function($a) use /* WAT */ ($param) {
return ($param === true) ? ($a * 2)
: ($a * 3);
}, $my_important_array);
Proper Lambdas
<?hh
$param = true;
$x = array_map($a ==> {
return ($param === true) ? ($a * 2)
: ($a * 3)
}, $my_important_array);
Some Other Features
- async / await
- tuples
- "shapes" (~structs)
- collections (incl. immutable)
docs, community, tools
- ...much to be desired...
- docs.hhvm.com
- hard to google (seriously? "Hack"?)
- still no widespread editor support
running HHVM & Hack
- Hack comes OOB with HHVM
- packages for most OSs
- deployment: FastCGI
- github.com/nikolaplejic/docker.hhvm