an elephant of a different colour: hack

30
An Elephant of a Different Colour: Hack Reduce your Server Load, Reuse your Code and Recycle your PHP Skills with HHVM & Hack Image Copyright Keith Evans. This work is licensed under the Creative Commons Attribution-Share Alike 2.0 Generic Licence. To view a copy of this licence, visit http://creativecommons.org/licenses/by-sa/2.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Upload: vic-metcalfe

Post on 11-May-2015

1.300 views

Category:

Technology


2 download

DESCRIPTION

Slides from my GTA-PHP Meetup talk about Hack which is the Facebook version of the PHP programming language which runs under their HHVM runtime environment for PHP. The focus of my talk was the language improvements that the Facebook team has added to PHP. There's a lot of information in the presenter's notes, so if you're interested in Hack scroll down to see the extras.

TRANSCRIPT

Page 1: An Elephant of a Different Colour: Hack

An Elephant of a Different Colour: Hack

Reduce your Server Load, Reuse your Code and Recycle your PHP Skills with HHVM & Hack

Image Copyright Keith Evans. This work is licensed under the Creative Commons Attribution-Share Alike 2.0 Generic Licence. To view a copy of this licence, visit http://creativecommons.org/licenses/by-sa/2.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San

Francisco, California, 94105, USA.

Page 2: An Elephant of a Different Colour: Hack

Just in case you’re not up to speed on this HHVM

stuff…

© Some rights reserved by Dave Hamster

© Some rights reserved by Andy Barnes

© Some rights reserved by Casey Fleser

Page 3: An Elephant of a Different Colour: Hack

HackXHP

Async

Collections

Lambda

Types

Page 4: An Elephant of a Different Colour: Hack

XHP<?hhrequire_once('lib/init.php');$class = "greeting";$subject = "Toronto & area";$body = <p class={$class}>$hello {ucwords($subject)}</p>;echo <x:doctype> <html> <head><title>Hello XHP</title></head> <body>{$body}</body> </html></x:doctype>;

<!DOCTYPE html><html><head><title>Hello XHP</title></head><body> <p class="greeting">$hello Toronto &amp; Area</p></body></html>

Page 5: An Elephant of a Different Colour: Hack

XHP

XHP emits HTML without

the whitespace andformatting. I’ve added

itfor readability.

<?hhrequire_once('lib/init.php');$list = <ul />;for ($i = 0; $i < 7; $i += 1) { $list->appendChild(<li>{date('l', time() + $i * 86400)}</li>);}echo $list;

<ul> <li>Monday</li> <li>Tuesday</li> <li>Wednesday</li> <li>Thursday</li> <li>Friday</li> <li>Saturday</li> <li>Sunday</li></ul>

Page 6: An Elephant of a Different Colour: Hack

XHP

• Available for Zend PHP too!

• See https://github.com/facebook/xhp

• Can use HTML() to emit unescaped HTML but don’t.

Page 7: An Elephant of a Different Colour: Hack

CollectionsVector

Map

Set

Pair

0 => ‘Apples’,1 => ‘Bananas’,2 => ‘Oranges’

[Red] => ‘Apples’,[Yellow] => ‘Bananas’,[Orange] => ‘Oranges’

0 => ‘Apples’,1 => ‘Bananas’

‘Apples’,‘Bananas’‘Oranges’

Page 8: An Elephant of a Different Colour: Hack

Vectors[0] => "zero"[1] => "one"[2] => 2

<?hh$v = Vector { "zero", "one" };

$v[] = 2;

$v->add($v->count());

$v->removeKey(0);

print_r($v);

[0] => “one"[1] => 2[2] => 3

[0] => "zero"[1] => "one"[2] => 2[3] => 3

[0] => "zero"[1] => “one”

Page 9: An Elephant of a Different Colour: Hack

Old School Arrays

Can you spot the difference between

the Hack and PHP results?

<?php$v = array("zero", “one”);

$v[] = 2;

array_push($v, count($v));

unset($v[0]);

print_r($v); [1] => "one"[2] => 2[3] => 3

