Ada 202x (14日目) - Unify record syntax ======================================= .. post:: Dec 14, 2019 :tags: ada, ada_2022 タイトルはAda 2012 Issues(以降AI)のまんまです。 経緯 ---- 他の構文と異なり ``record`` は ``end`` の後に名前を書けませんでした。 .. code-block:: ada type Rec is record E : Integer; end record; -- ここに "Rec" と書けませんでした Ada 202xでの改善 ---------------- 書けるようになりました。 .. code-block:: ada type Rec is record E : Integer; end record Rec; 関連AI ------ - `AI12-0213-1`_ **Unify record syntax** 所感 ---- このAI、提出者がJustin Squirekさんです。 (発案はTucker先生のようです。) Justinさんはgithubの https://github.com/AdaDoom3/ さんです。 数年前にAdaCore社に就職されたと聞いております。 感慨深く。 どうインデントすればいいのか? ------------------------------ めでたしめでたし、で済ませたいのです。 はい、例によって書いておきたいことが。 機能ではなくコーディングスタイル、ただの長い行の折り返し方の話、かつ100%私見ですので読むだけ損です。 正直私にはJean Ichbiah先生率いる初代Ada 83を策定したチームがこんなのを見逃したとは思えないわけですよ。 裏付けはありませんが ``record`` に名前を続けられないのはわざとそうしていたのではと推測しています。 他にAda 83から存在する ``end`` の後に名前を続けられる構文を見てみましょう。 | http://archive.adaic.com/standards/83lrm/html/ada_lrm.html | http://archive.adaic.com/standards/83rat/html/ratl-02-02.html | http://archive.adaic.com/docs/style-guide/83style/html/sty-02.html パッケージ。 .. code-block:: ada package Pack1 is -- declarations end Pack1; サブプログラム。``procedure`` 、 ``function`` 、 ``entry`` 。 .. code-block:: ada procedure Proc1 is -- declarations begin null; end Proc1; ``task`` 。 .. code-block:: ada task Task1 is -- declarations end Task1; .. code-block:: ada task type Task1 is -- declarations end Task1; .. code-block:: ada task body Task1 is -- declarations begin null; end Task1; ブロック文。 .. code-block:: ada Label: begin null; end Label; .. code-block:: ada Label: declare -- declarations begin null; end Label; ループ文。 .. code-block:: ada Label: loop null; end loop Label; accept文。 .. code-block:: ada accept Entry1 do -- 新規宣言ではなく既存のentry名 null; end Entry1; 以上です。 そして ``record`` の「本来の」インデントはこうです。 .. code-block:: ada type Rec is record E : Integer; end record; 他にはAda 95からの ``protected`` も ``end`` の後に名前を続けられます。 Ada 2005からの拡張return文は識別子の宣言を伴いますが ``end`` の後に名前は続けられません。 基本的に先頭行と ``end`` の行が揃うようになっています。 例外はブロック文、ループ文、``record`` で本体が名前よりも1段深くインデントされます。 (Rationaleを見ますとループ文と ``record`` が例外なのは認識されています。) このうち宣言文なのは ``record`` のみです。 ``task type`` 同様に ``record type`` のような文法でしたら ``end`` の行を先頭行に揃えるべきでしょう。 そうなっていないという事は ``record`` は他の型宣言同様に ``is`` 以降でひと塊と考えるべきです。 そう考えると本体を1段深くするインデントルールも納得できますし ``end`` に名前を続けないのも理解できます。 このインデントルールはAda 95以降の ``tagged record`` や ``interface`` を継承するために長くなった宣言にも良く合致します。 .. code-block:: ada type Rec_Having_Long_Declaration is abstract new Ada.Finalization.Limited_Controlled and Ada.Iterator_Interfaces.Forwared_Iterator with record E : Integer; end record; 或いは ``is`` から ``with`` までをAda 2005以降の ``protected`` が ``interface`` を継承する場合の構文に倣うことも考えられます。 .. code-block:: ada protected Long_Long_Protected_Name is new Long_Long_Package_Name.Long_Long_Interface_Name_1 and Long_Long_Package_Name.Long_Long_Interface_Name_2 with -- declarations end Long_Long_Protected_Name; この ``with`` は継承の終わりかつ宣言の開始を意味する区切りで ``tagged record`` を継承する用法に近いです。 個人的には区切りを明確にするために(``procedure`` の引数リストが長くなった後の ``is`` 同様に)この ``with`` の前で改行したくなりますが、しないのが主流っぽいです? (``protected`` の継承だけでもマイナーなのに改行するほど長くなった例なんて更に少ないのでよくわかりません。) 要は ``with`` を区切りに継承部分のインデントを後に影響させないということです。 ``record`` を1段だけインデントするのは前提としますとこうでしょうか。 .. code-block:: ada type Rec_Having_Long_Declaration is abstract new Ada.Finalization.Limited_Controlled and Ada.Iterator_Interfaces.Forwared_Iterator with record E : Integer; end record; 何れにせよこのインデントされた ``end`` の後ろに名前を続けるのって変じゃないですか? しかもAda 2012以降はアスペクトを追加すると ``end`` が最終行ですらなくなります。 .. code-block:: ada type Rec_Having_Long_Declaration is abstract new Ada.Finalization.Limited_Controlled and Ada.Iterator_Interfaces.Forwared_Iterator with record E : Integer; end record Rec_Having_Long_Declaration -- 次の行に続く with Pack; -- アスペクト これを ``end`` 行を先頭行に揃えようとしますとこうなってしまいます。 .. code-block:: ada type Rec_Having_Long_Declaration is abstract new Ada.Finalization.Limited_Controlled and Ada.Iterator_Interfaces.Forwared_Iterator with record E : Integer; end record Rec_Having_Long_Declaration with Pack; またはアスペクトに合わせて ``with`` の前で折り返しますと .. code-block:: ada type Rec_Having_Long_Declaration is abstract new Ada.Finalization.Limited_Controlled and Ada.Iterator_Interfaces.Forwared_Iterator with record E : Integer; end record Rec_Having_Long_Declaration with Pack; うーん? と、まあ、このようなことを書いて悩むふりをしつつ実は私は元から ``end`` を先頭行に揃える派なのですけどね。 宣言の長さで要素のインデントが左右されませんので。 コーディングスタイル違反を自覚していたのですが、まさか間接に正当化されるとはびっくりです。 (されてないされてない。) ちなみにGNATのソースには様々なスタイルが混じってたりします。 それでも私は今更 ``end record`` の後に名前を書き足したりはしないとは思います。 恐らく誰も書かないのではないでしょうか。 やっぱり今更ですよ。 Pascal系言語は他ほどインデントに迷わないのも利点と思っています。 この変更は迷うポイントを追加する変更であることは間違いありません。 .. _`AI12-0213-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0213-1.txt