土屋つかさの技術ブログは今か無しか

土屋つかさが主にプログラミングについて語るブログです。

#UEFN #Verse 3/28の"Ask Epic: Verse"で面白かった回答ピックアップ(その4)

 Ask Epic:Verse回答祭り第4回(完結編)です。今回はVerseの型システムに関係する質問がメインです。

 今回まとめた分はマニアックな質問が多く、土屋自身がついていけてない物もありました(結果誤訳してる可能性があります)。多くのユーザ-がVerseの言語仕様に強い興味を持っていて、回答側もそれに答えようとしている雰囲気が伝わればと思います。

MaxVerseはいつやってくる?

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393/82?u=t.tutiya

Q:VerseがSimon Peyton Jonesの示したものに近づくのはいつになるのでしょうか?

A:(既に)Verse Calculusに相当するリファレンス実装があります。(ただし)型の検証が進行中のため、まだ公開されません。その上で、リファレンス実装はUEFNが直接扱う物ではありません。MaxVerseがUEFNで利用可能になる時期を示すことはできません。

土屋解説

 繰り返しになりますが「MaxVerse」は予定している全ての機能を含むVerseの事*1。「Verse Calculus」はSimon Peyton Jonesらが発表した、Verseの数学的背景を説明した論文の事。「リファレンス実装」はコンセプトの検証を目的とした(必ずしも実用性を指向していない)実装の事です。

プロパティの導入

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393/58?u=t.tutiya

Q:いつかプロパティ*2を使えるようになりますか? そもそもこれは可能ですか?

A:私たちは、拡張メソッドを拡張フィールドに一般化したいと考えています。ただし、(no_transacts、サスペンドなどにおいて)副作用が起きない保証が必要です。

土屋解説

 プロパティは、クラスフィールドを参照/更新する際に処理を挟める仕組みの事で、多くのモダン言語で標準搭載されています。

 Verseでは、拡張メソッドの仕組みをフィールドにも使えるようにして、プロパティの役割を持たせる予定のようです(ただし、設計が上手くいけばの話)。

変数を持つインターフェイス

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393/60?u=t.tutiya

Q:変数を持つinterfaceは使えるようになりますか?

A:私にできる最善の答えは、それが私たちの頭の中にあるということです。

土屋解説

 Javaのinterfaceには変数*3を記述する事が可能で、それをVerseでもしたいという質問。ちなみにC#のinterfaceでは変数は持てません*4

列挙型を整数として扱う

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393/54?u=t.tutiya

Q:値も格納する列挙型はいつ使えるようになりますか?

A:判別可能な共用型は現在設計中ですが、いつになるかはわかりません。

土屋解説

 C++/C#の列挙型(enum型)は内部では整数として扱われていて、下記のように個々の要素に整数を割り当てる事ができます(設定しない場合はゼロからの連番)。

enum bitFlag
{
  X = 1, // 001
  Y = 2, // 010
  Z = 4, // 100
}

 これを使うと、個々の列挙子をビットフラグとみなしbitFlag.X | bitFlag.Yで"011"を表すような事が可能です。Verseでもこういう事が出来ないかというのが質問の趣旨です。

 回答は、時期は未定だが「判別可能な共用型(Discriminated unions.)」で対応したいという物。ここで簡単に共用型について説明しておきます。

 C/C++には「共用型(union型)」というのがあります*5。共用型は1つの変数に異なる型の値を格納できます。共用型は、異なる構造体型を1つの配列に格納したい場合などに使用します*6

 共用型は事故が起きやすく、その事故をコンパイル時に抑制しやすくしたのが「判別可能な共用型*7」で、TypeScriptなどで採用されています。

 というわけで、Verseでは、列挙型の各要素を内部的に整数として扱うのではなく、判別可能な共用型として値を持たせる形になるようです。

ミュータブルな配列/マップが欲しい

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393/102?u=t.tutiya

Q:いつかミュータブルなarray/mapが出来ますか? 現状では、大きな配列を作ることがフェイクラグ*8をシミュレートするベストな方法になってしまっています。

A:目標は、イミュータブルなデータ構造を持つvar変数の部分更新を効率化する事です(それが実現すればミュータブル版は必要ないので)。現時点ではそうはなっていません。というのも基底表示では完全コピー以外に部分更新を行う方法が無いためです。とはいえ、このリクエストは新しいVMでは念頭に置かれています。

