#>koguroさん
#えっと、method("Hello, world" println) call のcallと、call sender(つまりはcallメソッド?)のcallは別物なんですか?
#前者は特殊構文かなにかですか?
#Io> Car := Objcet clone
Exception: Object does not respond to 'Objcet'
---------
Object Objcet Command Line 1
Io> Vehicle := Object clone
==> Vehicle_0x8cd7ed0:
type = "Vehicle"
Io> Car := Vehicle clone
==> Car_0x8d6af90:
type = "Car"
Io> Car protos
==> list( Vehicle_0x8cd7ed0:
type = "Vehicle"
)
Io> Car proto
==> Vehicle_0x8cd7ed0:
type = "Vehicle"
#上のコードで、Car protosは単にCar protoの結果をリストでくるんだだけのものを返してますが、protosの存在理由は何ですか?
#話が前後する上、色々お尋ねして申し訳ございません。
#Io> obj pr := method(println)
==> method(
println
)
Io> obj pr
Object_0x8d5ef28:
pr = method(...)
==> Object_0x8d5ef28:
pr = method(...)
Io> obj
==> Object_0x8d5ef28:
pr = method(...)
Io> obj pr == obj
Object_0x8d5ef28:
pr = method(...)
==> true
#上の例で、method(println)中の、printlnはobjにメッセージを送っていると考えられます(間違ってないかな?)。
#ここで、
#Io> postOffice := Object clone
==> Object_0x82bd1f8:
Io> postOffice packageSender := method(call sender)
==> method(
call sender
)
#のmethod(call sender)中のcallは、postOffice packageSenderと呼び出したとき、postOfficeにメッセージを送りますよね。
#この両者の挙動は、つまり、someObject someMethod := method(doSomething)
#としたときに、someObject someMethodと呼び出すと、doSomethingがsomeObjectにメッセージを送るという理解で間違いないでしょうか?
#この理解が正しいとするならば、
#Io> Printer := Object clone
==> Printer_0x8c95380:
type = "Printer"
Io> Printer hello := method("Hello, world" println)
==> method(
"Hello, world" println
)
Io> Printer hello
Hello, world
==> Hello, world
#method("Hello, world" println)とを呼び出したときに、どうして"Hello, world"メッセージがPrinterに送られるという挙動にならないのですか?
#とりあえず以上です
#すいません、本質的なことを聞き忘れてました。
#method(doSomething) call
#としたとき、呼び出し元はどことなるのですか?また、それをプログラム上で確認するにはどうしたらよいですか?
#「とりあえず以上です」以下の文章は無視してください。自己解決しました。
#Io> method(call sender) call == Lobby
==> true
#またまた質問ですいません。
#Io> "Hello, world" slotNames
==> list()
Io> "Hello, world" println
Hello, world
#Io> Sequence proto proto proto proto proto
==> Object_0x8bb0558:
= Object_()
!= = Object_!=()
- = Object_-()
.. = method(arg, ...)
< = Object_<()
<= = Object_<=()
== = Object_==()
> = Object_>()
>= = Object_>=()
? = method(...)
@ = method(...)
@@ = method(...)
actorProcessQueue = method(...)
actorRun = method(...)
addTrait = method(obj, ...)
ancestorWithSlot = Object_ancestorWithSlot()
ancestors = method(a, ...)
and = method(v, ...)
appendProto = Object_appendProto()
apropos = method(keyword, ...)
argIsActivationRecord = Object_argIsActivationRecord()
argIsCall = Object_argIsCall()
asSimpleString = method(...)
asString = method(keyword, ...)
asyncSend = method(...)
become = Object_become()
block = Object_block()
break = Object_break()
clone = Object_clone()
cloneWithoutInit = Object_cloneWithoutInit()
compare = Object_compare()
contextWithSlot = Object_contextWithSlot()
continue = Object_continue()
coroDo = method(...)
coroDoLater = method(...)
coroFor = method(...)
coroWith = method(...)
currentCoro = method(...)
deprecatedWarning = method(newName, ...)
do = Object_do()
doFile = Object_doFile()
doMessage = Object_doMessage()
doRelativeFile = method(path, ...)
doString = Object_doString()
evalArg = Object_evalArg()
evalArgAndReturnNil = Object_evalArgAndReturnNil()
evalArgAndReturnSelf = Object_evalArgAndReturnSelf()
for = Object_for()
foreachSlot = method(...)
futureSend = method(...)
getLocalSlot = Object_getLocalSlot()
getSlot = Object_getSlot()
handleActorException = method(e,
#あれ、pasteが途中でちぎれてますね
#Io> Sequence proto proto proto proto proto
==> Object_0x8bb0558:
= Object_()
!= = Object_!=()
- = Object_-()
.. = method(arg, ...)
...
print = method(...)
println = method(...)
Io> Sequence proto proto proto proto proto slotNames contains println
false
==> false
#ここでtrueを期待しているのですが、違うのでしょうか?
#ここは一度にpostできるデータサイズに制限をかけてます。長いコードはgistあたりに貼ってリンクしてもらうのが良いかと。
#自分自身 Io の言語仕様をきちんと把握しているわけではないので、間違ったことを言うかもしれませんが、
#method("Hello, world" println) call のcallと、call senderのcallは違います。
###method("Hello, world" println) call と書いた場合、
#「method("Hello, world" println) で生成されたBlockオブジェクト」に「callメッセージ」を送るという意味になります。
#call sender は、「ローカル環境にある "call" という名前のオブジェクト」に「senderメッセージ」を送るという意味です。
#callという名前が同じでも、指している内容が異なります。
#次に protos と proto の関係ですが、Ioのオブジェクトは多重継承を許しているので、複数のプロトタイプとなるオブジェクトを持つことができます。そのため、プロトタイプのオブジェクトはリストとして管理されています。
##protoはそのリストの最初のオブジェクトを返すメソッドです。
##postOfficeの例の場合、postOffice packageSenderと呼び出した場合の method(call sender)中のcallは、ローカル環境のcallを参照します。なので、postOfficeにメッセージを送っているわけではありません。
#最後に、method("Hello, world" println) では、"Hello, world" は文字列リテラルなので何かを参照しているわけではありません。なので単に "Hello, world" に対して printlnを送っているだけです。
#method(println)と書いた場合、最終的にprintlnはobjにメッセージを送りますが、それはローカル環境に printlnがないためです。
#Io> a := Object clone
==> Object_0x7feffacb3eb0:
Io> a foo := method(println := 1; println)
==> method(
println := 1; println
)
Io> a foo
==> 1
#ローカル環境に println があれば、それを返します。
#「メッセージを送る」 == 「スロットの中から、その名前のオブジェクトを取ってきて Block ならcallを呼ぶ」ことかと思うけど、いまいち自信がない。
#回答ありがとうございます。ところで、Iolanguageの評価規則について質問があるのですが、
#Objectのスロットにwritelnがあるかどうか調べたいとき、
#Object slotNames contains writeln
#と書いたのですが、どうやら期待していた挙動をしません。
#Object slotNames contains "writeln" では?
#Io> Object slotNames contains "writeln"
==> writeln
Io> Object slotNames contains "hatena"
==> hatena
#こんな感じの挙動になってしまうのですが
#あっ、括弧が必要だ
#Object slotNames contains("writeln")
#Io> Object slotNames contains("writeln")
==> true
Io> Object slotNames contains("hatena")
==> false
#一つお伺いしたいのですが、koguroさんは、Iolanguageをどうやって学びましたか?
#僕はいま、七つの言語 七つの世界 という本を読んでいるのですが、結構ハードルが高くて難しいです
#あと、英語でもいいのですが(できれば日本語)、初心者をサポートしてくれるコミュニティーみたいな所ってありますかね?
##コミュニティはよくわかりませんが、英語ですけど、mailing listとかircで聞くのがいいんじゃないでしょうか。
#7つの言語〜は各言語を駆け足で見てくので、他の言語を色々知ってる人なら類推でさらりと済ませられるけど、読んでて途中でわからなくなるようなら、あの本だけで学習しようとせずにその言語のみを扱ったマテリアル (本とかチュートリアルとか) を見ながらやった方が良いように思います。もう何か参照してるかもしれませんが。
##>koguroさん >shiroさん そうですね。ただ、Iolanguageは書籍がないので、koguroさんが知っていたというSmalltalkから勉強してみることにします。
#Ioはめっさ検索しにくい名前なのが苦しいですね。Gaucheもあんまり言えないけど (日本語の情報探すだけならいいけど)。
#ioからまず連想するのがinput/outputですもんね
#Smalltalkなら、勉強会が定期的に開催されているみたいなので、近くにお住まいなら行ってみてはどうでしょう。
##>koguroさん ありがとうございます。
#HaskellのQuickCheckとかClojureのtest.generativeに似た生成的テストモジュールを書いてるんだけど、ランダムデータ生成の部分は他にも利用できるので別モジュールにしたい。どんな名前がふさわしいか。
#提供されるのはジェネレータやそのコンビネータなので、gauche.generatorのサブカテゴリと考えてgauche.generator.random という案。ちと長いのが欠点なのと、将来拡張してゆくと色々な他のモジュールに依存する可能性があるのでgauche.*の配下に置かないほうがいいかも、とも思う。
#色々な分布のデータからランダムサンプルする機能を提供すると考えると、util.samplerというのも考えられる。 ただ、samplerは分野によって具体的に指すものが違ってくるので、こういう一般的な階層に置いちゃって良いものか。もうちょい特定的なトップレベルカテゴリを作った方がいいかな。data.samplerとかstat.samplerとか。だがトップレベルカテゴリを作るとなると、それを将来どう使うかもある程度考えないとならない。
#他の言語でこのへんどうしてるか知ってる人いる? ちなみにQuickCheckは自分の階層下にデータジェネレータを抱えてるみたい (Test.QuickCheck.Gen)。Clojureは独立した階層 (data.generators)。
#あれ、twitterに流れてない? API制限に引っかかったかな。