Rubyの構文で静的型付けな記述ができる言語、Crystalの導入から型指定方法　まとめ


#Crystalとは
Ruby言語と似た構文を持った、静的型付けができる言語です。

#Crystalの目標
・構文がRubyの影響を受けている。(ほぼRuby言語の構文)
・静的な型のチェックがあるが、変数とメソッドの引数の型を指定しなくてもよい。
・Crystalのルールに基づいて書かれたC言語のコードを呼び出すことができる。
・ボイラープレートコード(定型文)を避けるため、コンパイル時間評価とコード生成を持つ。
・効率的なネイティブコードにコンパイルしてくれる。

#記事を書いた理由
公式リファレンスを読んだところ、Crystal特有の構文に加えてRuby言語ではおなじみの構文もしっかり書いてありました。
そこで今回は翻訳も含めてCrystal特有の構文や型指定方法に注目して記述していきます。

公式サイト
http://crystal-lang.org

公式リファレンス
http://crystal-lang.org/docs/index.html

#導入
・OS　OSX Yosemite 10.10.3
・Homebrewを使用
・Crystal 0.7.4

```bash:
$ brew tap manastech/crystal
$ brew install crystal

コンパイル&実行
$ crystal helloworld.cy

```

環境を構築しなくてもこちらで実行することができます。
http://play.crystal-lang.org/#/cr


#文法

##変数型宣言
```ruby:
str :: String
str = "Hello"
```
変数名 :: 型名
で変数に型を指定することができます。

```ruby:
str :: String = "Hello"
#unexpected token: =
```

型指定と代入を同時に行うことができない？(調査不足の可能性あり)


##返却値型

```ruby:
def hello : String
	"hello"
end
```

def メソッド名 : 型名
end
で返却値型を指定できます。


もし、型が違うと

```ruby:
def hello : String
	1
end
#in line 1: type must be String, not Int32
```
しっかりとエラーを吐いてくれます。

##引数型

```ruby:
def hello(keyword : String)
	"hello #{keyword}"
end
hello("world") #"hello world"
```

def メソッド名(引数名 : 型名)
end
で引数の型を指定できます。


##Crystal標準で扱える型
* Nil
* Bool
* Integers(Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64)
* Floats(Float32, Float64)
* Char
* String
* Array
* Hash
* Range
* Regex
* Tuple
* Proc

###Nill
nilオブジェクトに対応した型です。

###Bool
true、falseオブジェクトに対応した型です。

###Integers
整数型に関してはInt8、Int16、Int32、Int64があり、それぞれビット数に対応しています。
加えて、符号無し整数 UInt8, UInt16, UInt32, UInt64もあります。
基本的にはInt32を使用することになります。

```ruby:
num :: Int32
num = 10
```

###Floats
浮動小数点型は２種類存在しておりFloat32、Float64となります。
整数型と同じくビット数に対応しています。
基本的にはFloat64を使用することになります。

```ruby:
f :: Float64
f = 0.1
```


###String
文字列型です。

```ruby:
str :: String
str = "str"
```

###Array
可変長配列型です。

配列で扱う型を指定することができます。

```ruby:
array :: Array(Int32)
array = [1, 2, 3]
```

型を複数指定することも可能です。

```ruby:
array :: Array(Int32|String)
array = [1, "a"]
```

以下の方法でも初期化できます。

```ruby:
array = [] of Int32 

#Array(Int32).newと同等
```

###Hash
hash型です。

key,valueの型を指定することができます。

```ruby:
hash :: Hash(Int32, String) #key: Int32 , value: String
hash = {1 => "a", 2 => "b"} 
```

型を複数指定することもできます

```ruby:
hash :: Hash(Int32, String|Char)
hash = {1 => "a", 2 => 'c'}
```

以下の方法でも初期化できます。

```ruby:
hash = {} of Int32 => String 

#hash = Hash(Int32, String).new と同等
#key: Int32, value: String
```

###Range
範囲型です。

型の指定は以下の形式です。

```ruby:
range :: Range(Int32, Int32) 
range = 1..2
```

###Regex
正規表現型です。

```ruby:
reg :: Regex
reg = /foo|bar/
```

###Tuple
タプル型です。

型の指定は以下の形式です。

```ruby:
tuple :: Tuple(Int32, String, Char) 
tuple = {1, "a", 'a'}
```

###Proc
Proc型はrubyにおけるProcと同じですが、記法が若干異なります

```ruby:
y :: Proc(Int32, String)
y = ->(x : Int32) { x.to_s }
puts y.call(1) #"1"
```
Proc(引数型, 返却値型)のように指定することができます。

```ruby:
proc :: Proc(Int32) 
proc =  ->{ 1 }
proc.call #1
```
引数がないprocの場合はProc(返却値型)です。

メソッドをprocで実行する場合。

```ruby:
def plus_one(x)
  x + 1
end

proc = ->plus_one(Int32)
proc.call(41) #=> 42
```

#まとめ
今回はRuby言語と異なる部分に注目して記述しました。
今回Crystalに触れてみて感じたこと

* ほとんどの記述方法がRubyなので馴染みやすい。
* Rubyの記法で静的型付けの記述ができるのは有用性がありそう。(純粋なオブジェクト指向という観点で比較すると、Rubyよりしっかり書きたいがScalaよりは緩く書きたいときなど)
* Rubyに存在していた記法で無くなってしまったものがある？。(for文が見当たらなかった)
* 少々改善できそうな部分がある？変数の型指定と代入が同時に行えないなど。(調査不足の可能性あり)

まだバージョン1.0に達していないので今後に期待です。
紹介していない記法などもありますので今後もCrystalに関して記事を書いていこうかと思います。