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/


Top Related