変数とは、情報を保持する機能のことです。あさやけでは変数が関数・名前空間を管理するという仕組みになっているために、
変数はすべての根底に位置します。そのため、言語全体では最も重要な概念です。
変数を関数の中で定義・操作するには次のように行います:
整数 エントリーポイント{ 整数 あ、い。 整数 初期済み整数は-10。 あは 123。 いは 1000000。 あで戻る。 // 123が返る }
とても簡単です。
「整数」と「あ」はスペースなどで切り離す必要があります。これは意味のあるスペースです。
値を変数に入れる操作を代入といい、代入演算子「は」か「=」を使います
(その他の演算子については演算子の項参照)。
初期化と代入の違いはさほどありませんが、初期化のほうが効率が良いでしょう。
変数から値を取り出すのは変数名でできます。しかし、実装系は取り出すのではなく変数のアドレスを
間接的に受け取る必要があります。
変数名の制限はシンボルの制限と同じです(基礎構文の項参照)。
変数に対する参照を作ることもできます。参照を操作するのは次のように行います:
整数 テスト関数(参照 あで){ 整数 い。 いは あ。 い+1で戻る。 } エントリーポイント{ 123でテスト関数して、それを出力。// 124 整数 うはテスト関数(100)。 うを出力。// 101 参照 えはう。 うへ足す。 えを出力。// 102 }
参照はどのような変数でも"参照"することができ、複製によるメモリや時間のコストもありません
(型制限付きの参照については仕様策定中 恐らく搭載されない)。
変数を使ったプログラムで、説明していないものがあります。
変数を作る際、何の変数を作るのかを指定しました。
このとき指定されたのは、型です。
あさやけは型チェックの緩い型あり言語です。型があると実装系の負担が幾分か軽くなり、エラーを未然に防ぎます。
型は、変数をどのように作るのか、変数をどのように処理するのかを決めます。
型ごとに設けられた演算によって、123+456は579に、「123」+「456」は「123456」になります。
型は様々とあります(目に見えない形で実装系は様々な型をすぐに作れるように準備しています)が、
ユーザーが一般的に使うのは次の型です:
| 変数の型 | |
|---|---|
| 変数(型名) | 何でも入れられる自由型。型の制限が無い入れ物として使える。 |
| 整数 | 符号付き整数。最低4バイトで32bit(-2147483648~2147483647)。 |
| 実数 | 符号付き実数(数学の実数ではない)。最低8バイトで64ビット(2.22507e-308~1.79769e+308)。 |
| 文字 | Unicodeの2バイト文字。 |
| 文字列 | Unicodeの2バイト可変長文字列。 |
| 配列 | どのような型も入れることができる可変長配列。整数のインデックスでの参照。 |
| 辞書 | どのような型も入れることができる可変長連想配列。文字列のインデックスによる参照。 |
実装系はこの6つの型を必ず実装しなければいけません。
他にも整数のペアで有理数を実現する型「有理数」、1バイトを保持する型「バイト」などがあります。
スクリプト中に値を埋め込むときは、どのように表記するかで型が決まります。
123は整数に、123.0は実数に、「123」は文字列になります(それ以外の表記については仕様策定中)。
このように、スクリプトに埋め込まれた値をリテラルといいます。
また、決まりきった値を使いまわす際は、パフォーマンスと安全性のために定数を使います。
定数は、初期化の後一切書き換えることができません。
誤用で書き換えてしまったりすることを防いだり、コンパイラによる実装系では速度の向上につながります。
どのような型でも定数にすることができますが、式の形で初期化できなければなりません。
定数は次のように定義します。
整数 初期値{ 10*10で戻る。 } !整数 あは123。 !整数 いは初期値+1。 エントリーポイント{ あを出力。// 123 いを出力。// 101 }
定数を定義する際、式であれば動的に定数を初期化することも可能です。これにより、 柔軟なプログラムを書くことが可能ですが、定数領域に定数を置くことができませんので、 速度が落ちる可能性があります。 (この注意書きは、インタプリタの実装系の場合はほとんど関係ありません。インタプリタの実装系では、 書き換えができないという点以外ではただのグローバル変数と変わりません。)
文字列は、どのようなプログラミングでも頻繁に出てきます。
文章処理に限らず、ユーザにプログラムからの情報・エラー・警告を示すためなどにはよく使われます。
また、文字列は柔軟で、他の型をある程度許容できてしまいます。しかし、あさやけでは、
文字列によって型チェックをすり抜けていくプログラミングスタイルはおすすめできません。
型があることで初めてその扱い方が分かるからです。
文字列を使うには、文字列型の変数を定義する、文字列リテラルを使うなどの方法があります。
特に文字列リテラルは、他の型のリテラルと比べて仕様が複雑です。
文字列リテラルは、表現方法を誤るとそれ以外のスクリプトが文字列と解釈されるなどの
複雑なエラーが発生する危険があります。文法上で分かりにくいエラーが発生したときは、
文字列リテラルの場合が多いでしょう。
配列の要素の参照は整数で、辞書の要素の参照は文字列で行います。
大抵配列の方が高速ですが、辞書の方が便利です。
どちらの参照も、内部参照演算子「の」か[]を使います。これらの演算子は
変数をまとめる働きをするまとまりでも使用されます。
目的は値から何かを使って値を取り出すことです。
問題は、内部参照演算子の右辺値に、性質が異なるものが混在するということです。
つまり、内部参照演算子の左辺値を計算するまでは要素の参照ををどのようにするのか分からないのです。
実装系は、内部参照演算子の左辺値がまとまりである場合にのみ、右辺値を展開せずにシンボルとして
認識しなければいけません。これは言語全体から見て多少おかしな仕組みであり、スマートでは
ありません。
配列や辞書の要素を参照する場合、シンボルしか使えないととても不便です。逆にまとまりで、
整数や文字列によってどの要素を読み込むかを、簡単にユーザ側で書き換えられるようになってしまえば、
これはセキュリティの問題につながります。
この手間によってかかるコストはわずかであるため、文法の単純さを重視した結果と言えます。
(型チェックを行う実装系の場合はこれによるコストはありません)。
動的に変数を参照するには、文字列による変数の参照をするグローバルシステム関数「変数」を使います。
この関数はプログラムの柔軟性を大きく向上させますが、同時にセキュリティを悪化させます。
ユーザから与えられた文字列でそのまま変数を参照するのは大変危険ですので、
必ず、入力文字列に型での制限や、なんらかを付加してください。
本来このような機能はなくてもいいのですが、正しく使えば大変便利なので言語仕様に含まれています。
十分に注意して使用してください。
(動的定義については仕様策定中)