[0] => “zero"[1] => “one"[0] => "zero"[1] => "one"[2] => 2[0] => "zero"[1] => "one"[2] => 2[3] => 3

Page 10: An Elephant of a Different Colour: Hack

Vectors

• Always 0 .. (count -1)

• Values are not hashed / indexed

• Use Sets for this

• Can use [] to append, but not unset() to remove

Page 11: An Elephant of a Different Colour: Hack

PairPair Object( [0] => Pair Object ( [0] => Batman [1] => Robin ) [1] => xhp_p Object ( [tagName:protected] => p [attributes:xhp_x__composable_element:private] => Array () [children:xhp_x__composable_element:private] => Array ( [0] => The dynamic Duo ) [source] => /home/vic/prog/presentation/collections/pair.php:4 ))

<?hhrequire_once('../lib/init.php');$dynamicDuo = Pair {'Batman', 'Robin'};$p = Pair {$dynamicDuo, <p>The dynamic Duo</p>};print_r($p);

Page 12: An Elephant of a Different Colour: Hack

Pair

• Pairs must contain two items of any type

• Pairs are always immutable

• Items are accessed with [0] and [1]

Page 13: An Elephant of a Different Colour: Hack

Map

Map Object( [CA] => Canada [US] => United States [MX] => Mexico [NI] => Nicaragua)

<?hh$map = Map { 'CA' => 'Canada', 'US' => 'United States'};$map->add(Pair {'MX', 'Mexico'});$map['NI'] = 'Nicaragua';print_r($map);

Page 14: An Elephant of a Different Colour: Hack

Map

• Maps contain key / value Pairs

• Keys can only be integers or strings

• Values can be of any type

• Order is preserved

Page 15: An Elephant of a Different Colour: Hack

Set

HH\Set Object( US CA MX NI Has Canada)

• Can only contain integers orstrings

• Unordered

<?hh$s = Set {'US', 'CA'};$s->add('MX');$s[] = 'NI';$s[] = ($s->contains('CA') ? 'Has' : 'Lacks') . ' Canada';print_r($s);

Page 16: An Elephant of a Different Colour: Hack

Types<?hhfunction add(int $a, int $b): int {

return $a + $b;}var_dump(add(1, 2));var_dump(add(1.5, 2));

int(3)HipHop Fatal error: Argument 1 passed to add() must be an instance of int, double given in /home/vic/prog/presentation/type.php on line 4

Page 17: An Elephant of a Different Colour: Hack

