Gauche:WishList:pending
Gauche:WishList に出たもののうち、直接は採用しなかったもの。 できるだけ代案を提示しています。
- ssax:xml->sxml で実体参照の変換
- eval内で、macroやspecial formの実体を、macroやspecial formとして扱ってほしい
- useとprovide
- gauche.collectionにappend-mapとfilterあたりも
- use に複数引数やワイルドカードを
- エラーメッセージのclosureがlambdaを指し示す場合は、その出現順番を示して欲しい
- 失敗したテストの行番号を表示
- 変換ポートの CES を知りたい
- with-sigmask
- charsetオブジェクトの表示
- 用語(マニュアル)
- 期待したエラーが起こるかテストしたい
- リストリテラル および ベクターリテラル
- unbound variableはコンパイル時に
- gauche.netをwin9x系でも使えるように
- 環境変数のキー一覧を取得する手段があれば嬉しい(かも)
- defined?
- Literate comment
ssax:xml->sxml で実体参照の変換
齊藤 (2009/04/11 21:50:45 PDT) : ssax:xml->sxml では gt 等の xml において最低限の実体参照しか理解しません。 xhtml を解釈させようとすると nbsp 等を理解できずエラーになってしまいます。 オプショナルな引数で実体参照の情報を受取ってくれるようになっていると便利かと思いました。
ssax:make-parser の DOCTYPE ハンドラでやればいいのですが…
(define (parser xml-port) ((ssax:make-parser DOCTYPE (lambda(port docname systemid internal-subset? seed) (if internal-subset? (ssax:skip-internal-dtd port)) (values #f '((nbsp . " ") (copy . "(c)")) '() seed)) ) xml-port '()))
他のハンドラが省略できないらしくエラーになってしまいます。 NEW-LEVEL-SEED, FINISH-ELEMENT, CHAR-DATA-HANDLER は ssax:xml->sxml と同じでかまわないので、あらためて書くのも面倒な感じです。
- Shiro(2009/06/01 12:05:36 PDT): 確かに。他のハンドラは省略可能なのに
NEW-LEVEL-SEED, FINISH-ELEMENT, CHAR-DATA-HANDLER の3つはrequiredなんですね。
本家のソースをみても簡単な方法は用意されてないようです。たぶん本来の思想としては、
doctype handlerがちゃんとDTDをパーズして定義されてるentityを取ってくることを
想定してて、別経路でentity definitionsを注入するのは邪道ってことなんじゃないかと
想像します。
Gauche側でユーティリティとしてxhtml->sxmlを提供してしまう、というのが 便利かもしれません。
ぐぐったら、ssax内部のデフォルトのentity tableを置き換えちゃうって荒技が 出てきました。とりあえずのworkaroundにはなるかも? : http://article.gmane.org/gmane.lisp.scheme.ssax-sxml/328 - 齊藤(2009/09/01 20:00:52 PDT) : Gauche だとこんな感じでなんとかなりました。 スジの悪い方法ですが、手軽ですね。
(define xhtml-entity '((nbsp . "\u00a0") (copy . "\u00a9"))) (use sxml.ssax) (with-module sxml.ssax (set! ssax:predefined-parsed-entities `(,@(with-module user xhtml-entity) ,@ssax:predefined-parsed-entities))) (call-with-input-string "<xml>©</xml>" (cut ssax:xml->sxml <> '()))
eval内で、macroやspecial formの実体を、macroやspecial formとして扱ってほしい
→Gauche:#<syntax>や#<macro>の評価 にて検討中。 実装は簡単だけれど、一貫性のある仕様にするのが難しい。
useとprovide
useする時は、 (use hoge.fuga) なのに、provideする部分では、 (provide "hoge/fuga")なのは、ちょっと分かりにくいです…‥。 -- nekoie (2004/04/07 10:25:24 PDT)
- Shiro: provideはrequireと対応するからです。
そして、 use = require + importです。
まあ、ここは多少歴史をひきずった感がありますね。
require/provideの方がより基本的なメカニズムで、いろんなSchemeでサポート
されています。useはその上にのっかるユーティリティという感じでした。
ところが、実際に使ってみたらuseはとても便利で、requireなんかほとんど
使わなくなってしまったという…。
- useとかselect-moduleではhoge.fugaで指定するのに、provideだけ"hoge/fuga"なのは、はまりやすい気がするので、provideの方もラッパーを作って統一するのはどうでしょう。 -- nekoie
(define-syntax provide-module (syntax-rules () ((_ module) (provide (module-name->path (quote module))))))
- require/provideはファイル単位のメカニズムなのに対し、 モジュールはファイルとは基本的に関係ないのです。 useは運用で両者を一致させていて、大抵の場合それで便利に 使えるんですが、一つのファイルに複数のモジュールが入っていたり 一つのモジュールが複数のファイルで定義されていたりする場合が 時々あるので、provideをモジュール単位にすることができません。 (javaやperlのようにファイル=モジュールに固定しなかったのは、 「ファイル=モジュール」という方法の制限を不便と 感じたからです)。 --Shiro
- useとかselect-moduleではhoge.fugaで指定するのに、provideだけ"hoge/fuga"なのは、はまりやすい気がするので、provideの方もラッパーを作って統一するのはどうでしょう。 -- nekoie
- Shiro(2008/11/22 16:37:29 PST): provideがファイル中に無ければrequireしているfeature を自動的にprovideする、という機能をつけたので、provideを書く必要性は ほぼ無くなりました。
gauche.collectionにappend-mapとfilterあたりも
コレクションで扱っていると上記二つについては 欲しい場面に頻繁に遭遇したんで要望だけだしときます。cut-sea:2007/09/15 03:15:50 PDT
Shiro(2007/09/15 03:38:37 PDT): 0.9以降(もしかすると1.0以降)に、 srfi-1とgauche.collection, gauche.sequenceあたりの大幅な見直しを考えています。
- srfi-1 の関数の多く(たぶんlset関係以外ほとんど)をgeneric functionとして組込みで提供。
- gauche.collection, gauche.sequenceも組込みにする。
- generic functionのオーバヘッドを避けたい場合用に、リスト専用の関数を list-なんとか という名前で提供。
例えば fold や filter はデフォルトでジェネリックで、型特定の速い実装が 使いたければ list-fold/string-fold とか list-filter/string-filterみたいな 専用関数を使えると。
mapやfoldをデフォルトでジェネリックにすることで性能が大幅に低下するのは 嫌なので、この変更はジェネリック関数の最適化とセットになります。
use に複数引数やワイルドカードを
既出でしたら、すみません。
gaucheの便利な機能は拡張モジュールに有ることが多く、useは良く書くのですが、どう書く.orgなんかだと、少ないコードで書きたくなって、useの列挙が気になります。
とりあえず、useには、複数モジュールをかけるようにして下さると、助かります。
プロトタイピング程度では(use gauche.*)とかしてみたりもしたいのですが、いかがなもんでしょうか。あらかじめ、ワイルドカードを使われること前提で機能や名前の衝突のないモジュールを作らなければいけないのは、辛いとは思いますが。
自分の作ったモジュール群をまとめてロードしたい場合には、ワイルドカードが使えると大変助かります。(use usermod.*)みたいな感じで。
- Shiro(2007/08/30 13:10:31 PDT): そのような機能は欲しいと思ってて、インフラとなる
APIも作ってあるんですが (library-foldとか)、高レベルAPIに良いものを
思いつかないので保留になっています。
- useについては、将来オプションが指定できるようにするつもりです
(ロードするライブラリのバージョン指定とか、インポートするシンボルの
プレフィクスとか)。useで複数引数指定を可能にしてしまうと構文拡張が面倒です。
- 納得しました(質問者)
- 下の方の「srfi-*と書きたい」という議論で出たように、モジュールの中には 組込み関数をシャドウするものがある可能性があり、ワイルドカードは危険な場合が あります。具体的には、(use util.*) などとしているライブラリがあったとして、 組込み関数をシャドウするutil.xxxが追加された途端に壊れてしまう、という ケースです。相互の関連が明白でないものが影響を及ぼしあう、というのは モジュラリティの破れであって、問題の追跡が難しくなることが多いので、 なるべく避けたいです。
- 「まとめてロードすることが多い」自作モジュール群があるのなら、extendを
使ってひとつのモジュールにまとめてしまうことができます。
(define-module usermod (extend usermod.x usermod.y usermod.z)) と
書いたusermod.scmを作っておけば、(use usermod)だけでusermod.x, usermod.y,
usermod.zをuseしたのと同じになります。
- ワイルドカードは、「フォルダに入れるとuseされる」というどこぞで見たようなことをしたいというのもあります。逆に「フォルダから外すとuseされない」とも。この機能が善なのか悪なのかはわかりませんが、ものぐさには助かります。
- コンパウンドモジュールは使ったこと無かったので、試してみます。これで今やっている「cgiの共通部分ライブラリを集中管理」には十分だと考えてます。
- useについては、将来オプションが指定できるようにするつもりです
(ロードするライブラリのバージョン指定とか、インポートするシンボルの
プレフィクスとか)。useで複数引数指定を可能にしてしまうと構文拡張が面倒です。
Shiro(2007/08/31 02:02:17 PDT): 「フォルダに入れるとuseされる」という、 いわばプラグイン機能みたいな感じのものは、言語処理系レベルよりは 上のレイヤ (フレームワークとかアプリケーション) でやるべきかなあと 思います。例えばこんなマクロをmyframeworkモジュールで定義しといて:
(define-macro (load-plugins) `(begin ,@(library-fold 'plugins.* (lambda (mod path r) (cons `(use ,mod) r)) '())))
アプリケーションコードでこんなふうにすれば:
(use myframework) (load-plugins)
plugins/ ディレクトリに放りこんであるモジュールがだーっとuseされると。
エラーメッセージのclosureがlambdaを指し示す場合は、その出現順番を示して欲しい
*** ERROR: wrong number of arguments for #<closure (main #f)> (required 2, got 1)
というエラーメッセージがありますが、#fではなくて、手続き内でのlambdaの出現順番を表示してもらえればデバッグが助かります。
*** ERROR: wrong number of arguments for #<closure (main &3)> (required 2, got 1)
みたいに。
- Shiro(2007/08/25 18:07:35 PDT): 良さげなアイディアですが、マクロによってlambdaが 挿入されたり順番が変わったりするケースがあるので順序でアイデンティファイするのは 難しいかも。 引数の名前のリストは保存しようと思えば出来るはずなので、それを表示すれば 手がかりになるかな?
- そっか。macroか…。引数無しのclosureの場合が…。lambdaに任意のラベルを付けらるというのも良いかも知れません。
(f a (lambda (x y) #;;appnd (append x y)))
ってな感じで。エラー時にこれ"も"表示してもらえれば、再現性のあるエラーなら、怪しいところにラベルをつけて特定するのに役立ちます。まあ、local defineすればエラー時に名前が出てくるので、そうして対処しているわけですが。
- Shiro(2007/08/29 19:39:13 PDT): どうせプログラマが名前を書くのなら、
srfi-31のrecを使えばほぼ同じ手間で名前をつけられますよ (Cf. GaucheRefj:rec)。
(f a (rec (appnd x y) (append x y)))
- 早速試してみました。これなら、括弧の数を増やさずlambdaをrecに書き換え、引数の前に名前を足すだけだし、括弧の外側に影響が全くないので、デバッグにも最適です。知りませんでした。エラーメッセージにもちゃんと出てきますし。これから活用します。(もっと早く知っていれば苦労が少なくて済んだのにorz)
失敗したテストの行番号を表示
(2006/05/14 01:29:10 PDT): gauche.testのtest*が失敗したとき、test-endが出力するエラーレポートの各行に、ファイル名と行番号を出力すると便利じゃないでしょうか。同じようなテストがたくさん並んでいるときに、失敗したテストを見つけるのが手間なので。
- Shiro(2006/05/14 02:21:35 PDT): そうっすねぇ。一応NAME引数がそのために用意した ものではあるんですが… 本来は、複数のテストをマクロで生成したり、 高階関数化して総当たりでテストを走らせるというようなスタイルを 想定しているんですが、それだとtest関数の行番号って意味無いんですね。 私自身、確かに単純なテストをずらずら並べることもあるんですが、 テストのメンテナンス性やカバレッジの確保を考えると、 なるべくテストはパラメタライズしておくべきだと思います。 (ext/charconv/test.scm なんかが最も極端な例です。)
変換ポートの CES を知りたい
leque(2006/09/13 22:26:58 PDT):
(format oport "<?xml version=\"1.0\" encoding=\"~A\"?>" (or (port-ces oport) 'utf-8))
のように使える手続きが欲しいです。
- Shiro(2006/09/14 05:41:06 PDT): なるほど。ただ、ポートはレイヤリングされる 可能性があるので、今、手にしているoportが変換ポートなのか、変換ポートにさらに 何かのレイヤがかぶさったものなのか (例えば出力のログを取るようなデバッグ ポートが挿入されたりとか) によって動作が変わってしまうのはちょっとまずい 気もします。アプリケーションの末端で、そういうレイヤリングが無いことが わかっている場合には便利だと思いますが。一般的にやるなら、 最終出力エンコーディングを別に管理せざるを得ないような気がします。
- Shiro(2007/05/22 17:50:57 PDT): 上記の理由から、ポートのCESを取ることに 意味がないと考えます。将来、ポートのチェインにアクセスする インタフェースを用意するかもしれませんが、それでも確実ではないので (ポートのチェインが一本道とは限らない)、これはポートより上のレイヤで 対応すべきかと。www.cgiはcgi-output-character-encodingというパラメータで 出力のエンコーディングを管理してますが、そういった感じでフレームワークの レイヤで処理するのが正しいと思います。
with-sigmask
び(2006/05/26 02:20:22 PDT): 特定のブロック内だけシグナルマスクを変更する関数が欲しいです。
(define (with-sigmask how mask thunk) (let1 old_sigset #f (dynamic-wind (lambda () (set! old_sigset (sys-sigmask how mask))) thunk (lambda () (sys-sigmask SIG_SETMASK old_sigset)))))
こんな感じでしょうか。
- Shiro(2006/09/14 05:35:30 PDT): これは微妙だなあ。上記のコードは、before thunk中の sys-sigmaskの実行後からbody thunkに入る前や、body thunkが実行されてから after thunkのsys-sigmaskの実行までの間にもmaskが有効になるのだけれど、 そういうlooseなセマンティクスで良い場合と、もっとstrictにやりたい場合が あるような気がなんとなくする。なんとなくだけど。ハンドラの設定も必ず 絡んでくるはずだし、with-sigmaskという単位が抽象化のユニットとして使い勝手が 良いかどうかに確信が持てない。具体例歓迎。
- び(2006/09/14 20:22:06 PDT): 現状のKahuaで、オブジェクトDBへの操作中にシグナルをブロックするのに使っています。確かに、上記の実装はかなりルーズなので、特にスレッドが絡んだりすると危険な気もしますね。厳密にやろうとすると、Schemeコードで実装するのは厳しいかしら。
- Shiro(2007/05/22 17:50:57 PDT): アプリによって要求される条件も変わりそうなので、 当面はアプリごとに対応してもらうってことでこっちに移します。
charsetオブジェクトの表示
charsetオブジェクトの表示があまり見やすくありません。たとえば#[@A-Z]は#[@-Z]と表示されてしまい、この文字集合に含まれる文字が何か分かりにくいです(この程度の例ではたいしたことありませんが、もっと要素の多い文字集合では確認に手間がかかります)。入力したときの形か、あるいはアルファベットと数字以外は範囲指定しない形で表示するようになると使いやすいです。(2004/10/17 19:12:20 PDT)
- Shiro(2005/10/27 19:59:29 PDT): 「入力した時の形」は手続き的に生成されるchar-setで 使えません。また、「アルファベットと数字以外は範囲指定無し」だと漢字全てを含む char-setを表示させたら悲惨なことになります。「ASCIIの範囲内で、アルファベットと 数字以外は列挙」くらいが妥当でしょうか。私の中での優先度は低いですが、パッチは 歓迎します。
- Shiro(2007/05/22 17:50:57 PDT): すぐに直す予定はないのでこっちに移動。 パッチは歓迎中。
用語(マニュアル)
Rui (2006/06/02 20:35:18 PDT):「サンク」という用語、Gaucheのマニュアルに説明なしに現れているようです。第1章か初出の箇所のどちらかに説明があれば親切だと思います。私は「アリティ」という用語がわからなかったのでこれもついででお願いします。
- Shiro: なるほど。マニュアルについては、不連続に書き進めていること、今後構成に大幅な変更がないとは言えないこと、そして最初から通読されることを想定していないこと、という要素があるので、むしろglossaryの章をappendixに入れるのがいいかと思います。
期待したエラーが起こるかテストしたい
2006/05/31 07:29:28 PDT: gauche.test で、エラーが起こるかどうかだけでなく、 起こったエラーが期待した condition に属するかどうかテストできると 便利だと思います。
- 2006/06/05 22:51:41 PDT: test/dbidbd.scm と同じように with-error-handler を使えばだいたい同じことができますね。
こちらの方がシンプルでいいかなあ。
(test* "msg" <expected-condition> (with-error-handler (lambda (e) (class-of e)) (lambda () (proc arg))))
- Shiro (2006/09/14 05:35:30 PDT): guardを使うともっと簡単。
(test* "msg" <expected-condition> (guard (e (else (class-of e))) (proc arg)))
- Shiro (2010/04/13 13:45:33 PDT): 最近のGaucheでは test-error手続きで
期待するconditionを指定できるようになっています (GaucheRefj:test-error)。
(test* "msg" (test-error <expected-condition>) (proc arg))
リストリテラル および ベクターリテラル
nobsun(2006/09/21 22:27:53 PDT)
cut-seaさんと話しててでてきた思いつき.
`(,x ,y ,z)
を
[x y z]
とか
`#(,p ,q ,r)
を
#[p q r]
のように簡単に書けるといいかも.でも [,] は (,) と同じになっちゃって るから,{,} かなぁ.
{x y z} ;; リストリテラル #{x y z} ;; ベクタリテラル
ううむ。
- Shiro: リテラルというよりコンストラクタだよね。これは。 Lisper的には、統一性を求めるなら (constructor arg ...) の呼び出しがあるし、 短く書きたいならバッククオートでもいいじゃん、ってことになっちゃうんじゃないかと。 あんまりそそられないなあ。それとsplicingはどうするの、とか。
- Shiro(2006/09/22 14:02:42 PDT): これはcut-seaで出てるlazy Schemeからみの 話だと思うけれど、「不定長の引数が取れない」ことを補うためならば、 コンストラクタをマクロドメインに持ってくるって手があります。つまり、 (list x y z ...) の 'list' を構文にしちゃう。([x y z] みたいな 話も結局構文を導入してるわけで、同じことですが。) (apply list xxx) が出来なくなるのは別に良いけど、 ((flag? list vector) x y z) みたいな呼び出しは出来なくなりますな。 これは [] 構文を入れても同じことですが。
- ですねぇ。本質的にlazyになると結構波及範囲が広くて、だいぶ違うなという感想。
この書式の導入案は可変引数を取れないが故に出てきたものです。
(というかHaskellに実装されてるのが必然なんだろうなぁと納得してマネただけ)
R6RSでの[]の規定もあるので、正直Gaucheに入れるべきとは思わないですが、 ベクタで#(1 2 3)というのが、そのまま値として書けるってことを考えると、 同じようにリストにもリテラルが書ける書式があってもいいんじゃないかとは思いました。cut-sea:2006/09/22 22:16:49 PDT - Shiro: #(1 2 3)はR5RS的に不正ですよ。Gaucheの今の版ではたまたま '#(1 2 3) と
見做しているだけで。それから、「リテラル」と「コンストラクタ」は違います:
(let ((x 0) (y 1)) '#(x y)) => #(x y) ;; リテラル (let ((x 0) (y 1)) (vector x y)) => #(0 1) ;; コンストラクタ
欲しいのは後者ですよね?
- まぁ.(list x y z ...)があるんだからそれ使えばいいじゃん.
unbound variableはコンパイル時に
変数名を間違えたとき、定義していない関数や変数を使ってしまったとき、その部分が評価されるまでエラーが出ませんが、コンパイル時に出るように出来ませんでしょうか。
scheme的には後でトップレベル変数として束縛される可能性を無くしてしまいたくないということなのかも知れませんが。
時間のかかる処理の最後で、unboundって見つかるとがっかりしすぎで。
もし既にある機能だったら、すみません。(その際はこのエントリー消します)
- R*RS的に、エラーにしてはマズイということはあると思いますので、goshのオプションスイッチでとか。あるいは、モジュールごとに切り換えることで既存のモジュールはこのチェックはパスとか。
- トップレベルで相互再帰させたいと、エラーになってしまうわけですが
- ダミーのdefineを意図的に入れることで、一時的に束縛し、あとで改めて定義
- define-transientって作るとか
- letrecして、valuesで返してdefine-valuesで束縛することを強制する(めんどう)
- 未束縛シンボルが出てきても、その時点ではエラーは出さず、そのモジュールのコンパイルが終わっても未束縛であれば、エラーを出すとか。
今でもなんらかの工夫で同じようなことが出来るとかの情報でも。 宜しく御願いします(katsujiro)
- Shiro (2005/09/07 20:20:41 PDT): Gaucheのモジュールは開いている (いつでも グローバル定義を追加できる) ので、未定義変数への参照を実行せずに 解析するのは不可能です。が、ライブラリレベルのtypoバグが変な時に 出てくるのも嫌なんで、requireされるファイル単位で未束縛変数への 参照に警告を出す、という機能は計画しています。
- katsujiro(2005/09/10 08:25:10 PDT)ありがとうございます。是非是非宜しく御願いします
- Shiro(2006/04/22 17:31:18 PDT): gauche-devel-jpに投稿された辻本さんのアイディアで、 0.8.7からtest-moduleで未定義変数への参照をチェックするようになりました。
gauche.netをwin9x系でも使えるように
win9x系では_open_osfhandleが常に-1を返してしまいます。そのせいでソケットに入出力ができません。(ソケットの作成自体には成功しているようです。)ソケットまわりについてはまだ整備中のようですので可能であればこの点も考慮して頂ければ助かります。 (2005/11/24 20:55:56 PST)
- Shiro(2005/11/24 23:51:06 PST): win9x系は環境を新たに手に入れるのも既に難しく、 また今後需要は減りこそすれ増えることは無いと思われるので、私自身は積極的に サポートする予定はありません。環境をお持ちの方からのパッチは歓迎します (ただ、win9xのサポートのためにコードがむやみに複雑化するようでしたら ちょっと考えてしまいます。)
- (2005/11/25 03:15:14 PST): socket-sendあたりは支障なく使えるようなので低レベルな関数だけでなんとかしてみます。rfc.httpが使えないのが残念ですが…。gauche.vportを利用すればCでパッチを書かずに高レベル手続き部分をWin9xでも再現できるかもしれないと思いました。
環境変数のキー一覧を取得する手段があれば嬉しい(かも)
- 本当に必要かどうかと言われると微妙なのですが…‥。 (ソレが必要になる状況は、メタ変数一覧表示CGIとかぐらいしか、自分には思いつかないのですけど…‥) -- nekoie (2004/02/23 08:03:28 PST)
- Shiro 姑息な手段としてはこんなのとか:
(use gauche.process) (call-with-input-process '("/usr/bin/env") port->string-list)
全環境変数を得るportableな方法って、プロセスのmain関数でenvpを 受け取る以外にありましたっけ。
- Shiro(2010/04/13 13:45:33 PDT): 最近のGaucheにはそのものずばりの関数があります (GaucheRefj:sys-environ, GaucheRefj:sys-environ->list)。
defined?
- たっちん defined? (変数が bind されているかどうかを判断する predicate) がほしいです。
Shiro (2002/12/01 04:57:22 PST): symbol-bound? というのがあります。 あれ、ドキュメントに書いてないな。
gosh> (symbol-bound? 'foo) #f gosh> (define foo 3) foo gosh> (symbol-bound? 'foo) #t
symbol-bound? はそのフォームがコンパイルされた時のモジュールを 基準に変数名を参照するので注意して下さい。
- Shiro(2008/11/22 16:57:06 PST): 最近のGaucheではsymbol-bound?はdeprecatedで、 global-variable-bound?を使うことになってます。
Literate comment
プログラムソーステキストの指定部分だけをコードと看倣す記法があるとうれしいなぁ。 Haskell では、\begin{code}と\end{code}の間もしくは、> ではじまる行のみをコードと 看倣す記法があります。これに相当するものが Gauche にあるととても嬉しいです。Haskell では Literate comment を使用しているかどうかは、明示的にコンパイラやインタープリタに指示するか、ソースファイルの拡張子で判定するようになっています。(.hs は普通のソースファイル .lhs は Literate comment を使用したソースファイル) --nobsun 2002/11/25 01:13:17 PST
Shiro (2002/11/25 02:46:55 PST): 2パスになっちゃいますが、こんなんはどうですか。
(define (load-with-literate-comment file) (call-with-input-string (with-output-to-string (lambda () (with-input-from-file file (lambda () (define (code line) (cond ((eof-object? line)) ((#/^\\end\{code\}/ line) (comment (read-line))) (else (print line) (code (read-line))))) (define (comment line) (cond ((eof-object? line)) ((#/^\\begin\{code\}/ line) (code (read-line))) ((#/^>/ line) => (lambda (m) (print (m 'after)) (comment (read-line)))) (else (comment (read-line))))) (comment (read-line)))))) load-from-port))
対話レベルで拡張子によって動作を変えるには、loadを再定義するという 裏技が:
(use srfi-13)
(define load (let ((old-load load)) (lambda (file . args) (if (string-suffix? ".lscm" file) (load-with-literate-comment file) (apply old-load file args)))))
但しこれだけだと、コマンドラインからliterate comment入りのファイルを スクリプトとして読ませることはできません。内部で直接load-from-port相当 のものを呼んじゃっているので。