AliceScript 4の新機能

この記事では、AliceScript4の変更点と新機能について説明します


taiseiue | 2024-12-27

新機能

AliceScript 4(Alice4)は、Alice3.0の後継です。 Alice4では、大まかに分けて以下の新機能が導入されました。

  • 規定値を使った変数宣言: 変数の宣言に具体的な値を使用しなくても、左辺の型の規定値を使って変数を初期化できるようになりました。
  • 辞書型の導入: キーと値のペアを保持できる辞書型を導入しました。
  • 配列操作の改善: 配列を集合とみなして演算したり、特定範囲を取り出したり、反復して新しい配列を作成したりと、配列に対して便利な操作を簡単に行えるようになりました。
  • 関数定義の改善: .NETの型を関数の戻り値の型として使用したり、引数をreadonlyとしてマークしたり、関数に注釈を記述できるようになりました。

最新のAliceScriptADKはAliceScriptのダウンロードからダウンロードできます。

ご意見をお寄せください

AliceScriptの新機能に関するご意見や不具合がある場合、AliceScriptのリポジトリにお寄せください。

規定値を使った変数宣言

従来、変数の宣言時には必ず具体的な値を何か代入する必要がありました。 Alice4からは、変数の宣言に具体的な値を使用しなくても、左辺の型の規定値を使って変数を初期化できるようになりました。

AliceScript
// x = 0になる
number x;
// y = nullになる
number? y;

// 後から型を決める
var v;
v = 1;

辞書型

辞書型は、キーと値のペアのリストです。Alice 4では、この辞書型に加えて辞書式を導入しました。 次の例をご覧ください。

AliceScript
dictionary dict = {
    "one": 1,
    "two": 2
}

print(dict["one"]); //出力例: 1

dict["three"] = 3;

辞書式

辞書式は、配列式と同様に簡単に辞書構造を記述できる式です。辞書式は配列式と異なり、角かっこの代わりに波かっこを使います。次の例をご覧ください。

AliceScript
// 辞書になる
dictionary dict = {
    "one": 1,
    "two": 2
}
// KeyValuePairの配列になる
array ary = [
    "one": 1,
    "two": 2
]

KeyValuePair式

簡単にキーと値のペアを表すオブジェクトを作成できる、KeyValuePair式を導入しました。 次の例をご覧ください。

AliceScript
var kvp = "kvp": true;

print($"Key: {kvp.Key}, Value: {kvp.Value}");
// 出力: Key:kvp, Value: true;

配列型の改善

配列に対して幾つかの演算子を新たに導入しました。配列を集合とみなして演算したり、特定範囲を取り出したり、反復して新しい配列を作成したりと、配列に対して便利な操作を簡単に行えるようになりました。

反復演算子

文字列と配列型に、その値を複数回繰り返した新しいリストを取得できる、反復演算子を導入しました。次の例をご覧ください。

AliceScript
var ary1 = [0, 1, 2];
var ary2 = ary1 * 2;

print(ary2);
//出力: [0, 1, 2, 0, 1, 2]

この変更はWSOFT-Project/alicescript#5で提案、検討しました。

集合演算子

配列型同士の間で、左右の配列を集合とみなして集合演算を行えるようになりました。 Alice4では、次の演算ができます。いずれの操作でも、新しい配列が作成されます。

  • 結合演算子: 左の配列の末尾に右の配列を結合する
  • 差集合演算子: 左の配列に対する右の配列の差集合
  • 和集合演算子: 左の配列と右の配列の和集合
  • 積集合演算子: 左の配列と右配列の積集合
  • 対象差集合: 左の配列と右の配列の対称差

次の例をご覧ください。

AliceScript
var a = [1, 2, 3, 4];
var b = [2, 4, 6, 8];

// 結合
array concat = a + b;
print(concat); //出力: [1, 2, 3, 4, 2, 4, 6, 8]

// 差集合
array except = a - b;
print(except); //出力: [1, 3]

// 和集合
array union = a | b;
print(union); //出力: [1, 2, 3, 4, 6, 8]

この変更はWSOFT-Project/alicescript#17で提案、検討しました。

配列の範囲構文

配列添字を拡張子、配列の特定範囲を抜き出して処理できる範囲構文を導入しました。 配列添字で開始位置と終了位置を指定すると、その区間の配列をシャローコピーできます。 次の例をご覧ください。

AliceScript
array source = [1, 2, 3, 4, 5];

// インデックス1から2(3のひとつ前)まで取得する
print(source[1..3]); // [2, 3]

この変更はWSOFT-Project/alicescript#12で提案、検討しました。

関数定義の改善

.NETの型を関数の戻り値の型として使用したり、引数をreadonlyとしてマークしたり、関数に注釈を記述できるようになりました。