Types<?hhfunction add(

shape('x' => int, 'y' => int) $p1,shape('x' => int, 'y' => int) $p2

): shape('x' => int, 'y' => int) {return shape(‘x' => $p1['x'] + $p2['x'], 'y' => $p1['y'] +

$p2[‘y']);}var_dump(add(['x' => 3, 'y' => 4], ['x' => 5, 'y' => 25]));

array(2) { ["x"]=>int(8) ["y"]=>int(29)}

Page 18: An Elephant of a Different Colour: Hack

Types<?hhtype Coord = shape('x' => int, 'y' => int);function add(Coord $p1, Coord $p2): Coord {

return ['x' => $p1['x'] + $p2['x'], 'y' => $p1['y'] + $p2['y']];}var_dump(add(['x' => 3, 'y' => 4, 'z' => 1], ['x' => 5, 'y' => 25]));var_dump(add(['x' => 3, 'z' => 4], ['x' => 5, 'y' => 25]));array(2) {[“x”]=>int(8), [“y"]=>int(29)}

HipHop Notice: Undefined index: y in /home/vic/prog/presentation/typedef.php on line 4

array(2) {[“x”]=>int(8), ["y"]=>int(25)}

Page 19: An Elephant of a Different Colour: Hack

Generics<?hhclass Accumulator<T> {

function __construct(private T $value) {}function add(T $value) { $this->value +=

$value; }function get():T { return $this->value; }

}$accumulateInts = new Accumulator<int>(5);$accumulateInts->add(4);var_dump($accumulateInts->get());

$accumulateFloats = new Accumulator<float>(0.7);$accumulateFloats->add(1.6);var_dump($accumulateFloats->get());

$accumulate = new Accumulator([5]);$accumulate->add([4,9]);var_dump($accumulate->get());

int(9)

float(2.3)array(2) {

[0]=>int(5) [1]=>int(9)}

Page 20: An Elephant of a Different Colour: Hack

Generics<?hhclass Accumulator<T> {

function __construct(private T $value) {}function add(T $value) { $this->value +=

$value; }function get():T { return $this->value; }

}$accumulateInts = new Accumulator<int>(5);$accumulateInts->add(4);$accumulateInts->add(4.4);var_dump($accumulateInts->get());

float(13.4) !

Page 21: An Elephant of a Different Colour: Hack

Nullable Types<?hhfunction printNum(?int $num) {

echo "num is ";echo is_null($num) ? "null" :

$num;echo "\n";

}printNum(1);printNum(null);printNum("Five");

num is 1num is nullHipHop Warning: Argument 1 to printNum() must be of type ?int, string given in /home/vic/prog/presentation/nullable.php on line 6num is Five

Page 22: An Elephant of a Different Colour: Hack

Types<?hhclass MyClass<T as SomeInterface> {

function __construct(private T $v) {}}

newtype Secret as BaseClass = MyClass;

Page 23: An Elephant of a Different Colour: Hack

Lambda<?php$countries = [

'US' => 'United States','CA' => 'Canada','MX' => 'Mexico',

];uasort($countries, function ($a, $b) {

return $a > $b;});var_dump($countries);

array(3) { ["CA"]=> string(6) "Canada" ["MX"]=> string(6) "Mexico" ["US"]=> string(13) "United States"}

Page 24: An Elephant of a Different Colour: Hack

Lambda

array(3) { ["CA"]=> string(6) "Canada" ["MX"]=> string(6) "Mexico" ["US"]=> string(13) "United States"}

<?hh$countries = [

'US' => 'United States','CA' => 'Canada','MX' => 'Mexico',

];uasort($countries, ($a, $b) ==> $a > $b);var_dump($countries);

Page 25: An Elephant of a Different Colour: Hack

Lambda

<?hh$add = ($a, $b) ==> $a + $b;

function curry($callable, $value) {return $v ==>

$callable($value, $v);}

$addFour = curry($add, 4);var_dump($addFour(5));

int(9)

Page 26: An Elephant of a Different Colour: Hack

User Attributes<?hh<< MyAnnotation('Unicorn', 42) >>function bar() {}

$rc = new ReflectionFunction('bar');print_r($rc->getAttributes());

Array( [MyAnnotation] => Array ( [0] => Unicorn [1] => 42 )

)

Page 27: An Elephant of a Different Colour: Hack

User Attributes

• You can add attributes / annotations to classes, methods, functions and arguments.

• You can specify more than one set of user attributes:<< Foo(1), Bar(2) >>

• You can’t use constants or variables in attributes

Page 28: An Elephant of a Different Colour: Hack

Async

• I lied; hhvm’s async is more c# than node.

• Library functions like evhttp_async_get() don’t return Awaitable’s

• So they don’t seem to play well together

• PocketRent/beatbox uses async, but I don’t grock it

Page 29: An Elephant of a Different Colour: Hack

class Foo{}

class Bar { public function getFoo(): Foo { return new Foo(); }}

async function gen_foo(int $a): Awaitable<?Foo> { if ($a === 0) { return null; }

$bar = await gen_bar($a); if ($bar !== null) { return $bar->getFoo(); }

return null;}

Async

async function gen_bar(int $a): Awaitable<?Bar> { if ($a === 0) { return null; }

return new Bar();}

gen_foo(4);

This is the exampleFacebook provided on GitHub for async.

Page 30: An Elephant of a Different Colour: Hack

More• See hhvm.com

• The debugger is command line, and very good: hhvm -m debug

• Sara Golemon is giving a talk tomorrow night about HHVM and hack, and it will be live streamed:http://www.meetup.com/sf-php/events/159404382/

• Framework for Hack:https://wiki.pocketrent.com/beatbox/start

• I promise to blog about Hack at http://blog.vicmetcalfe.com/