2011年12月4日日曜日

Io言語に触れてみた

"7つの言語 7つの世界"の2言語目
Ioに突入です。

Ioの1日目

検索するときには、【Io 言語】で検索する。

環境:Windows7 Home 32bit
*Ioのインストール
Javaとかでよくある、インストール手順みたいなのが
あるかと思ったが、Ioという名前からして
検索しても特にHITしなかったので、とりあえず
前に進むことにした。


http://iolanguage.com
から、iobin-win32-current.zipを落としてきた。

それを解凍して、README.txtを読んだら
まぁいい感じにやってくれ、みたいな感じを受けたので
いい感じにやることにした。

IoLanguage-win32-20111103.exe
をダブルクリックすると解凍される。

IoLanguage/io.exe
があるので、それをダブルクリックすると、
ウィンドウが立ちあがる。
とりあえずこれで会話ができる。

*まずは挨拶


Io> "Hi ho, Io" print
Hi ho, Io==> Hi ho, Io


次は打った履歴
Io> Vehicle := Object clone
==>  Vehicle_0x157e550:
  type             = "Vehicle"

Io> Vehicle message := "This is message."
==> This is message.
Io> Vehicle message
==> This is message.
Io> Vehicle message = "Message is updated."
==> Message is updated.
Io> Vehicle message
==> Message is updated.
Io> Vehicle timer ::= "10 min"
==> 10 min
Io> Vehicle timer
==> 10 min
Io> Vehicle setTimer("20 min")
==>  Vehicle_0x157e550:
  message          = "Message is updated."
  setTimer         = method(...)
  timer            = "20 min"
  type             = "Vehicle"

Io> Vehicle timer
==> 20 min
Io> Vehicle timer = "30 min"
==> 30 min
Io> Vehicle timer
==> 30 min


VehicleはObject をclone して
そこにmessage slot を定義している。

 "="   は、slotの名前が定義されているものの値を変える。
 ":="  は、slotの名前がなければ作成する。
 "::=" は、slotの名前がなければ作成し、setterも作る。

Io> Vehicle type
==> Vehicle
Io> Vehicle slotNames
==> list(timer, type, setTimer, message)

すべてのオブジェクトにはtype メソッドがある。
オブジェクトの種類を表す。


Io> Car := Vehicle clone
==>  Car_0x17853a8:
  type             = "Car"

Io> Car slotNames
==> list(type)
Io> Car type
==> Car
Io> Car message
==> Message is updated.
Io> ferrari := Car clone
==>  Car_0x157e820:

Io> ferrari slotNames
==> list()
Io> ferrari type
==> Car
Io> ferrari message
==> Message is updated.


ここまでの関係を簡単に図にすると、



Object

Vehicle

Car  --インスタンス--> ferrari



Ioのタイプは単なる便宜的な道具にすぎない。
大文字で始まる名前を持つオブジェクトに、typeスロット
が設定される。
ferrariのtype が Car となっているがそれが嫌なら以下のようにする。

Io> Ferrari := Car clone
==>  Ferrari_0x16df5d0:
  type             = "Ferrari"
Io> Ferrari slotNames
==> list(type)
Io> Ferrari type
==> Ferrari


ferrariは、typeスロットなし
Ferrariは、typeスロットあり

先頭文字が、大文字か小文字かの違いだけ。
動作にはまったく変わりはないそう。

*メソッド

Io> method("This is method." println)
==> method(
    "This is method." println
)
Io> method() type
==> Block
Io> Car drive := method("Vroom" println)
==> method(
    "Vroom" println
)
Io> ferrari drive
Vroom
==> Vroom
Io> Ferrari drive
Vroom
==> Vroom

スロットの内容を取得する方法として
getSlotがある。


Io> ferrari getSlot("drive")
==> method(
    "Vroom" println
)
Io> ferrari getSlot("type")
==> Car
Io> ferrari proto
==>  Car_0x17853a8:
  drive            = method(...)
  type             = "Car"


特定のオブジェクトのプロトタイプを取得するには
次のようにする。

Io> Car proto
==>  Vehicle_0x157e550:
  message          = "Message is updated."
  setTimer         = method(...)
  timer            = "30 min"
  type             = "Vehicle"



すべての名前付きオブジェクトが含まれる、
マスター名前空間、Lobbyがある。

Io> Lobby
==>  Object_0x1416388:
  Car              = Car_0x17853a8
  Ferrari          = Ferrari_0x16df5d0
  Lobby            = Object_0x1416388
  Protos           = Object_0x1416328
  Vehicle          = Vehicle_0x157e550
  _                = Object_0x1416388
  exit             = method(...)
  ferrari          = Car_0x157e820
  forward          = method(...)
  set_             = method(...)
 
 
 


*リストとマップ
まずはリスト

