🎃

Verse言語の設計思想を読み解きたい(14)コードブロック

2023/04/18に公開

前回はこちら
https://zenn.dev/t_tutiya/articles/fdbc95dc315d57

Verse言語の最大の特徴と言える「失敗コンテキスト」と「非同期処理」については前回までで一通り終わりました。今後は紹介したい個々の要素についてトピックを立てていきます。

次は型システムをざっくり眺めていこうと思っていたのですが、その前に非同期処理の補足をしたくなり、今回は更にその前段階としてコードブロックについて改めて確認します。

コードブロック

https://dev.epicgames.com/documentation/ja-jp/uefn/code-blocks-in-verse

コードブロック(Code Blocks)」は複数の式[1]をグループ化する概念で、定数/変数のスコープを導入する物です。

C#等ではブレス括弧で囲まれた範囲をスコープとするのに対し、Verseではコードブロックの範囲を示すために3通りの「書式(Format)」が用意されています(一部公式訳とは異なります)。

  • 空白インデント書式(Spaced Format)
  • 複数行ブレス括弧書式(Multi-Line Braced Format)
  • 一行ドット書式(Single-Line Dot Format)

これらは意味としては同じ物であり、互いに切り替えて使う事ができます。

コードブロックは常になんらかの識別子(例えば関数名やsyncなど)の後に記述できます。任意の位置にコードブロックを構築する場合はblock式を使用します。

空白インデント書式(Spaced Format)

半角空白によるインデントでコードブロックの範囲を表します。

識別子の後に":"を記述すると、その次の行以降、字下げ(インデント)された行がコードブロックになります(":"と同じ行には式を配置できません)。

インデントは、公式ドキュメントでは「半角空白4個」となっていますが、1文字でも字下げされていれば、例え一行毎に字下げ幅がバラバラだったとしてもコードブロックとして機能します[2]

if式でのコードブロックの例を公式ドキュメントから引用します。

if (test-arg-block):
    expression1
    expression2

":"の直後から同インデントレベルにあるexpression1とexpression2が同じコードブロックにあります。述語部(ここではtest-arg-block)はそのコードブロックに含まれないので注意してください。

また、式の最後に";"を付与すると、1行内に複数の式を記述できます。

if (test-arg-block):
    expression1; expression2

なお、仕様上は空(つまり式がゼロ個)のコードブロックを構築する事も出来ます。これは、後から式を追記するための空箱(「プレースホルダー(Place Holder)」と言います)として用いる物で、それ自体に機能としての意味はありません。

複数行ブレス括弧書式(Multi-Line Braced Format)

C#と同じように、ブレス括弧で囲んだ範囲はコードブロックになります。

if (test-arg-block)
{
    expression1
    expression2
}

ブレス括弧書式についても、";"を使うと1行内に複数の式を記述出来ます。下のコードは先程のコードと同じ意味になります。

if (test-arg-block){ expression1; expression2}

一行ドット書式(Single-Line Dot Format)[3]

識別子の後に". "(ドット+半角空白)を記述して、一行でコードブロックを構築する事も出来ます。ドットの直後に半角空白が必要なので注意して下さい。この場合も";"を使って複数個の式を記述出来ます。

if (test-arg-block). expression1; expression2

else予約語の後に". "を入れる事もできます。ただし、この場合はthen節には式を一個しか記述出来ない仕様になっています。

if (test-arg-block). expression1 else. expression2

個人的には、一行ドット書式の処理は複数行ブレス括弧書式で内包出来るので、なぜこの書式が用意されているのかが分かりません。ブレス括弧をどうしても使いたく無い勢がいるのかな……?

色々なコードブロック

コードブロックを使った例を幾つか紹介します。

if式の述語部

ifの述語部についても、空白インデント書式を使う事が出来ます[4]

以下の2つの式は同じ意味です。

if(x:=0; y:=1; z:=2) true

if:
    x:=0
    y:=1
    z:=2
then:
    true

ちなみに、ifでは以下の様に";"ではなく","も式のデリミタ(区切り文字)に使えます。

if(x:=0, y:=1, z:=2) true

なぜデリミタが2種類あるのか不思議な感じがしますが、どうやら","で区切った場合、述語部はタプルとして解釈されるようです。ちなみに、将来的なVerse[5]には"|"をデリミタとしたchoiceという方式も採用される予定です。

option式

option式でも空白インデント書式を使って複数の式を記述出来ます。

以下の2つの式は同じ意味です。

MaybeFirstPlayer := option {GetPlayspace().GetPlayers()[0]}

MaybeFirstPlayer := option:
	Playspace := GetPlayspace()
	Players := Playspace.GetPlayers()
	Players[0]

map

twitterで@takaf51さんがmapもコードブロックで定義出来る事を紹介されていました。面白いです。

#Fortnite #Verse #VerseLang #UEFN

続き

https://zenn.dev/t_tutiya/articles/f9ece14ddb3fda

お知らせ


verse言語とUEFNの記事を他にも書いているので御覧下さい。
https://zenn.dev/t_tutiya

最後まで読んで頂きありがとうございました。この記事がお役に立てたようであれば、是非LIKEとフォローをお願いします(今後の執筆のモチベーションに繋がります)。

#Verse #UEFN #Fortnite #Verselang #UnrealEngine

宣伝

「Unityシェーダープログラミングの教科書」シリーズ1~5をBOOTHで頒布中です。
https://s-games.booth.pm/

脚注
  1. 正確にはゼロ個以上の複数個の式 ↩︎

  2. とはいえ可読性の為には半角空白4個に統一するのが望ましいでしょう ↩︎

  3. 公式ドキュメントでは「単一行の中括弧で囲まれた形式」となっているが、用語集の説明との不一致から来るミスと思われる。 ↩︎

  4. 他の書式と可換ではない筈で、厳密にはコードブロックでは無いと思いますがよくわかりません。 ↩︎

  5. MaxVerseと呼ばれている言語。今のVerse(同BetaVerse)と互換性が維持されるのかは不明 ↩︎

Discussion