http://www.adacore.com/2007/05/28/gem-3/
「limited typeを返すような関数が書けるよ!」
#1と#2から、limited typeにも代入できるようになったので関数が使えるようになりました。
中身の説明が興味深い。
In this case, Rumplestiltskin_Is_My_Name is allocated in the usual way (on the stack, presuming it is declared local to some subprogram). Its address is passed as an extra implicit parameter to Make_Rumplestiltskin, which then passes that same address on to Make_T, which then builds the aggregate in place at that address.
http://www.adacore.com/2007/05/28/gem-3/
適当訳: *1
この例では、 Rumplestiltskin_Is_My_Name は(サブプログラム内に宣言されていると仮定しているのでスタック上に)通常通り配置されます。そのアドレスはMake_Rumplestiltskin に暗黙のうちに追加の引数として渡され、その後同じアドレスが同様に Make_T に渡され、その後 Make_T は渡されたアドレスの指す先に aggregate を配置します。
アドレスを一々関数に渡すことで「limitedはコピーされない」ことを実現しているらしい…苦労してるんだなぁ…
この新しい機能を使えば似非単一代入で似非関数型言語っぽいことができます…?
こんな感じになる?:
type T is limited record N:Integer; end record; function Make_T(N:Integer) return T is begin return (N=> N); end Make_T; function F(X:T) return T is begin return (X.N+1); end F; function G(X:T) return T is begin return ((F(X).N)*(F(X).N)); end G; V: T := F(Make_T(1)); V2: T := G(V);
…うん、やらなくていいや。*2
Ada2012のExpression Functionsを使えば…!
type T is limited record N:Integer; end record; function Make_T(N:Integer) return T is (N=> N); function F(X:T) return T is (X.N+1); function G(X:T) return T is ((F(X).N)*(F(X).N)); V: T := F(Make_T(1)); V2: T := G(V);
わりとマシ…わりと…