Io> toDos := list("One", "Two", "Third")
==> list(One, Two, Third)
Io> toDos size
==> 3
Io> toDos append("Four")
==> list(One, Two, Third, Four)
Io> numList := list(1,2,3,4)
==> list(1, 2, 3, 4)
Io> numList average
==> 2.5
Io> numList sum
==> 10
Io> numList at(1)
==> 2
Io> numList append(5)
==> list(1, 2, 3, 4, 5)
Io> numList pop
==> 5
Io> numList prepend(0)
==> list(0, 1, 2, 3, 4)
Io> numList isEmpty
==> false
Io> numList push(5)
==> list(0, 1, 2, 3, 4, 5)

次はマップ
Io> pika := Map clone
==>  Map_0x157b490:

Io> pika atPut("home" , "Tokyo")
==>  Map_0x157b490:

Io> pika at("home")
==> Tokyo
Io> pika atPut("like" , "FPS")
==>  Map_0x157b490:

Io> pika asObject
==>  Object_0x16d9690:
  home             = "Tokyo"
  like             = "FPS"

Io> pika asList
==> list(list(like, FPS), list(home, Tokyo))
Io> pika keys
==> list(like, home)
Io> pika size
==> 2

*シングルトン
Io> Highlander := Object clone
==>  Highlander_0x177f3a8:
  type             = "Highlander"

Io> Highlander clone := Highlander
==>  Highlander_0x177f3a8:
  clone            = Highlander_0x177f3a8
  type             = "Highlander"

Io> fred := Highlander clone
==>  Highlander_0x177f3a8:
  clone            = Highlander_0x177f3a8
  type             = "Highlander"

Io> mike := Highlander clone
==>  Highlander_0x177f3a8:
  clone            = Highlander_0x177f3a8
  type             = "Highlander"

Io> fred == mike
==> true
Io> Highlander == fred and Highlander == mike
==> true

Highlanderは1人。
fred も mike も等しくなる。


普通に作ると等しくはならない。

Io> one := Object clone
==>  Object_0x15727f0:

Io> two := Object clone
==>  Object_0x1579780:

Io> one == two
==> false


*Object clone を破壊する。
  Object clone := "xxxxxxxxxxxx"
とか書くと、
以降はオブジェクトを一切作成できなくなる。
元に戻すには、プロセスを終了する必要がある。

逆にいいことは、以下のこと。
 オブジェクトを形造っている演算子とスロットに
 自由にアクセスできるため、数行の短いコードで
 ドメイン固有言語を作成できる。

*セルフスタディ

 *Ioのいくつかの問題点
  *検索しづらい
  *日本語リソースが少ない
 *質問に答えてくれるIoコミュニティ
  *http://tech.groups.yahoo.com/group/iolanguage/
  *Ioプログラミングガイド
   *http://xole.net/docs/IoGuide_ja.html
 *Ioのイディオムに関するスタイルガイド
  *http://en.wikibooks.org/wiki/Io_Programming/Io_Style_Guide
 
 
 確認してみよう:
 *Ioは強く型付けされた言語化、それとも弱く型付けされた言語か?
Io> 1+1
==> 2
Io> 1 + "one"

  Exception: argument 0 to method '+' must be a Number, not a 'Sequence'
  ---------
  message '+' in 'Command Line' on line 1


 *0は真か偽か?空文字列は?nilは?
Io> 0 and true
==> true
Io> "" and true
==> true
Io> nil and true
==> false

 *プロトタイプに存在するスロットを確認するには?
Io> Car proto slotNames
==> list(timer, type, setTimer, message)
Io> Vehicle slotNames
==> list(timer, type, setTimer, message)
Io> Car slotNames
==> list(type, drive)

 試してみよう:
 *スロットの名前を指定して格納されているコードを実行せよ
Io> ferrari drive
Vroom
==> Vroom
Io> ferrari getSlot("drive")
==> method(
    "Vroom" println
)
Io> ferrari getSlot("drive") call
Vroom
==> Vroom

driveはメソッドだったので、callをつけた。

 *ファイルからIoのプログラムを実行せよ。
c:\IoLanguage>io ../code/io/test.io
Hello, world

これは、パスを通しておくと楽ですね。

コンピュータ
⇒システムの詳細設定
⇒環境変数
⇒Path
に、c:\IoLanguage
を追加すればOK.

コマンドプロンプト上で、io
と打てば、io.exeが起動します。

先ほどの例も、
c:\code\Io>io test.io
Hello, world

となる。



*おわり
Ioはわかりやすくて、書きやすい。
楽しい言語だ。

量が増えてきたら、頭が混乱してしまいそうだけど、
適宜メモとか取りつつ書いていけば
けっこう使えそう?
すぐにコードが打てたのもよかった。

落としてくるだけ。

それではまた次回。