$30 off During Our Annual Pro Sale. View Details »

なぜPHPにはEnumがないのか

 なぜPHPにはEnumがないのか

Takayuki Fujisawa

October 30, 2019
Tweet

More Decks by Takayuki Fujisawa

Other Decks in Programming

Transcript

  1. なぜPHP
    にはEnum
    がないのか
    @miracle_fjsw
    1

    View Slide

  2. whoami
    $iam = [
    "
    名前" => "Takayuki Fujisawa",
    "
    会社" => "
    株式会社ラクス",
    "
    仕事" => ["R&D", "
    技術広報, "
    エンジニアリングカルチャー促進", "PMO"],
    "
    トゥイッター" => "@miracle_fjsw"
    ]
    2

    View Slide

  3. 「PHP
    にはEnum
    がない」と嘆く⼈が⼀定数いる
    3

    View Slide

  4. ⼤体「厳密な型付けのためのEnum
    がない」という⽂脈で⾔われ
    ているケースが多いようです
    以下、「厳密な型付けのためのEnum
    」という⽂脈で語ります。
    4

    View Slide

  5. Enum
    って何よ
    列挙型(enumration type)
    いーなむ、いにゅーむ、えなむ…
    列挙型とは、データベースやプログラミング⾔語などにおけるデータ型の⼀つで、
    複数の異なる定数を⼀つの集合として定義するもの。多くの⾔語では “enum”
    の略号で⽰される。
    こういうやつ
    enum Planet {
    MERCURY, VENUS, EARTH, MARS, ...
    }
    5

    View Slide

  6. Enum
    があると何が嬉しいのか
    定数をただの数値や⽂字列ではなく意味を持った集合として定義できる
    6

    View Slide

  7. Enum
    がない場合こうなる
    function distance(int from_planet_id, int dist_planet_id) {
    //
    処理
    }
    7

    View Slide

  8. Enum
    がない場合こうなる
    const PLANET_ID_MERCURY = 1;
    const PLANET_ID_VENUS = 2;
    const PLANET_ID_EARTH = 3;
    const PLANET_ID_MARS = 4;
    ////
    $distance = distance(PLANET_ID_MERCURY, PLANET_ID_VENUS);
    8

    View Slide

  9. Enum
    がない場合こうなる
    $distance = distance(PLANET_ID_MERCURY, PLANET_ID_VENUS);
    PLANET_ID_xxx
    はあくまで、ラベルをつけただけで内部的にはただの整数値
    distance(1, 2);
    これでも呼び出せる
    distance(1, 100000);
    これでも呼び出せる
    distance(OTHER_CONSTANT_A, OTHER_CONSTANT_B);
    これでも呼び出せる
    メソッドを使う⼈がちゃんと使ってくれることを祈るしかない
    PHPDoc
    やドキュメントなどで使い⽅の説明をしなければならない
    内部での⼊⼒値チェックを⾏わなければならない
    9

    View Slide

  10. Enum
    があればこうできる
    enum Planet {
    MERCURY, VENUS, EARTH, MARS, ...
    }
    function distance(Planet from, Planet dist) {
    //
    処理
    }
    $distance = distance(Planet::MERCURY, Planet::VENUS);
    メソッドの仕様がコードをみるだけで⼀⽬瞭然
    型が縛られるため、Planet
    で定義した要素以外渡ってこない(安全)
    コードはいかにその仕様や概念を読み⼿に伝えるかが重要
    定数によって管理されているそれはどこまで⾏っても数値や⽂字列でしかない
    Enum
    を使うことで意味‧概念をそのまま表現できる
    他にも、返却値をboolean
    や定数ではなく、Enum
    で表現したり⾊々便利
    10

    View Slide

  11. なぜPHP
    にはEnum
    がないのか
    11

    View Slide

  12. 実はPHP
    にもEnum
    はあります
    12

    View Slide

  13. PHP
    にもEnum
    はあります
    SplEnum
    Standart PHP Libraly
    を冠している割に本体に未だ統合されず、「実験的」のまま
    13

    View Slide

  14. PHP
    にもEnum
    はあります
    サードパーティ製
    myclabs/php-enum
    『SplEnum
    が本体に統合されてないから作りました』
    BenSampo/laravel-enum
    「php enum
    」で検索すると⼤量の「作ってみました」系記事
    14

    View Slide

  15. Enum
    が欲しいという要望は多いものの、標準仕様には未採⽤
    15

    View Slide

  16. RFC
    を⾒てみよう
    2015
    年に提案があるものの、未だドラフト。
    16

    View Slide

  17. RFC
    を⾒てみよう
    もっと古いのもあるが、議論中で⽌まっている
    17

    View Slide

  18. どうなってるの?
    18

    View Slide

  19. この謎を解くべく、過去のディスカッションの中⾝を追う
    PHP
    コミュニティのメーリングリスト
    https://externals.io/
    Enum
    関連で盛り上がっているスレッドが2
    本(2012
    年,2015
    年)
    2012
    年の議論は凄まじい激論
    2012
    年というとPHP5.4
    くらい
    すでにタイプヒンティング(引数の型指定 ※)などは導⼊されておりPHP

    型付けを意識しはじめている段階
    ※ …
    クラス/
    インタフェース、配列のみ。int
    やstring
    などのスカラ型は⾮対
    応。
    19

    View Slide

  20. 2012
    年の議論を超意訳して抜粋
    Enum
    要らない派の猛攻
    PHP
    は緩い型付けの⾔語なんや。便利なシーンも多いやろ。
    厳密な型付けは実⾏時の速度を落とすからアカン。
    そもそもコンパイル⾔語じゃないから厳密に型をしばったところで、事前に
    ⾒つけられへん。ボンクラが間違った実装しとったら実⾏時に落ちるやろ。
    厳密な型付けが欲しい?Java
    使えば?
    厳密さが欲しい⼈ばっかりやないねん。⾃分が正しいみたいに⾔うなや。
    という泥沼感のある議論が、なんだかよくわからないうちにストップ
    20

    View Slide

  21. 実際、Enum
    は必要なのか?
    便利で強⼒はあるが「必ず要る」わけではない。
    クラスを使って同じことが実現できる。
    class Planet { ... }
    class Mercury extends Planet { ... }
    class Venus extends Planet { ... }
    class Earth extends Planet { ... }
    function distance(Planet from, Planet dist) {
    //
    処理
    }
    $distance = distance(Mercury::getInstance(), Venus::getInstance());
    当時のPHP
    コミュニティの⼈たちの意⾒も理解できる。
    21

    View Slide

  22. ところが、2015
    年の議論では⾵向きが変わる
    突如「Enum
    について議論しようず!」というスレが⽴つ
    2015
    年というとPHP7
    のリリース。
    厳密な型判定(strict
    )モードの追加
    スカラ型宣⾔の機能追加(引数の型にint
    やstring
    などを指定できる)
    現在ドラフト中のRFC
    が作られたのもこの時期
    22

    View Slide

  23. 2015
    年の議論
    2012
    年とは違い、PHP
    に組み込むとしたらどのような仕様が良いのかが前向きに
    議論されている
    Enum
    に振る舞いをもたせる必要あるか(※)、とか、シリアライズする時どうす
    るの、とか
    ※C++
    などのEnum
    は定数の集合だが、Java
    のEnum
    はクラスの亜種であり、メ
    ソッドを持てる
    PHP
    に組み込む上での実装上の問題についての議論なども
    過去に⾒られた「Enum
    要らない派」がほとんどいない
    23

    View Slide

  24. つまり…
    PHP
    はもともと緩い型付けで柔軟に記述できる⾔語
    これは別の視点ではあまり深く考えずにサクッと作れる強⼒な⾔語、とも⾔
    える
    PHP
    の⽣みの親であるラスマス‧ラードフの⾔からも窺い知れる
    『PHP
    は問題を解決するシンプルなツール以上のものではない』
    実際そうだし、だからこそ広く愛⽤されるに⾄った⾔語。
    24

    View Slide

  25. つまり…
    かつてはEnum
    のような厳密に型を意識したいというアプローチは受け⼊れられに
    くかった
    そもそも必要としている⼈ばかりではなかった(代替⼿段もあるし)
    ⼀⽅で、ここ数年では徐々にコミュニティの考え⽅が変わってきており、PHP

    体が型を意識した⾔語に変容している
    現在はその過渡期であり、完全にEnum
    採⽤が棄却されたわけではない
    25

    View Slide

  26. という資料をまとめていた折
    Union Types
    が投票フェーズに(現状賛成⼤多数)
    こういうやつ
    public function setNumber(int|float $number): void {
    $this->number = $number;
    }
    public function getNumber(): int|float {
    return $this->number;
    }
    26

    View Slide

  27. UnionTypes
    は2015
    年に⼀度ポシャっている
    てことは、Enum
    もワンチャンあるで!
    27

    View Slide

  28. xdebug
    の開発者であり、RFC
    の投票者でもあるDerick Rethans
    のツイート
    「Enum
    の議論⽌まってるみたいやけど、なんか詳しいこと知ってます?」という
    問に対し
    「あんま知らんけど、UnionTypes
    がマージされたらもっかい⾒なアカンね」
    28

    View Slide

  29. PHP
    にEnum
    が来る⽇はそんなに遠くない…

    29

    View Slide

  30. なぜPHP
    にはEnum
    がないのか
    @miracle_fjsw
    30

    View Slide

  31. なぜ今はPHP
    にはEnum
    がないのか
    @miracle_fjsw
    31

    View Slide

  32. 以上。
    32

    View Slide