an elephant of a different colour: hack

Post on 11-May-2015

1.300 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

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

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.

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

HackXHP

Async

Collections

Lambda

Types

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>

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>

XHP

• Available for Zend PHP too!

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

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

CollectionsVector

Map

Set

Pair

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

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

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

‘Apples’,‘Bananas’‘Oranges’

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”

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

Vectors

• Always 0 .. (count -1)

• Values are not hashed / indexed

• Use Sets for this

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

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);

Pair

• Pairs must contain two items of any type

• Pairs are always immutable

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

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);

Map

• Maps contain key / value Pairs

• Keys can only be integers or strings

• Values can be of any type

• Order is preserved

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);

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

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)}

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)}

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)}

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) !

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

Types<?hhclass MyClass<T as SomeInterface> {

function __construct(private T $v) {}}

newtype Secret as BaseClass = MyClass;

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"}

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);

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)

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

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

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

)

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

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

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.

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