変な挙動
コードをいろいろテストしていたら変なことに気がついた。
julia> [x - 1 for x in 1:2]
これは動くのに、
julia> [x -1 for x in 1:2]
ERROR: syntax: invalid comprehension syntax
こうなる。何が違うかと言うと、x - 1
の マイナスと1の間にスペースがあるかないか、なのだけど、ないとエラーがでる。
しかし、リスト内包表現でない場所では当然普通に動作する。
julia> x = 1
1
julia> x -1
0
julia> x - 1
0
いろいろ試してみた
別の演算子で試してみる。
julia> [x +1 for x in 1:2]
ERROR: syntax: invalid comprehension syntax
julia> [x *1 for x in 1:2]
2-element Array{Int64,1}:
1
+
だとだめだけど*
だと普通。つまり単項演算子として機能する演算子だとだめ、ということらしい。
いっそ演算子を抜いてみるとどうなるのか。
julia> [x 1 for x in 1:2]
ERROR: syntax: invalid comprehension syntax
では、ジェネレータの内包表現だとどうか。
julia> (x -1 for x in 1:2)
Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##7#8"))}(getfield(Main, Symbol("##7#8"))(), 1:2)
問題ない。つまり、リストというか配列でだけ問題が起きるようだ。
なにがおこっているのか
正直全然わからないが、x -1
が x
と -1
という2つの値としてパースされていることは間違いなさそう。なぜ配列の中でだけおかしなことがおこるのか、ということなのだけど、よく考えると、Juliaの配列リテラルの中では、そもそもスペースの扱いが特殊なのだった。
julia> [x -1]
1×2 Array{Int64,2}:
1 -1
julia> [x - 1]
1-element Array{Int64,1}:
0
個人的にはこの記法はとても気持ち悪いのだけど、matlabとかも同じらしい。つまり数学で使うのとなるべく近い記法で書きたい、ということなのだろう。
ちょっとソースを見てみる
ちょっとソースコードを探してみた。Juliaのパーサってschemeで書かれているのね。びっくり。
space-sensitive
という変数で制御していそうだけどよくわからない。。時間があったらもう少し探してみよう。