式形式の関数

関数の本文が1行で収まる場合、ラムダ式のように波括弧やreturn文を省略して関数を定義できるようになりました。 次の例をご覧ください。

AliceScript
number Pow(number x) => x * x;

// requiresやensuresも使える
number Divide(number x, number y) requires(y != 0) ensures(return != 0) => x / y;

この変更はWSOFT-Project/alicescript#28で提案、検討しました。

注釈

関数に補足情報として、注釈を記述できるようになりました。例えば、次の例ではobsolete属性を関数に付与して、関数がもう非推奨であることを示します。

AliceScript
@obsolete("func_newを使用してください")
public virtual void func_old();

この変更はWSOFT-Project/alicescript#1で提案、検討しました。

readonlyな引数

関数の引数も、readonlyとしてマークできるようになりました。 関数の引数をreadonlyとすることで、関数内部で引数を読み取り専用にでき、より安全に開発できます。次の例をご覧ください。

AliceScript
void Hoge(readonly number x)
{
    // 以下のコードはエラー
    x = 0;
}

この機能は、参照渡しとも併用できます。大きな引数を扱うとき、参照渡しを使うことで値のコピーを回避でき効率が向上しますが、副作用として内部で値が書き換え可能になってしまうという問題がありました。そこで、参照渡しとなる引数をreadonlyとしてマークすることで、値のコピーは防ぎつつ、呼び出し先で内容を変更できないようになります。次の例をご覧ください。

AliceScript
void Func(readonly ref var item)
{
    // ...
}

この変更はWSOFT-Project/alicescript#15で提案、検討しました。

プリミティブ型以外を返す関数

Type型の値を関数のシグネチャに使えるようになりました。これによって、プリミティブ型以外の型も関数の戻り値として宣言できるようになり、.NETの型をOBJECT型として宣言する必要がなくなり、より正確な型で戻り値を定義できるようになりました。次の例をご覧ください。

AliceScript
using Alice.Interop;

// Complex型の情報を取得する
var Complex = interop_GetType("System.Numerics.Complex","System.Runtime.Numerics");

Complex Hoge(Complex x, Complex y)
{
    //...
}

この変更はWSOFT-Project/alicescript#25で提案、検討しました。

関数のシグネチャにvarキーワードを書けるように

関数シグネチャで、引数の型にvarキーワードを使えるようになりました。引数リストの中ではvarキーワードは任意の型を表します。次の例をご覧ください。

AliceScript
var hoge(var x);

この変更はWSOFT-Project/alicescript#19で提案、検討しました。

その他

typeof式

任意のオブジェクトについてその型情報をType型で返す、typeof式を導入しました。これはvariable.GetTypeメソッドを呼び出すのと同じです。次のように使用します。

AliceScript
string str = "Hello,World";
bool cond = false;

print(typeof(str)); //出力: STRING

Type bolType = typeof(cond);

// bool型は値型なので、falseになる
print(bolType.IsObject); //出力: false

この変更はWSOFT-Project/alicescript#28で提案、検討しました。

3値論理

論理演算のどちらかのオペランドがnullの場合、クリーネの3値論理に従った論理演算を行うようになりました。これにより、null許容Bool型を用いてより複雑な論理演算を行えるようになりました。

3値論理演算の詳しい定義については、論理演算子#3値論理演算をご覧ください。

この変更はWSOFT-Project/alicescript#27で提案、検討しました。

ビット補数演算子

数値型の値にビット補数演算子を適用して、その数値の1の補数を取得できるようになりました。次の例をご覧ください。

AliceScript
number x = 10;

// xの1の補数を取る
number cmpl = ~x;

print(cmpl); //出力: -11

この変更はWSOFT-Project/alicescript#14で提案、検討しました。

複数個連続した単項演算子

従来、隣接して単項演算子を複数個ならべたときの動作は未定義でした。 Alice4以降では、隣接した単行演算子はオペランドに近い方から処理するようになりました。 つまり、次の2行のコードは等価です。

AliceScript
-+2;

-(+(2));

この変更はWSOFT-Project/alicescript#13で提案、検討しました。

foreachの条件緩和

従来、foreachで列挙可能な値は文字列か配列である必要がありましたが、Alice4からはGetEnumeratorメソッドを実装し、それがIEnumerator型のオブジェクトを返すすべてのオブジェクトで列挙できるようになりました。 この改善によって、.NETのオブジェクトをそのままforeach文で使えるようになりました。

この変更はWSOFT-Project/alicescript#8で提案、検討しました。

Alice.Runtime

Alice.Runtimeの新しいAPIや、APIの改善を以下に示します。

Alice.IO名前空間

Alice.Math名前空間

Alice.Reflection名前空間

Array

Dictionary

String