Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving
Search
yuuki takezawa
September 04, 2018
Technology
3
2.3k
HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving
builderscon 2018 tokyo の資料です
yuuki takezawa
September 04, 2018
Tweet
Share
More Decks by yuuki takezawa
See All by yuuki takezawa
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
1.7k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
170
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
600
再考 アクターモデル/ reconsider actor model
ytake
0
1.3k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
500
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
310
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.2k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
870
技術的負債と向き合う取り組みでよかったもの / positive_efforts_to_tackle_technical_debt
ytake
10
3.9k
Other Decks in Technology
See All in Technology
Model Mondays S2E03: SLMs & Reasoning
nitya
0
350
「クラウドコスト絶対削減」を支える技術—FinOpsを超えた徹底的なクラウドコスト削減の実践論
delta_tech
4
140
整頓のジレンマとの戦い〜Tidy First?で振り返る事業とキャリアの歩み〜/Fighting the tidiness dilemma〜Business and Career Milestones Reflected on in Tidy First?〜
bitkey
2
14k
自律的なスケーリング手法FASTにおけるVPoEとしてのアカウンタビリティ / dev-productivity-con-2025
yoshikiiida
1
15k
生成AI時代の開発組織・技術・プロセス 〜 ログラスの挑戦と考察 〜
itohiro73
1
430
PO初心者が考えた ”POらしさ”
nb_rady
0
190
Flutter向けPDFビューア、pdfrxのpdfium WASM対応について
espresso3389
0
130
OSSのSNSツール「Misskey」をさわってみよう(右下ワイプで私のOSCの20年を振り返ります) / 20250705-osc2025-do
akkiesoft
0
140
品質と速度の両立:生成AI時代の品質保証アプローチ
odasho
1
210
AI導入の理想と現実~コストと浸透〜
oprstchn
0
190
What’s new in Android development tools
yanzm
0
220
fukabori.fm 出張版: 売上高617億円と高稼働率を陰で支えた社内ツール開発のあれこれ話 / 20250704 Yoshimasa Iwase & Tomoo Morikawa
shift_evolve
PRO
2
6.7k
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Agile that works and the tools we love
rasmusluckow
329
21k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Adopting Sorbet at Scale
ufuk
77
9.4k
BBQ
matthewcrist
89
9.7k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
950
Faster Mobile Websites
deanohume
307
31k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
48
5.4k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
500
Transcript
HHVM/HackͰಘΔղܾྗ yuuki takezawa builderscon 2018
Profile • ᖒ ༗و / ytake • גࣜձࣾΞΠελΠϧ CTO •
PHP, Hack, Go, Scala • Apache Hadoop, Apache Spark, Apache Kafka
ͱΓ͋͛Δ͜ͱ • ༷ʑͳղܾ • HackʹΑΔղܾ • ΞϓϦέʔγϣϯʹ͓͚Δղܾ
ղܾͱ • Λղܾ͢Δɺ ͢ͳΘͪղΛൃݟ͢Δ͜ͱͰ͋Γɺ ࢥߟͷҰ෦Ͱ͋Δ • νʔϜʹ͓͚ΔࢥߟͰ͋ͬͨΓ ΦϒδΣΫτࢦͰ͋ͬͨΓ
ͳͥHackΛ͏ͷ͔
എܠ • શମతʹPHPϝΠϯͷٕज़ελοΫ • WebΞϓϦέʔγϣϯ͕ϝΠϯ • GoͷΞϓϦέʔγϣϯ͍͔ͭ͘ • ੳॲཧScala͕͍͔ͭ͘
ݒ೦ • ͦΕ XX ͰͰ͖ΔΑ • ಛఆͷݴޠ͔͠Βͳ͍ • ։ൃͱ͍͏ߦҝʹΫϦΤΠςΟϒ͕͞ײ͡ΒΕͳ͍
બͷύϥυοΫε https://www.ted.com/talks/barry_schwartz_on_the_paradox_of_choice?language=ja
None
None
ΞϓϦέʔγϣϯ ϦϦʔε͢Δ·ͰͰͳ͘ɺ ϦϦʔε͔ͯ͠Β͕ຊ൪
։ൃऀ ΞϓϦέʔγϣϯͱͱʹ ͢Δ
None
։ൃͷଊ͑ํ • ͍ͭͷࢹͱগ͠ҧ͏ࢹΛՃͯ͠ΈΔ • ҧ͏ࢹͷ͋ͱɺ͍ͭͷݴޠ͔Β • ํʹಇ͘ݟ͑ํΛཆ͏͜ͱѱ͍͜ͱʁ • ͍ͭͷࢹ͚ͩɺѱ͍͜ͱʁ
None
None
ࢹΛม͑Δํ๏ͷҰͭͱͯ͠ HackΛར༻
PHP͕ ͪΐͬͱૣ͘ͳͬͨͭͰ͠ΐʁ
HHVM/Hack • ݴޠͷϕʔεʹ͋ΔͷPHPͷվળ • I/O͕ൃੜ͢Δͷʹରͯ͠ͷAsync/Await શͯʹରͯ͠࡞༻͢ΔΘ͚Ͱͳ͍ͷͰɺෑډ͕͍ • ݫ֨ͳܕνΣοΫͱίϨΫγϣϯɾ੬ऑੑରࡦ
for Developer • Atom + Nuclide • Visual Studio Code
+ Hack plugin • Docker (hhvm/hhvm)
.hhconfig
.hhconfig ͷجຊ • HackͰ࣮ߦڥʹઃஔ͢ΔϑΝΠϧ • ༷ʑͳઃఆΛهड़Ͱ͖Δ • PHPར༻Λఆ͠ͳ͍(PHPࠞࡏෆՄ) assume_php
= false(default: true) • Type Checker Ұ෦ແࢹ ignored_paths = [ "vendor/hhvm/hhast/.+" ]
.hhconfig ͋Ε͜Ε • λΠϓνΣοΧʔͷϝϞϦૢ࡞ • ࢀর͠͏ͳϞʔυՃ(3.28) disallow_return_by_ref disallow_array_cell_pass_by_ref
None
ۤ࿑ • IDEʹ͓͚Δิػೳͷಈ͖ • Τϥʔ༰͕Θ͔Βͳ͍ • PHPʹݟ͍͑ͯͯผͱ͍͏ೝࣝΛͭ·Ͱ • ใऩूྗ
Type Checker
None
Type Checker • ίϯύΠϥϥΠΫʹಈ͘ܕνΣοΫπʔϧ • Ϟʔυ3ͭ Partial / Strict /
Decl • σϑΥϧτͰPartial
Type Checker: Partial • PHPͷܕએݴ strictͱಉఔ • ඞཁҎ্ʹܕνΣοΫ͠ͳ͍ • ओʹPHPͷίʔυΛ
Hackͱ࣮ͯ͠ߦ͢Δ ίʔυҠ২தͷϑΝΠϧͰར༻ • ࢀর͠ ར༻Մೳ
Type Checker: Decl • <?hh // decl • ܕνΣοΫ͠ͳ͍ •
ଞͷίʔυνΣοΫ࣌ʹࢀর͞ΕΔ • New Hack code should never be written in decl mode
Type Checker: Strict • <?hh // strict • PHPґଘ͕ͳ͘ɺ100% HackͰ࣮͢Δ߹ʹબ
• ݫ֨ͳܕνΣοΫΛߦ͏ϞʔυͷͨΊɺ ίʔυϨϏϡʔ࣌ͷܕએݴʹ͍ͭͯͷٞඞཁ࠷খݶ • ఆ֎ͷܕมͳͲߦΘΕͳ͍ͨΊɺ ϨϏϡʔΫϥεઃܭɾΞʔΩςΫνϟͳͲʹ ϑΥʔΧεͰ͖Δ
for Example • ίϯετϥΫλͰॳظԽ͍ͯ͠ͳ͍ίʔυܯࠂ • isset͡Όͳͯ͘ɺarray_key_existsΛ͍ͳ͍͞ • ͨͩͷarray͡ΌΘ͔Βͳ͍ Vector͔Map͍ͳ͍͞
ߟ͑ํΛม͑Δ • ͱΓ͋͑ͣarray ͦͷarrayͲΜͳׂ͕͋ΓɺͲ͏͍͏ͷͳͷ͔ • arrayͰ͋Δඞཁ͕͋Δͷ͔Ͳ͏͔
Hackͷarrayࡾछྨ • array ௨ৗͷྻ • varray ͷΈͰߏ͞ΕΔྻ • darray σΟΫγϣφϦͷྻ
<?hh // strict class Sample { protected varray<string> $varray =
varray[ 'php', 'hack' ]; protected darray<int, string> $darray = darray[ 'testing' => 'testing', 1 => 'testing' ]; public function failedVArray(): varray<int> { return $this->varray; } public function getDArray(): darray<string, string> { return $this->darray; } } ܕҧ͍ Γܕҧ͍ Γܕҧ͍
ΞϓϦέʔγϣϯʹ͓͚Δ ղܾ
None
ܧঝΛ੍ޚ͢Δ • Sealed Class • Sealed Interface • Hack 3.27
Ҏ߱
<<__Sealed(Hoge::class)>> class SealedClass { } <<__Sealed(Sample::class)>> interface SealedInterface { }
ࢦఆͨ͠ΫϥεҎ֎ ܧঝෆՄ ࢦఆͨ͠ΫϥεҎ֎ ܧঝෆՄɾ࣮ෆՄ
ܧঝʹ͍ͭͯͷߟ͑ํ • final classͷΈͰ੍(ڐՄ)Λ͔͚Δ͔ • GenericsͰදݱͷΈڐՄ͢Δͷ͔ • ͦͷޙͷΞϓϦέʔγϣϯͷͱɺ ֦ுੑͰେ͖͘Ξϓϩʔν͕ҟͳΔ
ܕม
public function sum(): int { return 10 + "5e2"; }
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.
ܕม: mixed
public function get($id): mixed { return //Կ͔Λฦ٫͢Δ; } $container =
new Container(); $container->get('something');
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͚ʹهड़
final class Util { public function something(mixed $any): mixed {
if($any is int) { // } if($any is string) { // } } }
Type Constants
interface TypeInterface { abstract const type T; public function getNative():
this::T; }
class UserType implements TypeInterface { const type T = Vector<int>;
public function getNative(): this::T { return new Vector([1,2]); } }
Factory
class Sample { }
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ͳͲ
<<__ConsistentConstruct>> class Sample { } constructor੍ޚ
final class Factory { protected Map<string, classname<Sample>> $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จࣈྻࢦఆ ࣮֬ͳΠϯελϯεੜ
ࣝผͷҧ͍
final class BookId { private $id; public function __construct(string $id)
{ $this->id = $id; } public function getValue(): string { return $this->id; } }
final class BookId { public function __construct( private string $id
) {} public function getValue(): string { return $this->id; } }
ҧ͏දݱํ๏
abstract class Identifier<T> { public function __construct( protected T $id
) {} public function getValue(): T { return $this->id; } } final class BookId<T> extends Identifier<T> { } Generics
ॻ੶දݱํ๏
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; } // লུ }
class Book { public function __construct( private BookId<string> $id, private
BookTitle<string> $title, private Price<int> $price ) {} public function getId(): BookId<string> { return $this->id; } // লུ } ݎ੍͍ ݎ੍͍
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) }
ॻ੶ίϨΫγϣϯදݱํ๏
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; } } ϑΟʔϧυ੍ͳ͠
type BookShape = shape( 'book_id' => string, 'title' => string,
'price' => int ); ϑΟʔϧυ੍
class BookCollection { protected Vector<Book> $v = Vector{ }; public
function __construct( protected varray<BookShape> $array ) { $this->v = $this->vec(); } protected function vec(): Vector<Book> { $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<Book> { return $this->v->toVArray(); } } shapeΛvarrayͰ to Vector
$v = new Vector([ new Book('1234', 'testing', 2999), new Book('1235',
'testing', 2999), ]); $v = $v->filter( ($t) ==> $t->getId() === '1234' )->immutable(); collection filter Πϛϡʔλϒϧʹ
ෳҙຯΛ࣋ͨͤͳ͍ͨΊͷ੍ޚ • ߹ͷ͍͍ΫϥεΛ࡞Βͳ͍ • ूΛΑΓߟ͑Δ • ͳΜͰͰ͖ΔΫϥεͰͳ͍ ͜Ε͔͠Ͱ͖ͳ͍Ϋϥε
ݫ֨ͳܕΛPHPΞϓϦέʔγϣϯʹద༻͢Δҙຯ • ͱΓ͋͑ͣಈ͘ঢ়ଶʹͰ͖Ε͍͍ • ༷มߋ͕͋Εܕ͕ͳ͍ํ͕ଟ༷ੑ͋ΔΜ͡Όͳ͍ʁ • ͦͦଞͷݴޠͰΑ͘ͳ͍ʁ
ͱΓ͋͑ͣಈ͘ঢ়ଶ͔Β ៉ྷʹ͢Δ࣌ؒͳ͔ͳ͔དྷͳ͍
None
બࢶͱࢹΛ͛Δ
Λղܾ͢Δɺ ͢ͳΘͪղΛൃݟ͢Δ͜ͱͰ͋Γɺ ࢥߟͷҰ෦
ղܾ͢ΔͨΊͷྗͱ ࢹ