Ada 202x (49日目) - 4月29日の電子会議の結果¶
4月29日に行われた電子会議の議事録が公開されました。
genericの型引数のデフォルト¶
genericパッケージに引数を追加する場合のことを考えてみます。
generic
type Element_Type is private;
package G1 is
type Array_Type is array (Positive range <>) of Element_Type;
end G1;
このパッケージにいろいろ引数を追加してみます。
generic
type Element_Type is private;
type Index_Type is range <>;
procedure Swap (Left, Right : in out Element_Type) is <>;
Max_Index : Index_Type := Index_Type'Last;
package G2 is
type Array_Type is array (Index_Type range <>) of Element_Type;
procedure Swap (Left, Right : in out Array_Type_Type);
end G2;
サブプログラムと値に関してはデフォルトを設定できます。
この場合 Element_Type
を引数に取る Swap
が存在していれば実引数として明記しなくてもそれを使ってくれますし、Max_Index
にしても明記しなくても Index_Type'Last
が使われます。
デフォルトにより使う側の変更を抑えることができます。
しかし型にデフォルトは設定できませんでした。
従来 Positive
としていたものをより一般化のために型引数 Index_Type
に置き換えてしまいますと使う側も全ての箇所に実引数を足す必要がありました。
この度、型引数にもデフォルトを設定できるようになりました。 Ada 2005制定の頃から欲しがられていたやつです。 とうとう入りました。
generic
type Element_Type is private;
type Index_Type is range <> or use Positive;
package G3 is
type Array_Type is array (Index_Type range <>) of Element_Type;
end G3;
これで、型引数を追加しても使う側に実引数を足さずに済むようになります。
構文は or use
です。
なんでしょうね use
を再利用するの流行ってるのでしょうか。
後はデフォルトを設定できないのはパッケージ引数だけです。 提案だけはされていますが Hold になってます。
未解決問題を修正しました。
制限¶
他の型引数に依存する型引数にデフォルトを設定することはできないようです。
この例ですと Array_Type
をデフォルト付きの型引数にはできません。
type Float_Array is array (Positive range <>) of Float;
generic
type Element_Type is private;
type Index_Type is range <> or use Positive;
type Array_Type is array (Index_Type range <>) of Element_Type
or use Float_Array; -- error
package G4 is
end G4;
package I4 is new G4 (Element_Type => Float);
型引数同士の矛盾がないインスタンスが存在できたとしてもだめです。 デフォルトを通じてgenericのモデルに暗黙の条件を追加することはできません。
他の型引数に依存しなければOKです。
type Float_Array is array (Positive range <>) of Float;
generic
type Array_Type is array (Positive range <>) of Float or use Float_Array;
package G5 is
end G5;
Ada.Numerics.Big_Numbers.Big_Integers/Big_Reals¶
ちょこちょこ修正されています。 新規ライブラリですし修正自体の説明はいらないでしょう。 (手抜き)
Nonblockingの変更¶
17日目や19日目でgenericの引数を参照する例を出しました。
このgenericの引数との論理積は常に行われるようになりましたので、わざわざ書く必要がなくなりました。
(Global
アスペクトにも同様の変更が行われているらしいです?)
また多態呼び出し先の Nonblocking
を参照するための構文 X'Nonblocking (Primitive)
が追加されています。
X'Nonblocking (all)
で全てのプリミティブの論理積を取れます。
(あれ? overriding
で Nonblocking
を変更することはできなかったのでは?)
Dynamic_Predicate
でブロッキングを行う関数を呼びたい場合のため subtype
でも Nonblocking => False
を指定できるようになりました。
知らないうちの変更が多いですね。 まあ私が調べ漏らしているだけなのですが。 一度まとめ直す必要がありそうです。
Globalアスペクトの変更¶
Globalアスペクトにまたも変更が加えられています。
all
と synchronized
を指定する場合にはモードも必須になりました。
モードが書かれていないと in out
の意味だったのですが、サブプログラムやgenericの仮引数等他の箇所ではモードが書かれていないと in
の意味ですので一貫性を保つための変更のようです。
19日目を修正しました。
Default_Valueアスペクトと内部表現の変更¶
値渡しされる型は派生先でも内部表現の変更が許されています。
declare
type S is range 0 .. 127 with Size => 8;
type D is new S with Size => 7;
しかし Default_Value
アスペクトが設定されていますと out
パラメータが参照渡しのような挙動を示します。
(参照渡しそのものではなく実際は値渡し in out
に近く、アドレスが渡されているわけではありません。)
理由等は面倒な話ですので割愛させていただいて、デフォルト値があると out
パラメータの挙動が若干変わるとだけ把握してください。
細かいことが知りたければJohn Barnes先生の Rationale Update for Ada 2012 読んでください。この辺です。
とにかくこの挙動のせいで、元の型が Default_Value
とユーザー定義のプリミティブの両方を持っている場合に派生先での内部表現の変更が禁止されていました。
正確には Default_Value
の導入はAda 2012、内部表現の変更が禁止されたのはAda 2012 with Technical Corrigendum 1からですので、後から禁止されました。
Ada 202xからは再び許可されます。
declare
type S is range 0 .. 127 with Default_Value => 1, Size => 8;
type D is new S with Size => 7;
その他細かい修正¶
見落としレベルの細かい修正がひとつのAI (AI12-0373-1)に詰め込まれています。 これも詳しい説明はいいでしょう。 (手抜き)
関連AI¶
AI12-0205-1 Defaults for generic formal types
AI12-0366-1 Changes to Big_Integer and Big_Real
AI12-0373-1 Bunch ‘o fixes
AI12-0375-1 Meaning of Global when there is no mode
AI12-0376-1 Representation changes finally allowed for untagged derived types
AI12-0374-1 Fixes for Nonblocking