Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving

HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving

builderscon 2018 tokyo の資料です

yuuki takezawa

September 04, 2018
Tweet

More Decks by yuuki takezawa

Other Decks in Technology

Transcript

  1. HHVM/HackͰಘΔ໰୊ղܾྗ
    yuuki takezawa
    builderscon 2018

    View Slide

  2. Profile
    • ஛ᖒ ༗و / ytake
    • גࣜձࣾΞΠελΠϧ CTO
    • PHP, Hack, Go, Scala
    • Apache Hadoop, Apache Spark, Apache Kafka


    View Slide

  3. ͱΓ͋͛Δ͜ͱ
    • ༷ʑͳ໰୊ղܾ
    • HackʹΑΔ໰୊ղܾ
    • ΞϓϦέʔγϣϯʹ͓͚Δ໰୊ղܾ

    View Slide

  4. ໰୊ղܾͱ͸
    • ໰୊Λղܾ͢Δɺ

    ͢ͳΘͪղΛൃݟ͢Δ͜ͱͰ͋Γɺ

    ࢥߟͷҰ෦෼Ͱ͋Δ
    • νʔϜʹ͓͚ΔࢥߟͰ͋ͬͨΓ

    ΦϒδΣΫτࢦ޲Ͱ͋ͬͨΓ

    View Slide

  5. ͳͥHackΛ࢖͏ͷ͔

    View Slide

  6. എܠ
    • શମతʹ͸PHPϝΠϯͷٕज़ελοΫ
    • WebΞϓϦέʔγϣϯ͕ϝΠϯ
    • Go੡ͷΞϓϦέʔγϣϯ΋͍͔ͭ͘
    • ෼ੳॲཧ͸Scala੡͕͍͔ͭ͘

    View Slide

  7. ݒ೦
    • ͦΕ XX Ͱ΋Ͱ͖ΔΑ

    • ಛఆͷݴޠ͔͠஌Βͳ͍
    • ։ൃͱ͍͏ߦҝʹΫϦΤΠςΟϒ͕͞ײ͡ΒΕͳ͍

    View Slide

  8. બ୒ͷύϥυοΫε
    https://www.ted.com/talks/barry_schwartz_on_the_paradox_of_choice?language=ja

    View Slide

  9. View Slide

  10. View Slide

  11. ΞϓϦέʔγϣϯ͸
    ϦϦʔε͢Δ·ͰͰ͸ͳ͘ɺ
    ϦϦʔε͔ͯ͠Β͕ຊ൪

    View Slide

  12. ։ൃऀ͸
    ΞϓϦέʔγϣϯͱͱ΋ʹ
    ੒௕͢Δ

    View Slide

  13. View Slide

  14. ։ൃͷଊ͑ํ
    • ͍ͭ΋ͷࢹ఺ͱগ͠ҧ͏ࢹ఺Λ௥Ճͯ͠ΈΔ
    • ҧ͏ࢹ఺ͷ͋ͱɺ͍ͭ΋ͷݴޠ͔Β
    • ૒ํ޲ʹಇ͘ݟ͑ํΛཆ͏͜ͱ͸ѱ͍͜ͱʁ
    • ͍ͭ΋ͷࢹ఺͚ͩɺ͸ѱ͍͜ͱʁ

    View Slide

  15. View Slide

  16. View Slide

  17. ࢹ఺Λม͑Δํ๏ͷҰͭͱͯ͠
    HackΛར༻

    View Slide

  18. PHP͕
    ͪΐͬͱૣ͘ͳͬͨ΍ͭͰ͠ΐʁ

    View Slide

  19. HHVM/Hack
    • ݴޠͷϕʔεʹ͋Δͷ͸PHPͷվળ
    • I/O͕ൃੜ͢Δ΋ͷʹରͯ͠ͷAsync/Await

    શͯʹରͯ͠࡞༻͢ΔΘ͚Ͱ͸ͳ͍ͷͰɺෑډ͕௿͍

    • ݫ֨ͳܕνΣοΫͱίϨΫγϣϯɾ੬ऑੑରࡦ

    View Slide

  20. for Developer
    • Atom + Nuclide
    • Visual Studio Code + Hack plugin
    • Docker (hhvm/hhvm)

    View Slide

  21. .hhconfig

    View Slide

  22. .hhconfig ͷجຊ
    • HackͰ࣮ߦ؀ڥʹઃஔ͢ΔϑΝΠϧ
    • ༷ʑͳઃఆΛهड़Ͱ͖Δ
    • PHPར༻Λ૝ఆ͠ͳ͍(PHPࠞࡏෆՄ) 

    assume_php = false(default: true)

    • Type Checker Ұ෦ແࢹ

    ignored_paths = [ "vendor/hhvm/hhast/.+" ]

    View Slide

  23. .hhconfig ͋Ε͜Ε
    • λΠϓνΣοΧʔͷϝϞϦૢ࡞

    • ࢀর౉͠࢖͏ͳϞʔυ΋௥Ճ(3.28)

    disallow_return_by_ref

    disallow_array_cell_pass_by_ref

    View Slide

  24. View Slide

  25. ۤ࿑
    • IDEʹ͓͚Δิ׬ػೳͷಈ͖

    • Τϥʔ಺༰͕Θ͔Βͳ͍
    • PHPʹݟ͍͑ͯͯผ෺ͱ͍͏ೝࣝΛ΋ͭ·Ͱ
    • ৘ใऩूྗ

    View Slide

  26. Type Checker

    View Slide

  27. View Slide

  28. Type Checker
    • ίϯύΠϥϥΠΫʹಈ͘ܕνΣοΫπʔϧ
    • Ϟʔυ͸3ͭ Partial / Strict / Decl 

    • σϑΥϧτͰ͸Partial

    View Slide

  29. Type Checker: Partial
    • PHPͷܕએݴ strictͱಉఔ౓
    • ඞཁҎ্ʹܕνΣοΫ͸͠ͳ͍
    • ओʹPHPͷίʔυΛ Hackͱ࣮ͯ͠ߦ͢Δ

    ίʔυҠ২தͷϑΝΠϧ౳Ͱར༻
    • ࢀর౉͠ ར༻Մೳ

    View Slide

  30. Type Checker: Decl
    • • ܕνΣοΫ͸͠ͳ͍
    • ଞͷίʔυνΣοΫ࣌ʹ͸ࢀর͞ΕΔ
    • New Hack code should never be written 

    in decl mode

    View Slide

  31. Type Checker: Strict
    • • PHPґଘ͕ͳ͘ɺ100% HackͰ࣮૷͢Δ৔߹ʹબ୒
    • ݫ֨ͳܕνΣοΫΛߦ͏ϞʔυͷͨΊɺ

    ίʔυϨϏϡʔ࣌ͷܕએݴʹ͍ͭͯͷٞ࿦͸ඞཁ࠷খݶ
    • ૝ఆ֎ͷܕม׵ͳͲ͸ߦΘΕͳ͍ͨΊɺ

    ϨϏϡʔ͸ΫϥεઃܭɾΞʔΩςΫνϟͳͲʹ

    ϑΥʔΧεͰ͖Δ

    View Slide

  32. for Example
    • ίϯετϥΫλͰॳظԽ͍ͯ͠ͳ͍ίʔυ͸ܯࠂ
    • isset͡Όͳͯ͘ɺarray_key_existsΛ࢖͍ͳ͍͞
    • ͨͩͷarray͡ΌΘ͔Βͳ͍ Vector͔Map࢖͍ͳ͍͞

    View Slide

  33. ߟ͑ํΛม͑Δ
    • ͱΓ͋͑ͣarray

    ͦͷarray͸ͲΜͳ໾ׂ͕͋ΓɺͲ͏͍͏΋ͷͳͷ͔
    • arrayͰ͋Δඞཁ͕͋Δͷ͔Ͳ͏͔

    View Slide

  34. Hackͷarray͸ࡾछྨ
    • array

    ௨ৗͷ഑ྻ
    • varray

    ஋ͷΈͰߏ੒͞ΕΔ഑ྻ
    • darray

    σΟΫγϣφϦͷ഑ྻ

    View Slide

  35. class Sample {
    protected varray $varray = varray[
    'php',
    'hack'
    ];
    protected darray $darray = darray[
    'testing' => 'testing',
    1 => 'testing'
    ];
    public function failedVArray(): varray {
    return $this->varray;
    }
    public function getDArray(): darray {
    return $this->darray;
    }
    }
    ܕҧ͍
    ໭Γܕҧ͍
    ໭Γܕҧ͍

    View Slide

  36. ΞϓϦέʔγϣϯʹ͓͚Δ
    ໰୊ղܾ

    View Slide

  37. View Slide

  38. ܧঝΛ੍ޚ͢Δ
    • Sealed Class
    • Sealed Interface
    • Hack 3.27 Ҏ߱

    View Slide

  39. <<__Sealed(Hoge::class)>>
    class SealedClass {
    }
    <<__Sealed(Sample::class)>>
    interface SealedInterface {
    }
    ࢦఆͨ͠ΫϥεҎ֎
    ܧঝෆՄ
    ࢦఆͨ͠ΫϥεҎ֎
    ܧঝෆՄɾ࣮૷ෆՄ

    View Slide

  40. ܧঝʹ͍ͭͯͷߟ͑ํ
    • final classͷΈͰ੍໿(ڐՄ)Λ͔͚Δ͔

    • GenericsͰ஋දݱͷΈڐՄ͢Δͷ͔

    • ͦͷޙͷΞϓϦέʔγϣϯͷ੒௕ͱɺ

    ֦ுੑͰେ͖͘Ξϓϩʔν͕ҟͳΔ

    View Slide

  41. ܕม׵

    View Slide

  42. public function sum(): int
    {
    return 10 + "5e2";
    }

    View Slide

  43. public function sum(): int
    {
    return 10 + "5e2";
    }
    Typing error
    This is a num (int/float) because
    this is used in an arithmetic
    operation.
    It is incompatible with a string.

    View Slide

  44. ܕม׵: mixed

    View Slide

  45. public function get($id): mixed
    {
    return //Կ͔Λฦ٫͢Δ;
    }
    $container = new Container();
    $container->get('something');

    View Slide

  46. private function invariantLoggerInterface(
    Container $container,
    ): LoggerInterface {
    $logger = $container
    ->get(LoggerInterface::class);
    invariant(
    $logger instanceof LoggerInterface,
    "Interface '\Psr\Log\LoggerInterface' is not
    implemented by this class",
    );
    return $logger;
    }
    mixedͷ৔߹͸Կ͕ฦ٫͞ΕΔ͔Θ͔Βͳ͍
    ظ଴஋ͷ΋ͷ͕ฦ٫͞ΕΔ͔Ͳ͏͔
    ඞͣهड़ͯ͠ɺTypeChecker޲͚ʹهड़

    View Slide

  47. final class Util {
    public function something(mixed $any): mixed {
    if($any is int) {
    //
    }
    if($any is string) {
    //
    }
    }
    }

    View Slide

  48. Type Constants

    View Slide

  49. interface TypeInterface {
    abstract const type T;
    public function getNative(): this::T;
    }

    View Slide

  50. class UserType implements TypeInterface {
    const type T = Vector;
    public function getNative(): this::T {
    return new Vector([1,2]);
    }
    }

    View Slide

  51. Factory

    View Slide

  52. class Sample
    {
    }

    View Slide

  53. final class Factory
    {
    protected array $array = [
    'Sample' => Sample::class
    ];
    public function get(string $id)
    {
    $key = \ucfirst(\strtolower($id));
    if(\array_key_exists($key, $this->array)) {
    $class = $this->array[$key];
    return new $class();
    }
    }
    }
    class_existsͳͲ΋

    View Slide

  54. <<__ConsistentConstruct>>
    class Sample {
    }
    constructor੍ޚ

    View Slide

  55. final class Factory {
    protected Map> $map = Map{
    'Sample' => Sample::class
    };
    public function get(string $id): Sample {
    $class = $this->map->get(\ucfirst(\strtolower($id)));
    if (!\is_null($class)) {
    return new $class();
    }
    throw new \RuntimeException();
    }
    }
    classจࣈྻࢦఆ
    ࣮֬ͳΠϯελϯεੜ੒

    View Slide

  56. ࣝผͷҧ͍

    View Slide

  57. final class BookId
    {
    private $id;
    public function __construct(string $id)
    {
    $this->id = $id;
    }
    public function getValue(): string
    {
    return $this->id;
    }
    }

    View Slide

  58. final class BookId {
    public function __construct(
    private string $id
    ) {}
    public function getValue(): string {
    return $this->id;
    }
    }

    View Slide

  59. ҧ͏දݱํ๏

    View Slide

  60. abstract class Identifier {
    public function __construct(
    protected T $id
    ) {}
    public function getValue(): T {
    return $this->id;
    }
    }
    final class BookId extends Identifier {
    }
    Generics

    View Slide

  61. ॻ੶දݱํ๏

    View Slide

  62. class Book
    {
    private $id;
    private $title;
    private $price;
    public function __construct(
    BookId $id,
    BookTitle $title,
    Price $price
    ) {
    $this->id = $id;
    $this->title = $title;
    $this->price = $price;
    }
    public function getId(): BookId {
    return $this->id;
    }
    // লུ
    }

    View Slide

  63. class Book {
    public function __construct(
    private BookId $id,
    private BookTitle $title,
    private Price $price
    ) {}
    public function getId(): BookId {
    return $this->id;
    }
    // লུ
    }
    ݎ੍͍໿
    ݎ੍͍໿

    View Slide

  64. object(Book)#2 (3) {
    ["id":"Book":private]=>
    object(BookId)#3 (1) {
    ["id":protected]=>
    string(36) "6ad4bb95-262c-4a5b-a6c7-ac9b5cadf707"
    }
    ["title":"Book":private]=>
    string(18) "HHVM/Hack Practice"
    ["price":"Book":private]=>
    int(2999)
    }

    View Slide

  65. ॻ੶ίϨΫγϣϯදݱํ๏

    View Slide

  66. class BookCollection
    {
    protected $books = [];
    public function __construct(array $books = [])
    {
    $this->books = $books;
    }
    public function toArray(): array {
    $books = [];
    foreach($this->books as $book) {
    $books[] = new Book(
    new BookId($book['id']),
    new BookTitle($book['title']),
    new Price($book['price'])
    );
    }
    return $books;
    }
    }
    ϑΟʔϧυ੍໿ͳ͠

    View Slide

  67. type BookShape = shape(
    'book_id' => string,
    'title' => string,
    'price' => int
    );
    ϑΟʔϧυ੍໿

    View Slide

  68. class BookCollection {
    protected Vector $v = Vector{ };
    public function __construct(
    protected varray $array
    ) {
    $this->v = $this->vec();
    }
    protected function vec(): Vector {
    $v = Vector{ };
    foreach($this->array as $row) {
    $v->add(new Book(
    new BookId($row['book_id']),
    new BookTitle($row['title']),
    new Price($row['price'])
    ));
    }
    return $v;
    }
    public function toArray(): varray {
    return $this->v->toVArray();
    }
    }
    shapeΛvarrayͰ
    to Vector

    View Slide

  69. $v = new Vector([
    new Book('1234', 'testing', 2999),
    new Book('1235', 'testing', 2999),
    ]);
    $v = $v->filter(
    ($t) ==> $t->getId() === '1234'
    )->immutable();
    collection filter
    Πϛϡʔλϒϧʹ

    View Slide

  70. ෳ਺ҙຯΛ࣋ͨͤͳ͍ͨΊͷ੍ޚ
    • ౎߹ͷ͍͍ΫϥεΛ࡞Βͳ͍

    • ू໿ΛΑΓߟ͑Δ

    • ͳΜͰ΋Ͱ͖ΔΫϥεͰ͸ͳ͍

    ͜Ε͔͠Ͱ͖ͳ͍Ϋϥε

    View Slide

  71. ݫ֨ͳܕΛPHPΞϓϦέʔγϣϯʹద༻͢Δҙຯ
    • ͱΓ͋͑ͣಈ͘ঢ়ଶʹͰ͖Ε͹͍͍
    • ࢓༷มߋ͕͋Ε͹ܕ͕ͳ͍ํ͕ଟ༷ੑ͋ΔΜ͡Όͳ͍ʁ
    • ͦ΋ͦ΋ଞͷݴޠͰΑ͘ͳ͍ʁ

    View Slide

  72. ͱΓ͋͑ͣಈ͘ঢ়ଶ͔Β

    ៉ྷʹ͢Δ࣌ؒ͸ͳ͔ͳ͔དྷͳ͍

    View Slide

  73. View Slide

  74. બ୒ࢶͱࢹ໺Λ޿͛Δ

    View Slide

  75. ໰୊Λղܾ͢Δɺ

    ͢ͳΘͪղΛൃݟ͢Δ͜ͱͰ͋Γɺ

    ࢥߟͷҰ෦෼

    View Slide

  76. ղܾ͢ΔͨΊͷྗͱ
    ࢹ໺

    View Slide