#今のところdata.samplerという名前に傾きつつあるのだけど、もう大学でやった確率の話を忘れかけているのでいまいち自信が持てない。
#data.samplerモジュールのpoissonとかgeometricという手続きは、それぞれポアソン分布/幾何分布の確率変数からランダムな値を引っ張ってくるジェネレータを返す、という動作はokか。
#gaussianがガウス分布で乱数を生成するジェネレータを返す、っていうのはまあ良いと思うんだけど。ポアソン分布とかあまり使ったこと無いので感覚がわからない。
#何が引っかかるかというと、samplerという名前だと母集団がNやRってだけじゃなくて、別に集合を与えてそこから引っ張ってくるって場合も含意しちゃうからかな。
#Clojureみたいにdata.generatorってすれば、他に集合を与えるのではなくランダムデータを生成してるんだ、ってはっきりするけど、名前がgauche.generatorと似ちゃうので紛らわしい。
#gunfoldの簡易版として、シードから値と次のシードを多値で返すものをわたすようなものがあると、例えば、検索結果の複数ページを列挙していくような流れを抽象化できるのかなあとか考えました(この例ではシードをurl、値をhtmlとします。次のシードはhtmlの「次へ」リンクから取ります)。値を取得する部分と次のシードを取る部分が重なるので、gunfoldでは扱いづらいです。
#終了判定をどうするかということはあるのですが・・・
#素直にdata.randomでいいような気がしてきた。
#>yamasushi 確かにひとつの関数で次のシードの計算と値の生成をやりたい場合はgunfoldは使えないですね。再帰にフォールバックするのも癪ではあるけど…
#Smalltalk勉強するのにおすすめの書籍とかってあります?
#Smalltalk 80: The Languageを読もうかと思っているのだが、邦訳版が絶版なので英語で読むほかない。
#乱数生成はRNGという略語がそれなりに浸透してるけどランダムデータ生成がRDGという略語は浸透していると言い難いので、
#data.rdg というのを考えたけど、何が何だかわからなさそう。
#; p .... seedから中間データを計算
; f .... 中間データから値を計算
; g .... 中間データから次のseedを計算。次がないときは#f
(define (gunfold-modoki p f g seed)
(let1 s seed
(^ ()
(if s
(let1 d (p s)
(set! s (g d) ) (f d) )
(eof-object)
) ) ) )
#こんな具合なものをつくると、htmlからつぎつぎに「次へ」リンクをたどってページを取ってくる流れが書けます。
#多分unfold系の発想としては、その「中間データ」に相当するものをseedにするのだと思います。
#中間データをシードにするとなると、「url」が中間データ的な役割になってしまいます。最初のシードを作るときに「url」からシードをとり、次のシードを取るときにおなじ手続きでシードをとることになって、記述が重複してしまいます。
#(define (make-webobj uri :key (get-uri sxml-get-http-uri))
(let1 obj #f
(^ ()
(if uri
(begin (unless obj (set! obj (get-uri uri))) obj)
#f ) ) ) )
; sxml-get-http-uriはuriからsxmlを取得する関数
#このようなものを用意するとgunfoldでもいいわけですね。
#これを短くできる表現がありましたでしょうか? 遅延して取得するみたいな。
#必要になったときにobjを取得してキャッシュしておきたい、ということですよね。シード自体を
(delay (and uri uriから取ってきてパーズする処理))
としておいて、必要になった時にforceすれば一回だけ取ってきて結果をキャッシュしてくれますよ。つまり
p = (force seed) ; uriが#fならforceした値も#f。そうでなければ取得にゆく
f = (get-value (force seed)) ; ジェネレートすべき値をパーズした結果から取得
g = (get-next-url (force seed)) ; 次に読みにゆくurlをパーズした結果から取得
#>shiroさん ChatonにはすでにCLやHaskell部屋などがありますが、その他の言語部屋(Other languages)を作っていただけるとありがたいです。
#Gauche部屋でIoやSmalltalkの話題を出すのは気が引けるので。
#迷惑になるといけないので手短かに。
#んー、今くらいの量なら私は別にGauche部屋使ってもらっても構わないですよ。困るとすればtwitterでchaton_gaucheフォローしてる人のところにだだだっとGauche以外のメッセージが流れてしまうことくらいでしょうか。
##twitterの方にたくさん流したくなければ、長いメッセージを書いて貼り付けるとか、pastebinやgistに書いてリンクを貼るとかしてもらえれば。
#>sumim >shiro 了解です。
#>iyanaha Io、Smalltalk のことは Twitter で直接つぶやいてもらえれば、ある程度フォローできます。込み入った話でしたら他の方法ででも。
#; sxml-get-http-uriはuriからsxmlを取得する関数
(define (make-lazy-webobj uri :key (getop sxml-get-http-uri) )
(delay (and uri (getop uri) ) ) )
(define (rip-url-from-page-all url)
($ for-each print
$ lconcatenate $ generator->lseq
$ gunfold
(^s (not (force s)) )
($ map
$ データを抽出する部分
$ force $)
($ make-lazy-webobj
$ 次のURLを抽出する部分
$ force $)
(make-lazy-webobj url) ) )
#こんなかんじに書けました。
#ご教示ありがとうございます。
#(define (rip-url-from-page-all url)
(define (if-conv-uri uri)
(if (string? uri)
(regexp-replace #/&/ uri "&")
#f ) )
(print url)
($ for-each print
$ lconcatenate $ generator->lseq
$ gunfold
(^s (not s) )
($ map ...... データを抽出 $)
($ sxml-get-http-uri
$ ..... 次のurlを抽出する $)
(sxml-get-http-uri url) ) )
#いま、shiroさんの指摘された点に気が付きました。(汗
#遅延構造にする必要があまりなかったのでした・・・
#sxml-get-http-uriはuri文字列ならデータを取得、#fなら#fを返すという仕様ですが、この#fなら#fを返すというパターンはよく使います。