Skip to content

Instantly share code, notes, and snippets.

@kmizu
Created August 8, 2019 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmizu/40c238262f3196bdfe8113be4e3d16d8 to your computer and use it in GitHub Desktop.
Save kmizu/40c238262f3196bdfe8113be4e3d16d8 to your computer and use it in GitHub Desktop.
2004/09/09の自分のWeb日記
以前にちょっとだけ触ってみたNiceについて調べてみる。  Niceは、Javaをベースに高階関数、マルチメソッド、パラメータ型、キーワード引数、省略可能引数、Option Typesなどの機能を追加した言語で、処理系は、Java VM用のコードを吐くコンパイラとなっている。
マルチメソッド、キーワード引数などは、他の言語でもよく見かけるが、 Option Typesは、他の言語ではあまり見かけない機能だ。Option Typesとは、値としてnullを許す型で、それだけ見ると、珍しくもなんともないのだが、Niceでは面白いことに、変数の型はデフォルトでnullを代入できないのだ。例えば、以下のようなコードを書くと、sはnullを代入できない型になり、もしsにnullが代入され得るようなコードを書くと、コンパイルエラーになる。
let String s = "Hello";//nullは代入できない
もし、nullを代入可能にしたければ、型名の頭に'?'を付けて、次のように宣言する。
let ?String s = "Hello";//nullが代入可能
この機能は、大変面白い機能なんじゃないかと思う。例えば、Mapにキーを与えて値を取得するとき、返って来た値がnullかどうかをチェックする必要がある場合は多いが、この機能があれば、もし仮にnullかどうかのチェックを忘れたとしても、コンパイルエラーになってくれる。
しかし、このチェック機能、どこまでちゃんと働くのだろうか。それを確かめるために、以下のコードを書いて実験してみることにした。このコードでは、if文の中では、valueは絶対にnullになり得ないが、それをコンパイラが判断できるかどうか。
void main(String[] args){
let Map map = new HashMap();
map.put("A", 0);
map.put("B", 1);
map.put("C", 2);
?int value = map.get("E");
if(value != null || false){
int value2 = value;
}
}
このコードをコンパイルしてみると、以下のエラーメッセージが出力された。
nice.lang: parsing
example: parsing
example: typechecking
 
C:\programs\nice\.\example\option_type.nice: line 8, column 21:
Unused local variable value2
 
C:\programs\nice\.\example\option_type.nice: line 8, column 21:
The value value cannot be assigned to value2 because it might be null.
 
To allow value2 to contain the null value, it should be declared as:
?nice.lang.int value2
どうやら、論理式の中身までは見ておらず、nullかどうかを判断する式(value != null)と他の式が、||でつながれているかどうかだけを見ているようだ。となると、&&の場合はどうなるだろうか。以下のコードも、先ほどと同じくif文の中ではvalueはnullになり得ないが、先ほどと違って、演算子の種類(&&か||か)だけを見ればそれを判断可能になっている。
void main(String[] args){
let Map map = new HashMap();
map.put("A", 0);
map.put("B", 1);
map.put("C", 2);
?int value = map.get("E");
if(value != null && false){
int value2 = value;
}
}
このコードをコンパイルすると、今度は、何もエラーが出ずにコンパイルを通った。やはり、演算子の種類を見て判断しているようだ。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment