Io Language

このエントリーをはてなブックマークに追加
19デフォルトの名無しさん
↓のみてて思ったんだけど、++とか--みたいな演算子って直接呼べないの?
ttp://blog.xole.net/article.php?id=658

value := 0
value ++ := method(self = self + 1)
value -- := method(self = self - 1)
value ++ println
value -- println

結果はファイルから読み込むと何もでないんだけど、コンソール(?)からやるとなんか出力されるんだよね

> io
Io> value := 0
==> 0
Io> value ++ := method(self = self + 1)
==> method(...)
Io> value ++ println
==> 1
Io> value ++ println
==> 1
Io> value println
==> 0

なんでだろ?
あと、↓のにすると上手く動く。この違いがわからない...orz
value getSlot("++") setScope(value) call println
value getSlot("--") call println
20デフォルトの名無しさん:2008/02/05(火) 03:07:40
>>19
selfに代入しても、元のが変わらんっぽい

Io> value := 0
==> 0
Io> value test := method(self = "banzai!")
==> method(
self = "banzai!"
)
Io> value test
==> banzai!
Io> value
==> 1
217:2008/02/05(火) 03:24:01
>>19
> value ++ println
これは、value ++(println) となって println は引数として扱われる。
んで、メソッドの側で仮引数を指定していないのでなにも起こらない。
コンソールで 1 が返ってくるのは、コンソールがメソッドの返値を表示するようになっているだけで、
println が表示しているわけではない。
> value ++ := method(v, self = self + 1)
とすれば何が起こっているかわかりやすいかも。

>>20
self はローカル領域オブジェクトのスロットなんじゃない?
変わる方がおかしいと思います。
2220:2008/02/05(火) 03:41:13
Io> value := Sequence clone setItemType("float32") setEncoding("number") setSize(1)
==> 0.000000
Io> value ++ := method(self += 1)
==> method(
self += 1
)
Io> value ++
==> 1.000000
Io> value
==> 1.000000

やったー ++ できたよー orz

>>21
そっか、selfも単なるread onlyなスロットだからか・・・
2320:2008/02/05(火) 04:18:45
Io> value := 0
==> 0
Io> value ++ := method(call sender setSlot("value", self + 1))
==> method(
call sender value := self + 1
)
Io> value ++
==> 1
Io> value
==> 1

先生!receiverの名前を得る方法はないんでしょうか!


どうでもいいけど、referenceがページ分けされてないので検索しずらいです('A`)
http://www.iolanguage.com/scm/git/checkout/Io/docs/IoReference.html
247:2008/02/05(火) 04:42:21
>>23
リファレンス読むと、
  call message previous name
で、出来そうだけど実際には previous が無い模様。
ソース読むと、それっぽい実装はあありました。
使えるようになれば、value ++ とか出来そうですね。
ただ、>>21の問題もあるので細工がいりそうですけど。

>検索しずらいです('A`)
以前のJavaScript使った妙なやつよりはマシな気がする。
2520:2008/02/05(火) 05:25:05
絶対にスマートにできる方法があるはず!と思ってソース見たら

Number.c の Number のデータ部分に代入しているのが(DATA(self) = しているところ)、
IoNumber_rawClone、IoNumber_newWithDouble_、IoNumber_copyFrom_ くらいしかなくて、
IoNumber_rawClone は、Clone用、
IoNumber_newWithDouble_は、内部のIoState用、
IoNumber_copyFrom_は、組み込まれてないww(たぶん内部用)

オワタ\(^o^)/
Number copyFrom メソッド実装汁!って本家に言っとくか、パッチなげるかだなw
2620:2008/02/05(火) 05:26:36
ああ、言い忘れた。一応、IoNumber_readFromStream にもあったから、Stream使ったらいけるかも
2720:2008/02/05(火) 06:14:24
連投スマソ。

>>26 のStream関連はまだ使われてないようでした orz

>>24
確かに call message previous で行ける!と思いましたが、
IoMessage_previous の中の実装が ifdef で外されている上に、
Ioのメソッドとして組み込まれてないですね。
28デフォルトの名無しさん:2008/02/05(火) 13:10:12
チラシの裏です。

Windows版でコンパイルしたくなって四苦八苦してたんですが、
downloadページで配布されている Io-2008-01-20.tar.gz が、
ShellExecuteのための shell32.lib がリンクされてねえとか、setenvがねえとか、
OS依存なエラーでwin32環境でコンパイルできなくて、どうなっとるねん!!1

エラーつぶしているうちに、Changelog 見たらWindows関連部分が Fix されてるっぽくて、
http://www.iolanguage.com/scm/git/checkout/Io/
↑見たら直ってて、俺の時間返せー!!! って感じです・・・ orz

とりあえず、git落として最新版ダウンロードしたお
29デフォルトの名無しさん:2008/02/05(火) 18:18:29
最近のバージョンって do( とかで改行すると、エラーで続きが入力できない。
3019:2008/02/06(水) 01:22:28
なるほど、selfはローカルのslotかあ。

というか、前回の>>19で書いた++は1の評価を返してるだけ?
value := 3
value setSlot("++", method((self + 2) println))

value ++ // 5

やたー

ということは...ここは>>19のクロージャか!!w
value := 6
value ++ := block(
block(
value = value + 1
call activated
)
) call

(value ++) call call call call
value println

全然答えじゃねえorz
31デフォルトの名無しさん:2008/02/06(水) 01:48:38
>>30
解決になっとらんでワロタ
327:2008/02/06(水) 03:16:47
無理矢理解決してみた。
v := 0

inc := method(
  res := nil
  recv := call target
  cntxt := call sender
  cntxt foreachSlot(name, value,
    if (recv == cntxt getSlot(name),
      res = cntxt setSlot(name, cntxt getSlot(name) + 1)
    )
  )
  msg := call message
  right := msg argAt(0)
  msg setArguments(list())
  msg setNext(right)
  res ++ := Lobby getSlot("inc")
  res
)

v ++ := getSlot("inc")

v println
(v ++ ++ ++ println)
v println
337:2008/02/06(水) 03:19:22
>>32 書いてて気づいたんだけれど
1 + ; 2
は、 1 + 2 と解釈されるのね。
改行も同様につながってしまう。
そのせいで右辺のメッセージのごまかしが完全じゃない。
34デフォルトの名無しさん:2008/02/06(水) 03:55:34
俺も...と思ったけど、ダメだったorz

value := 0
value ++ := method(
call message setName("call")
call sender setSlot("self", self + 1)
)

(value ++) println //1
value println // 0
35デフォルトの名無しさん:2008/02/08(金) 14:08:19
++の話題、Smalltalkスレで聞いたら、同じような力技でしたw

アラン・ケイも認めた!Ruby>>>>>Smalltalk
http://pc11.2ch.net/test/read.cgi/tech/1150106090/169

> >>165
> やっつけですが、Squeak Smalltalk で。
>
> Object >> inc
>   | sender index |
>   sender := thisContext sender.
>   index := (sender method at: sender pc - 2) \\ 16 + 1.
>   ^sender tempAt: index put: (sender tempAt: index) + 1
>
> | a b before after |
> a:= 1. b := 2.
> before := {a. b}.
> a inc. b inc.
> after := {a. b}.
> ^{before. after} "=> #(#(1 2) #(2 3)) "
36デフォルトの名無しさん:2008/02/08(金) 14:19:36
>>35
Io もレシーバが代入されているスロット名を知る手段があればできるんだけどね。