土屋解説

 一般に、作成後にその状態を変更出来ないオブジェクトを「イミュータブル(immutable. 不変)なオブジェクト」と、その逆を「ミュータブル(mutable. 変更可能な)なオブジェクト」と呼びます。

 現在のVerseでは、一度作成した配列の要素を削除/追加する事ができません*9。削除が必要な時は配列を作り直すしかありません。つまり、配列のデータ構造はイミュータブルです。これがミュータブルにならないのかという質問。

 質問の後半はこの現状に対する皮肉で、「大きな配列を作るだけで(要素の追加/削除のたびに配列の作り直しが発生して処理負荷がかかるので)フェイクラグシミュレータが作れちゃうよ」というジョークなのだと思います(間違ってたらすみません)。

 回答は、ミュータブル版の配列を用意する予定はなく、イミュータブル版の部分更新を効率化させるとのこと。ここで言う「部分更新(partial updates)」は、先述した「配列から要素を削除する」のような処理を指します。現状では完全コピー(つまり配列を丸ごと作り直す)しか方法がありませんが、これについてはVerseVMでの対応が予定されているとのこと。

 ちなみに「基底表示(underlying representation)」は言語学用語なのですが、プログラミング言語理論にもある用語なのか、単に「現在の仕様では」くらいの意味なのかは判別出来ませんでした。

var変数にパラメータ型を適用する

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393/50?u=t.tutiya

Q:パラメータ型にvar変数を追加する予定はありますか?

A:はい。Verseが現在ベースにしている型システムであるMLsubはvar変数を問題なくサポートしています。ただし、MLsubがMaxVerseと一致しない可能性があることが懸念されます

土屋解説

 現在のVerseではパラメータクラス*10のメンバにvar変数を定義できません。

box(item:type) := class:
        ConArg:item #これはOK
    var VarArg:item #コンパイルエラー"Mutable members in parametric classes are not yet implemented.(3502)"

 エラーメッセージに"not yet implemented"とあるので、いつかは採用されるの? というのが質問の趣旨。

 "MLsub"はOCamlで書かれている型推論エンジンです("MLsub"の存在を初めて知りました)。MLsubで可能でも、MaxVerseと一致しない仕様の導入は難しいので、検討した上での採用したいという回答。

型同士の比較について

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393/46?u=t.tutiya

Q:型同士の比較はできるようになりますか?例えば、DIフレームワークでは、mapのkeyとして型を使います。

A:いいえ。何故ならMaxVerseでは型と部分恒等関数とが区別されないからです。型を比較可能にするには、例えばint型と、引数にintを取るラムダ式との等価性を実行時に判定する必要がありますが、これは一般的に不可能です。

土屋解説

 プログラミング言語によっては、実行時にインスタンスの型情報を取得/比較する機能*11があります。現在のVerseでは出来ないので、その予定はあるのかという質問。

 回答は恐らく型システム/型推論上の説明をしているのだと思うのですが、土屋の理解範囲を超えているのでほぼ直訳です。結論としては、言語仕様上出来ないとのこと。

おわりに

 Ask Epic:Verse回答祭りは今回で完結です。世界中のユーザーによるVerse言語の仕様への悲喜交々、そして公式フォーラムの活況が伝われば幸いです。

 とはいえ、紹介していないやりとりが他にも沢山あるので、是非元スレッドの方も御覧になってください。

https://forums.unrealengine.com/t/ask-epic-verse-march-28-10-00-am-et/1765393

 近々採用される(筈の)シーングラフ機能についても多く触れているので、この当たりに興味のある人も是非。

 なお、型システム関連の回答で、解説が長くなるため外した物と、既に紹介した回答に追加解説が来た物がありまして、これらは単発で記事にする予定です。

宣伝

Verse言語の言語仕様解説同人誌をPDFで頒布しています。よろしければどうぞ。

s-games.booth.pm


*1:現在のVerseはMaxVerseのサブセットでBetaVerse/ShipVerseと呼ぶ。

*2:原文ではswift言語でプロパティを表す"computed properties(計算型プロパティ)"。

*3:ただし強制的にpublic static final(つまり定数)になる。変数を記述できてしまうとダイヤモンド継承で大変な事になるから

*4:土屋はC#erなのでこのメリットが良く分かりません。

*5:C#には共用型はありません

*6:メモリマップを共用できる事が利点だというのが土屋の理解だけど、モダン言語の共用型はまた違うのかもしれない(良く知らない)。

*7:直和型とも言う

*8:意図的にラグを発生させる事を意味するオンラインゲーム用語

*9:mapは追加出来るが削除できない

*10:C#で言うジェネリッククラスのこと

*11:C#で言えばtypeof演算子、is演算子、Object.GetType()メソッドなど