#実際には、上位手続きは必ずしも失敗をチェックする必要はありません。例えばPettalのAjaxディスパッチャは、Ajax処理を行う手続きからの戻り値を、そのままオペレーションログに記録した後、上位手続きにエスカレートしています。
#でもIconのような仕組みがあれば、もっとシンプルに扱えそうですね。実はPettalでは、実行時エラーもtry/catchで捕まえて、(:result "failure" :reason "file_read_error" ...)のような形で戻しています。Iconならこれも、簡単に扱えそうな気がします。
#ディスパッチャのように、値の中身を見る必要がなくて値を受け渡すだけならそうですが、値の中身を見る必要があったらチェックが必要ですよね。MaybeモナドやGoal-directed executionは、値の中身を見る必要がないケースをデフォルトでシステムがあらかじめ取り除いてくれてるようなものです (見る必要があれば明示的に書く)。
#現実的には、どっちのパターンが多いのかによってどっちが便利かは左右されそうですね。エラーチェック→中身見る、のパターンが多ければシステムでサポートしてくれた方がいい、っていうことかも。
#そうですね。でもシステムレベルで仕組みが決まっているのは嬉しいかも。私のやりかたはちょっと「チカラワザ」のにおいがしますし。
#もちろん、一貫性が維持できること、が前提なのですが。私にとって、シンプルで一貫性があり、ライブラリの直交性が高い言語が最も魅力的なので。RubyやPythonではなく、Gaucheを使わせてもらっているのも、そのあたりが最大の理由だったりします。
#すみません、前述の
#(define (get-kv keylist kvlist . default)
(let* ((result (apply ~ kvlist keylist)))
(cond ((eq? result '())
(cond ((eq? default '())
#f)
(else
(car default))))
(else
result))))
#
#なのですが、重大な問題を見つけちゃいました。
#これだとバリューni'()
#これだろバリューに'()が含まれていた場合も#fが返されちゃいますね。
#そういえばこの問題を解消するため、下部手続きは値のリストを作成することにしたんだった。
#s/これだろ/これだと/
#date->stringで使える書式文字列がstring->dateで使えるとは限らない罠
#~1とか~Tとか~Nは使えないんですね
#~Nはあってもいいんじゃないかと
#diff --git a/ext/srfi/srfi-19.scm b/ext/srfi/srfi-19.scm
index 39214a2..ae12991 100644
--- a/ext/srfi/srfi-19.scm
+++ b/ext/srfi/srfi-19.scm
@@ -1144,6 +1144,8 @@
(slot-set! object 'minute val)))
(list #\S char-numeric? ireader2 (lambda (val object)
(slot-set! object 'second val)))
+ (list #\N char-numeric? ireader2 (lambda (val object)
+ (slot-set! object 'nanosecond val)))
(list #\y char-fail eireader2
(lambda (val object)
(slot-set! object 'year (tm:natural-year val))))
#これでいける?
#本当は9桁縛りとかしなきゃいけないのかな
#対象でないのがちょっと気持ち悪いですね。string->dateは、入力がマッチしなかった時の振る舞いがはっきり書いていない、などunderspecifiedな点もあるので、Gaucheで独自拡張しちゃうのはありだと思います。
#ふむ
#day jobが終わったらちょっとやってみます。testも書いた方がいいんですよね?
#ありゃ、この差分じゃだめだね。やっぱりちゃんと調べてちゃんと書かないと
#diff --git a/ext/srfi/srfi-19.scm b/ext/srfi/srfi-19.scm
index 39214a2..8d83764 100644
--- a/ext/srfi/srfi-19.scm
+++ b/ext/srfi/srfi-19.scm
@@ -1144,6 +1144,8 @@
(slot-set! object 'minute val)))
(list #\S char-numeric? ireader2 (lambda (val object)
(slot-set! object 'second val)))
+ (list #\N char-numeric? ireaderf (lambda (val object)
+ (slot-set! object 'nanosecond val)))
(list #\y char-fail eireader2
(lambda (val object)
(slot-set! object 'year (tm:natural-year val))))
#こうだった
#本当はireader9とか作るべきだけど
#でも、~Nに対して9桁じゃない数字列を与えた時に、前に0パディングして考えるべきか後ろにパディングすべきかは微妙に難しい問題ですね
#2011-02-01 00:00:02,719を~Y-~m-~d ~H:~M:~S,~Nで読み込もうとした時、719は719nsではなく719000000nsとして読んで欲しい気がする
#それは小数として読むって感じだから、それなら~Nじゃない方がいいかもね。date->stringの方で ~f があるから、読む時も ~f を有効にするとか。
#おおお ~f 見落としてた
#"Oleg Kiselyov, computer scientist, already solved that. In the type system." And of course, with hygienic macros. http://haskell.spreadshirt.com/oleg-already-did-it-A6499531 #このサイト面白いですね。自分で店が開けるんだ。
#昨日の「失敗」の取り扱いですが、こんなのがあればいいのかな。
#(define-syntax or-condition
(syntax-rules ()
((_ c)
#f)
((_ c expr rest ...)
(guard (e ((condition-has-type? e c)
(or-condition c rest ...))
(else (raise e)))
expr))))
#こんなふうに使うとか
#(define (get-kv key-list kv-list default)
(or-condition <error>
(fold get-keyword kv-list key-list)
default))
#どうなんだろう?
#Gaucheだと例外があるから、例外キャッチの簡単な構文があればいいのかな。(guardだとちょっと高機能過ぎるのかも)
#問題設定を少し変えてよければ、階層構造 SXML で表現して sxpath でアクセスという手もありますね。結果は常にリストで返るので List モナド的
#C++ とかだと安全にコールスタックの深いところから一気にトップレベルに戻ってくる制御構造は例外しかないですけど、Scheme だと普通に継続使えばいいから、選択肢が多くてかえって迷うかも?
#トップレベルっていうか、ある程度上の層、という意味で。