LISP Scheme Part4

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
2デフォルトの名無しさん:02/03/16 02:00
□参考リンク□

日本Lispユーザ会(日本語)
http://jp.franz.com/jlug/index.html
ここにかなりの情報があります。

プログラミング言語Scheme(日本語)
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/scheme.html
Schemeの人はまずここを見ましょう。

Lisper への道(日本語)
http://www.geocities.co.jp/SiliconValley-Oakland/1680/rakup.html
判りやすいLISP入門サイト

Schemeへの道(日本語)
ttp://www.stdio.h.kyoto-u.ac.jp/~hioki/gairon-enshuu/SchemeNotes/scheme.html

慶応の授業のページ・記号処理プログラミング 2001
http://buri.sfc.keio.ac.jp/lisp/menu.html

Practical Scheme(日本語)
http://www.shiro.dreamhost.com/scheme/index-j.html
「普通のやつらの上を行け」など、興味深い文書があります。

SICP(英語)
http://mitpress.mit.edu/sicp/full-text/book/book.html
「計算機プログラムの構造と解釈」の原書です。
全てオンラインで読めます。

Scheme Hash(英語)
http://okmij.org/ftp/Scheme/index.html

John McCarthy's Home Page
http://www-formal.stanford.edu/jmc/
LISPの生みの親、J・マッカーシーのページだそうです。

お隣りのプログラマ板のLISPスレのログです。
http://mentai.2ch.net/prog/kako/963/963134110.html

□仕様書関係□

Common Lisp the Language, 2nd Edition(英語)
http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/cltl2.html
CommonLispの仕様書です。

アルゴリズム言語Schemeに関する第五改訂報告書 R5RS(日本語)
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/r5rsj/html/r5rsj_toc.html
http://www.biwa.ne.jp/~mmura/scheme/tspl.html#r5rs
日本語訳はここ以外にもあるそうです。

Scheme Requests for Implementation SRFI (英語)
http://srfi.schemers.org/

Scheme Frequently Asked Questions (英語)
http://www.schemers.org/Documents/FAQ/


幻の「入門Scheme」
http://www4.ocn.ne.jp/~inukai/scheme_primer_j.html
オンラインで読める
6デフォルトの名無しさん:02/03/16 02:15
スレ立てお疲れ様です。

Smalltalk スレで、Smalltalk のリフレクションは Lisp 系起源という話が
あったのですが、これって Common Lisp とかでしょうか?
Scheme にもありますか?
7デフォルトの名無しさん:02/03/16 02:19
お疲れ様ですげっとー!!
今日から guile をガリガリ覚えます。
ってただ言いにきただけ。scheme は何でもできて(・∀・)イイ!!みたいな意見
を前スレで見たので(実は難しくてあんまり読んでないけど) 楽しみ。
CLOS では intersession や introspection が可能らしいんだけど。
10デフォルトの名無しさん:02/03/16 03:04
こういう特定用途のmapってschemeだと自分で定義するしかないけど、
CommonLispで同型関数ありませんか?(関数名を参考にしたいので)

;先頭からn番目までのリストをコピーして返す
(define (list-head l n)
 (let loop ((l l) (n n))
  (if (zero? n)
   tail
   (cons (car l) (loop (cdr l) (- n 1))) )))

;リストがn以上の長さであれば#tを返す
(define (nlength? n l)
 (if (zero? n)
  #t
  (if (pair? l)
   (nlength? (- n 1) (cdr l))
   #f)))

;n個引数ずつ処理するmap
(define (mapn n proc l)
 (let loop ((x l))
  (if (nlength? n x)
   (cons (apply proc x) (loop (list-tail x n)))
   '())))

;n個引数ずつ処理するmap。
;引数はコピーされるので可変個procに対してのapplyも安心
(define (mapnc n proc l)
 (let loop ((x l))
  (if (nlength? n x)
   (cons (apply proc (list-head x n)) (loop (list-tail x n)))
   '())))

;使い方
>(mapn 3 (lambda x (apply + x)) '(1 2 3 4 5 6))
=>(21 15)
>(mapnc 3 (lambda x (apply + x)) '(1 2 3 4 5 6))
=>(6 15)
> ;先頭からn番目までのリストをコピーして返す
subseq
> ;リストがn以上の長さであれば#tを返す
nthcdr
12デフォルトの名無しさん:02/03/16 17:03
guile で step 実行とかやりたいんだけど info 見たら何も書いてなかった。
cvs でとってきた 1.7 なんですけど。これって make 失敗とかですか?もと
もとないんですか?
>>8
Scheme の良いところは、言語仕様を覚えるのが楽って事かな。
あとはマクロか。これがデカい。タイプ量が減るので最高。
ライブラリは適当に出回ってるのでも使って頂戴。
148:02/03/17 00:59
やっぱり gauche の方がおもしろそうなので乗り換えます(w
でも slib が使えるようにならないなぁ。インストールばっかりやってると時
間がもったいないから slib は後まわしで scheme 覚えよ。
15デフォルトの名無しさん:02/03/17 03:11
>>14
guileのinfo読めば書いてあるのに。
168:02/03/17 09:54
>>15
いや、guile からは slib 使えるようになったんですけど、gauche
の方が... もうちょっと調べに逝ってきます。
C は「手続き型」なのに「関数」
scheme は「関数型(?)」なのに「手続き」

なんかおもしろいね。間違ってたらツッコミよろしく。
18デフォルトの名無しさん:02/03/17 12:02
>>16
あ、ごめん。>>12と同一人物かと思った。
>>15>>12にね。
>>17
前者は手続きを含むプログラムで言う所の「関数」
後者は写像の意味の「函数」の一般的な表記
ちょとちがう。

20デフォルトの名無しさん:02/03/17 12:18
gaucheは./configure --helpすれば書いてるよ
slibのパスを設定すれば何とかなるんでない?
俺は試してないけどね。
Emacs Lisp を学べるサイトを教えていただけませんでしょうか。
http://www.gentei.org/~yuuji/elisp/
http://www.cs.indiana.edu:800/LCD/cover.htm
http://www.anc.ed.ac.uk/~stephen/emacs/ell.html
http://www.geocities.co.jp/SiliconValley-Oakland/1680/xyzzy_lisp.html

xyzzy で勉強したいと思ってます。
おすすめの書籍なんかもあったら教えてください。
22めりっさ P マッカ−:02/03/17 13:00
SICPの問題にでてくる登場人物の名前ってどこから
とったんだろう。気になって夜もねむれません。教えてセソセイ!
23デフォルトの名無しさん:02/03/17 13:24
C言語を始めようと思って、コンパイラ(BCC)をダウンロードしました。
C言語は解説してるページもけっこうありそうなので、それを参考に勉強していこうと思ってのですが、
無理です......
やっぱり解説書を買うべきでしょうか。
>>23
逝ってよし
  誤爆は無視して 行きましょう
>>21
xyzzyはEmacs LISPじゃないょぅ
xyzzyはcommon lisp風ですね
27デフォルトの名無しさん:02/03/17 16:24
>>21
俺は「リスト遊び」読んでから、URL の1個目の人が書いてる「やさしい
Emacs-Lisp 講座」を読んだよ。「やさしい...」読んだら人のソースとかも読
めるようになる...かな?俺も勉強中。
298:02/03/17 18:36
slib のインストール挫折しました。
gauche で slib 使えてる人教えてください。
Gauche-eucjp-0.5.2-1 の rpm なんですが、/usr/local/silb から slib を探
しているようなので、ln -s /usr/share/slib /usr/local/slib とシンボリッ
クリンクしました。それから gauche を起動すると、

gosh> (use slib)
*** ERROR: no such module: srfi-1
Stack Trace:
_______________________________________
0 (%require feature)
At line 34 of "/usr/share/gauche/0.5.2/lib/gauche-init.scm"

のようになります。srfi-1 を探すと

/usr/share/slib/srfi-1.scm
/usr/share/gauche/0.5.2/lib/srfi-1

というのが見つかるのですが。どうしたらいいんでしょ。
308:02/03/17 18:39
>>20
--with-slib=PATH ですよね。ソースから make も試したのですがだめでした。
;; 何が悪いんだろ。もう1回 make してみようかなぁ...

3121:02/03/17 19:50
>>25 >>26
そうなんですか・・! Emacs Lisp ⊂ Common Lisp だと思ってました。
そういえば、xyzzy は Common Lisp だとどこかで読みました。
Emacs Lisp と Common Lisp、とりあえずどちらを学ぶのが
良いのでしょうか。
より一般的にエディタに使われている方を学びたいと考えてます。
つまり、どちらの言語でライブラリを書くと、より多くの人に
(特に英語圏の方に)使ってもらえるでしょうか。
そりゃ当然 Emacs lisp でせう。
3321:02/03/17 20:15
>>32
どうしてですか?
どうぞ教えてくださいませ。
(一般論でなくても、俺的意見でも何でも・・)
>>31
Emacs Lisp だけ覚えても、良いプログラムが書けるとは思えない。
まずは Common Lisp か Scheme で修行して、Lisp の本質を勉強する
事をオススメする。
3521:02/03/17 20:42
>>34
Scheme なら大学の授業でとりました。
これならおっけいですか?
3634:02/03/17 20:49
>>35
素晴らしい。Emacs の世界に貢献して下さい!
3721:02/03/17 21:01
>>27
あ、あなたのレス見逃してました。すみません;
http://www.gentei.org/~yuuji/elisp/
とりあえずここを保存してじっくり読んで見ます。
良さそうだったら、書籍も購入してみます。

>>34
半分はそのつもりです。もう半分は、まぁ自分のためです。
>>37
激しく激しく外出だが、
ftp://ftp.ascii.co.jp/pub/GNUの
emacs-lisp-intro-jp, emacs-20.xも忘れるな!
3921:02/03/18 03:52
ダウンロードしました!

>>25 >>26 >>27 >>32 >>34 >>36 >>38
みなさま、ありがとうございました。
40デフォルトの名無しさん:02/03/18 21:48
きだあきらがSICPをCマガで紹介してた
gauche で slib 使ってるシト教えてよぉ...
42デフォルトの名無しさん:02/03/18 22:17
>>40
scheme 特集あるの?立読みしに逝こ。
43デフォルトの名無しさん:02/03/18 22:38
>>42
そんなたいそうなもんじゃない
単なる書評
Great !っていう内容の
44デフォルトの名無しさん:02/03/18 23:49
scsh使ってる人いる?今マニュアル読んでるんだけど。
おもしろい?
45デフォルトの名無しさん:02/03/19 02:39
guile-gtk は cygwin では使えないんだよね?
>>42
もしscheme特集やるとして、何載せるんだ?
どうせCマガのことだからlambdaとかtailrecurseみたいな
初歩的な事しかやらないだろ。
末尾再帰の練習に fibonacci 数計算してみた。
あってる? 修行が足りない?

(define (fibo num)
(define (loop n p1 p2)
(cond ((= n 0) 1)
((= n 1) 1)
((= n 2) (+ p1 p2))
(else (loop (- n 1) (+ p1 p2) p1))))
(loop num 1 1))
48デフォルトの名無しさん:02/03/19 13:30
Cマガで特集?
それはやっぱアサインメントを使用しないで
アルゴリズムを構築するってことの妙味を伝えるんじゃないかな?
49OLEさん ◆l/oKiJ62 :02/03/19 14:03
>>44

さわった事あるよ。
でもC-z等が使えないので、bashにとってかわる事は出来なかった。
50デフォルトの名無しさん:02/03/19 16:32
C-zて何よ
suspend とか?
5251:02/03/19 17:54
make して ./go してみたけど使い方が分からんかった(w
53デフォルトの名無しさん:02/03/19 20:37
すsぺんdなら継続をぶった切ればいいじゃん
盛り上がらないなぁ、lisp, scheme スレ。
Schemeの評価は確立されたものだよね。
あとは「より良いライブラリ」についての議論ぐらいじゃないの?
56デフォルトの名無しさん:02/03/19 22:52
Scheme/Lisp のオブジェクト指向ってメソッドがクラスに従属していない
って言うけど、良く判らない。クラスの内部にアクセスする手段というのが、
メソッドの一つの役割ですよね。メソッドをクラスの外で宣言できるという
事はオブジェクトの隠蔽と矛盾しないのでしょうか?

って、自分で調べてみろって? そうします・・・。
Bertrand Meyerも書いているけれど、オブジェクト指向の定義は
これといったものがないんだよね。人によって定義が違うわけ。だ
から、ある人にとって「こんなのオブジェクト指向じゃない!」と
言えるものが、ほかの人にとっては「まさにこれこそがオブジェク
ト指向だ!」となることもあるわけ。

メソッドの定義を隠蔽するかどうか、アクセス制御を提供するかど
うか、といったあたりはOOPLによってかなり幅のある部分ですよね。

58デフォルトの名無しさん:02/03/19 23:15
>>57
流行を追いかけて Smalltalk と Java をかじった私としては、とても新鮮です。
Smalltalk と Lisp は歴史上、非常に縁近いと聞いていたので尚更です。

ちなみに >>56 はこの文書を読んだ感想です。

Schemer's way
http://www.shiro.dreamhost.com/scheme/docs/schemersway-j.html
>>54
特に盛りあがる必要なし
60デフォルトの名無しさん:02/03/19 23:50
>>56
LISPやSchemeではオブジェクトやメソッドとかの隠蔽って
自然に出来ると思うけど?
特にこれといったインターフェースを使え、とか強要されて
るわけでもないし、制限も別に無いんで、頭やらかい人じゃない
と逆に使いづらいのかも。
61デフォルトの名無しさん:02/03/19 23:58
例えば、単にclosureの中に置けば隠蔽したことにならない?
それと「メソッドがクラスに従属していない」のは
CLOSみたいなマルチメソッドを採用してるパッケージだと思う。
もちろん、C++やJava風の、クラスに垂れ下がるメソッドを持つ
形式のパッケージもあるよ。
62デフォルトの名無しさん:02/03/19 23:59
56ではないのですけどメソッドのディスパッチの方法はどうやってるの?
くわしい人解説プリーズ。
63デフォルトの名無しさん:02/03/20 00:31
>>62
CLOSのディスパッチ方法は・・・

最初に、ある名前に対して
「この名前をメソッド(=総称関数)として使用する」
と宣言する。(必ずしも名前を定義する必要はなく、lambdaと同様に無名メソッドも定義できる。)
するとメソッドディスパッチを行うオブジェクトが生成され、その名前に関連付けされる。
そのオブジェクトはメソッド毎のクラス階層と依存関係を保持していて、
新しいメソッドが定義されると、その依存関係を更新する。

メソッド呼び出しで、ディスパッチオブジェクトが引数に与えられた
各オブジェクトのクラスを比較していき、クラスが一致するか、
または与えられたオブジェクトがそのクラスの派生型である
メソッドを選択して適用する。

64デフォルトの名無しさん:02/03/20 00:40
CLOSでは無名メソッドが許されているため、
名前よりもむしろ引数型の組み合わせが重視される。
ローカル宣言もできるので、名前を外部に公開しなければ
隠蔽の意味にもなるでしょ。
65デフォルトの名無しさん:02/03/20 20:24
CLOSの参考書おしえて!
今更 part2 を読んできました。懐しかった。今読んだら意味が判る(ところも
あった) ところで、
scheme の「手続き」は closure で、
closure とは「環境」のついてくる「(Cでいうような)関数」で、
「環境」とはその時点で存在する変数とその値、手続きなどの alist (のようなもの)
っていう理解であってる?間違ってたら指摘プリィズ。
67デフォルトの名無しさん:02/03/21 15:50
alistってなに?
68デフォルトの名無しさん:02/03/21 15:59
(define-macro(apush key data table) (set! table (cons (cons key data) table)))

(define (table '())
(apush 'これが 'alistや! table)
(assq 'これが table)
=>(これが . alistや!)
69デフォルトの名無しさん:02/03/21 20:48
コンパイラ入門の本をみてみると、再帰下降法がのっていた。
「強力な手法」とのこと。
やっぱり、構文の再構成に使用するデータ構造はリスト構造が最適なのでしょうか。

それとお聞きしたいのですが、
LISPと数式処理、LISPと有限群論について何か良い本、Webページはないでしょうか。
70デフォルトの名無しさん:02/03/21 23:02
>>69
> LISPと数式処理、LISPと有限群論について何か良い本、Webページはないでしょうか。

http://sal.kachinatech.com/A/1/ なんかあさったらどう?
71デフォルトの名無しさん:02/03/22 02:18
Gauche な人は既に読んでると思うけど、ここが興味深い。
http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?c=a&l=jp
FAQ 見たけどやっぱ slib が使えないぞ俺には...(鬱

*** ERROR: no such module: srfi-1
Stack Trace:
_______________________________________
0 (%require feature)
At line 34 of "/usr/share/gauche/0.5.2/lib/gauche-init.scm"

なんでこうなるんだよう。教えてくれよう。
SCHEME_LIBRARY_PATH 設定したのにだめ。
7372:02/03/22 04:01
あ、gauche の話です。
slib 使えなくても多分問題はないんだけど...気になる。
7472:02/03/22 05:23
あ、わかった。
(use srfi-1) (use srfi-2) .... (usr slib)
ってひたすらやったらエラーは出なくなったけど...

(use slib) だけでできるってマニュアル書いてあったから本当は自動でやっ
てくれたりするんじゃないの?
75デフォルトの名無しさん:02/03/22 09:58
LISPはいい。
複雑な構文もない。
演算子もない。よって優先順位もない。
書いた文はそのままリストになるし。
リストをevalに書ければ評価される。
非常にわかりやすい。
カッコ付けるだけで、なんでもできる気がする。
76デフォルトの名無しさん:02/03/22 10:07
LISPとFORTHどっちが簡単か?
と問われたら、俺は間違い無くLISPと答えるだろう。
つーかFORTHわけわからん。
LISPが一貫して
(<関数|構文> 引数)
なのに対し、
FORTHは暗黙のスタック操作も含まれるため、
引数 <関数|構文>
だけでは済まされない事が、問題を複雑化してる様に思う。
コードを読んでも、そのときスタックに何が積まれている(べきな)のか、
俺にはさっぱりわからないのだ。
とはいえ、OpenBootがgarbage collection始めたらイヤだよね。
FORTHは人間にとって優しい言語ではなく、
処理系実装者にとって優しい言語だと思われ。
>>78
LispもFORTHほどじゃないが処理系実装者にとって優しい言語だと思う。
邦訳の ANSI Common Lisp はまだ出てないかな?
>>80
結局今月は出ない模様。
http://www.pearsoned.co.jp/washo/nbindex_chg.html
8280:02/03/22 16:20
>>81 ガーソ。 未定っていつになるんだろう...
出版中止にだけはなりませんように

84デフォルトの名無しさん:02/03/22 23:59
>>83
学校の授業でDrScheme使うのか。
課題がPICコンパイラつーのは面白そうだな。
85デフォルトの名無しさん:02/03/23 00:29
fluid-let マクロで作って。
86デフォルトの名無しさん:02/03/23 00:31
>81
訳本で未定ってどういうこと?
まだ翻訳が終わってないのか、
金の問題なのか。
後者だったらやだなあ・・
87デフォルトの名無しさん:02/03/23 00:37
>>85
fluid-letって初出どこだったかな。
define-macro版とsyntax-rule版がを見かけたことあるけど。
そういや、fluid-let内で継続脱出があった場合、
どういう扱いになるか、誰か知ってますか?
>>85
Slib にあったよ。チラっと見たら、dynamic-wind 使ってました。
89デフォルトの名無しさん:02/03/23 00:52
define-macro版のfluid-let。
どっかから持ってきたやつをちょっと修正したもの。
R5RSのdynamic-windが必要。
この実装だと継続脱出が起こると前の状態に戻る。

(define-macro fluid-let
  (lambda (xexe . body)
    (let ((xx (map car xexe))
          (ee (map cadr xexe))
          (old-xx (map (lambda (ig) (gensym)) xexe))
          (result (gensym)))
      `(let ,(map (lambda (old-x x)
                    `(,old-x ,x))
               old-xx
               xx)
         (dynamic-wind
           (lambda()
             ,@(map (lambda (x e)
                      `(set! ,x ,e))
                  xx
                  ee))
           (lambda() ,@body)
           (lambda()
             ,@(map (lambda (x old-x)
                      `(set! ,x ,old-x))
                  xx
                  old-xx)))))))
90デフォルトの名無しさん:02/03/23 01:01
resultは余計だった。
9181:02/03/23 01:05
>>86
んー,なんでだろ。たしか去年の11月ぐらいから近刊案内
には載ってたから金ではない気も。単に翻訳の遅れと思い
たい。
お前ら scheme 処理系は何使ってらっしゃいますか?自作ですか?初期設定ファ
イルには何を書いてますか?
>>92
自作が多いと思われ。
1)最低限の実装以外は全部schemeマンセー
2)可能な限りCやASMで組み込み症候群
の2派が存在すると思われ。
その中でもEXE作れる処理系はごくわずかと思われ。
94デフォルトの名無しさん:02/03/23 01:58
前スレあたりで出ていた
``Why functional programming matters''
(ttp://www.cs.chalmers.se/~rjmh/Papers/whyfp.html)

という論文を読んだんですけど、

lazy evaluation が非常に重要だという話になってました。

scheme などは lazy list しかないので
妥協的だとしていましたが、
scheme マンセーなみなさんとしてはどう思いますか?
9588:02/03/23 02:03
>>94
delay/force を頻繁に使ってます。lazy list って何?
9695(88):02/03/23 02:05
lazy list を www.dict.org で調べました。失敬。
9788:02/03/23 02:10
連続 sorry

>>94
lazy list の説明に、
A list which is built using a non-strict constructor.
(non-strict なコンストラクタを使って構築されるリスト)
ってあるんだけど、Scheme は strict じゃないの?
98デフォルトの名無しさん:02/03/23 02:30
>>97
a non-strict constructor → delay

"un-evaluated objectをconstructする。"
9988:02/03/23 02:40
>>98
なるほど。お馬鹿な質問をしてしまいました。
100デフォルトの名無しさん:02/03/23 02:53
>>88
なぜ関数プログラミングは重要か
ttp://www.sampou.org/haskell/article/whyfp.html
ってHaskellな人の文章だからねー
あんまり信用しないほうが良いのでは?

Scheme:LazyEvaluation
ttp://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Scheme%3aLazyEvaluation&l=jp
>>100
納得できる内容なら信用すれば良い。
(すごいとは思ったけど何処まで重要なのか私には和歌欄……)
「なぜ関数プログラミングは重要か」は、たしかに目からうろこだったよ。
これを読むまでHaskellがどうして遅延評価にこだわっているのか、わか
らなかったし。

Schemerとしては、リスト構造や高階関数の価値がわからないプログラマ
に対して「こんな良いものがわからないなんて...」という気分を持って
いますから、Haskell派の方々が遅延評価について同じような気持ちを
抱いているであろうことはわかりました。ただ、Haskellは僕にはわけが
わからないんで、しばらく使う気はありませんけれど。
103デフォルトの名無しさん:02/03/23 08:33
ここで関数型の話をするのもなんだけど、
「遅延評価が重要だ」が先にくるんじゃなくて、作用順序に依存しないコード
の方が保守性が良くなるんじゃないか、って考えが元なんじゃないかと。
haskellはそれを体現してみせたわけだけど、結局、
モナドなんかはやりすぎって感じで、本末転倒な気がするのは俺だけでしょうか。
104腰の曲がったおじいさん:02/03/23 12:09
AlgolやPascalだって昔はやりすぎに見えたよ。
105BASICER:02/03/23 12:31
> (define (length l)
(cond
[empty? (l) 0]
[else (+ 1 (length (rest l)))]))
cond: clause is not in question-answer format
>

ランゲージレヴェルスエクザンプルの1ページ目に載ってた関数を実行したら
こうなったDrSchemeをうかつにDLしたが、サパーリちんぷんかんぷん
誰か乞うアドバイス
>>104
C++は今がやりすぎだね(w
106デフォルトの名無しさん:02/03/23 14:27
>>105
setpperつかったら?
(length (1 2 3 4))とかやってみてみそ
107デフォルトの名無しさん:02/03/23 14:31
(length (1 2 3 4))
(+ 1 length(2 3 4))
(+ 1 (+ 1 length(3 4)))
(+ 1 (+ 1 (+ 1 length(4))))
(+ 1 (+ 1 (+ 1 (+ 1 length()))))
(+ 1 (+ 1 (+ 1 (+ 1 0))))
=4
108BASICER:02/03/23 14:41
>>106
えっ?
> (length (1 2 3 4))
illegal application: first term in application must be a function name
> (length (1 2 3 4))
(+ 1 length(2 3 4))
(+ 1 (+ 1 length(3 4)))
(+ 1 (+ 1 (+ 1 length(4))))
(+ 1 (+ 1 (+ 1 (+ 1 length()))))
(+ 1 (+ 1 (+ 1 (+ 1 0))))
illegal application: first term in application must be a function name
>
こりゃだめだ!!
DrSchemeが嫌いになりそ(@_@);
SICP プリントアウトしたいんだけど誰か pdf にしてうぷしてYO!
110デフォルトの名無しさん:02/03/23 16:30
>>105
restはschemeにはないよ。cdrにしたら?

>>108
> (length (1 2 3 4))
quote付いてないよ
111107:02/03/23 17:23
>>110 >>BASICER

>> (length (1 2 3 4))
>quote付いてないよ

う、初歩的しょぼいミスー。すまぬ
(length '(1 2 3 4))だね
112BASICAR:02/03/23 18:24
> (length '(1 2 3 4))
quote: misused: '(1 2 3 4) is not a symbol
>

出鼻でつまづいたのはDrSchemeが始めてだす〜
113BASICAR:02/03/23 19:30
もう嫌になりました。
DrSchemeはアンインストールします。
皆さんありがとうございました。
114デフォルトの名無しさん:02/03/23 19:39
DrScheme version 103p1で動いたよ

(define (mylength l)
(cond
((empty? l) 0)
(#t (+ 1 (length (cdr l))))
)
)
(mylength (list 1 2 3 4))
lengthは駄目だって。予約済みだから。

>> (length '(1 2 3 4))
>quote: misused: '(1 2 3 4) is not a symbol
このエラーはねー 「リストと quote 」
ttp://www.edu.cs.kobe-u.ac.jp/Enshu6/2000/scheme_web/sexpr_quote.html
みてみそ。
ただしBiggner modeじゃないとStepperは使えない
115デフォルトの名無しさん:02/03/23 19:46
DrSchemeは、なんであんなアホなモードがデフォなんでしょ?
116デフォルトの名無しさん:02/03/23 23:30
procedure をカタカナにすると「プロシージャ」なの?
英語発音とずいぶんずれてるような気がするけど。
117デフォルトの名無しさん:02/03/23 23:56
フランス語だとポロセドレ
118BASICAR:02/03/24 09:18
>>114
あんがと
今から勉強します。
>>116-117
プロセデュアっての聞いた事あるよ。
SICPって日本語訳は4600円なのに原書は8400円くらいするんですねぇ。
120デフォルトの名無しさん:02/03/24 18:26
なぬ?
web だと読まないんだよね。日本語訳はひどいらしいから英語買ってみようか
なぁと。4000円くらいなら買うけど8000円だとためらうなぁ。
>>122
そんなに日本語訳ひどいかなぁ? 少し特徴のある訳し方だとは思うけど、
表面的な意味は十分理解できるよ。
124122:02/03/24 22:06
>>123
そうなの?じゃ日本語訳買ってみようかなぁ。原書読破っていうのも楽しそう
だけど。
125デフォルトの名無しさん:02/03/24 22:56
まさにSICPをオンラインで見ながらDrSchemeで勉強始めたものです。
まだ全然なんですが、Schemeって3つ以上の分岐ってどうやるのか疑問。
いわゆるelseifです。
if文の中にif文ネストするのもエラーって言われたし。どうすんでしょ?
cond では? if の中に if 書けるよ。
127デフォルトの名無しさん:02/03/24 23:00
ちなみに、「二つの数字a,bが同符号か異符号か判別する」という問題です(SICPの例題じゃないです)。

自分はしょーがないからこんな風にした。

(define a 10)
(define b 0)
(define c "hoge")

a; 10
b; 5

(set! c (* a b))
c; "c = a * b"

;***** if branch *****
;1
(if (> c 0)
(printf "a and b have the same sign")
)
;2
(if (= c 0)
(printf "c is zero")
)
;3
(if (< c 0)
(printf "a and b have the different signs")
)
128デフォルトの名無しさん:02/03/24 23:03
>126

お、情報ありがとうございます。やってみます。
DrScheme見やすくて素人に優しそうなんですけど、全角だめっぽいのが傷。
(let* ((a 10) (b 0) (c (* a b)))
(cond
((> c 0) (display "same sign") (newline))
((= c 0) (display "c is zero") (newline))
((< c 0) (display "different sign") (newline))))

厨房だけど、こんなのとか。
;; different signs (複数形)なの?わからんけど(汗
130デフォルトの名無しさん:02/03/24 23:11
でけた。condがelseifなんですね。読み返したら1ページまえのSICPに書いてあった・・・


(define a 10)
(define b 5)
(define c 0)

a; 10
b; 5

(set! c (* a b))
c; "c = a * b"

;***** cond branch *****
(cond ((> c 0)
(printf "a and b have the same sign"))

((= c 0)
(printf "c is zero"))

((< c 0)
(printf "a and b have the different signs"))
)
131130:02/03/24 23:15
>129
ほとんど同じっすね。安心。

>different signs (複数形)なの?わからんけど(汗

いや、コメントは僕も適当なんで読み流してください。同符号ならひとつだから単数形、異符号なら二つだから複数形(笑
132デフォルトの名無しさん:02/03/24 23:19
>>125
あれっ。てもとにあるDrSchemeでできるけど。
condじゃだめなの?
133デフォルトの名無しさん:02/03/24 23:56
培風館のLISP 原書
でlispを勉強してるのですが、
そこにでてくるテイル再帰プログラムというのがいまいちなんですが、
(defun hoge (param1)
;処理
(hoge (param))
という風に再帰呼び出しをするときに余計なことせずに
その関数そのものだけを呼び出せばテイル再帰になるという理解でいいんですか?
また、テイル再帰にすることにどんな意味があるんですか?
末尾再帰は引数付きgoto文
135デフォルトの名無しさん:02/03/25 01:58
condもいいけどassoc系も用途によっては有効かも
136デフォルトの名無しさん:02/03/25 02:02
>>133
LISPは処理系によってどうなるかわからんけど、
schemeだと
(define (hoge) (hoge))
(hoge)
がふつーに動く。
これは末尾コンテクストという概念で、
シーケンスの最後に関数などの呼び出しがあるなら、
それはただのジャンプに置き換わるって事なんだけど。
137デフォルトの名無しさん:02/03/25 02:04
(define (hoge n) (display n)(hoge (1+ n)))
(hoge 1)
12345678...
永遠にカウントアップする関数
何度もこのスレで繰り返されたことだけど、
schemeにはループ制御構文はdoしかない。
それもオプション扱いなんだけど。
言語設計者は末尾再帰をサポートすれば専用のループ構文は
全く必要ない事に気が付いた。
139デフォルトの名無しさん:02/03/25 04:37
>>138
後はif文さえ除去できれば。
非正格言語なら遅延実行でif文も無くせるのに
140デフォルトの名無しさん:02/03/25 07:09
良く知らないけど、パターン使うんでしょ?>139
あれってif文みたいなものじゃないの?
141デフォルトの名無しさん:02/03/25 07:21
>>140
パターンマッチングはただのシンタックスシュガー.
142デフォルトの名無しさん:02/03/25 08:13
>>141
>パターンマッチングはただのシンタックスシュガー.
え、何の?
143141じゃない:02/03/25 09:08
if文case文の構文砂糖じゃない?
if,caseはガードに相当する
>>134 センスいーね〜
 正しくは、引数書き換え&goto文 だと思われ。
146デフォルトの名無しさん:02/03/25 12:45
>>144
パターンマッチもガードじゃないの?
147134:02/03/25 13:00
>>145
え?センスいいって。どっかに書いてあったのをそのまま書いただけです(w
僕も実はあんまりわかってないです。はい(汗
処理系はなにがいいのでせうか?

今使ってるのはMeadow, XLispStatですが、Common Lispと微妙に違っているので、
出来るだけ準拠したものがほしいのです。できれば、GUIありで・・・。
gauche (・∀・)イイ!!
150デフォルトの名無しさん:02/03/25 14:03
UNIX に限った話ですが、
guile は

#!/usr/bin/gulie

の書式が使えるんだけど、
mit-scheme で同じようなことできませんか?
guile は #!/usr/bin/guile ではできなかったような気が...
(eq #\a #\a) は未規定なんだね。
guile と gauche は #t 返したけど。
153デフォルトの名無しさん:02/03/25 18:22
>>152
オブジェクト生成の爆発を避けるために
256バイトとかでテーブル参照でもやってるんでしょう。
gc起動が一番コストがでかいから。
154デフォルトの名無しさん:02/03/25 18:29
256個の文字で固定すれば
属性フラグ+文字で1オブジェクト2〜4バイトとして考えても
最大1024バイト程度のテーブル参照で済むから、
そういうのは積極的にやってると思う。
実際ソース読んで見ないとわからないけども。
でもgaucheは漢字も1文字として解釈するんだよね。
155152:02/03/25 18:50
あっ、、eq ぢゃないや(汗

>>153-154
そういうことなんですか、実装のことまでは分からないけど。俺もいつかは
scheme 処理系書くぞ。でも今は scheme 書けるようになるのが先だけど。
過去ログに単語lambdaが長いとあったけど
lambda->lm
はどうよ?
(de list(lm x x))
157デフォルトの名無しさん:02/03/25 19:44
schemaの処理系ねー
継続以外の処理は、すぐにでも作れるけど・・・
みんな、どうな風に作ってるんだろ?
(ソースみて勉強しないとねー)
lambda は lambda だから カコ(・∀・)イイ!! のに、とか言ってみるテスト。
159150:02/03/25 21:41
>>151
#!/usr/bin/guile だけではできませんが、

#!/usr/bin/guile -s
!#

と書けばできます。

#! から !# までをコメントとする guile 独自の拡張らしい。
>>150
":"; exec gosh -b $0 "$@"

gauche だけどこれでできたから逝けるかも。-b は batch mode. 後ろの 2つ
は何だか知らないけど多分引数を渡すやつ。shell によっては変えないとだめ
かも。
やっぱ
#!/usr/bin/env gosh
の方が簡単かも。引数渡せるかは調べてないから調べて判ったら教えてね。
162130:02/03/25 22:33
もちっとSICP読み進んでSchemeにも慣れたら
「SICP読む→ウマー」ってスレ立てようかと思ってるんですけど、お前らいかがですか。
scheme教えてスレはホスィ
164150:02/03/25 23:11
>>160-161
":"; exec gosh -b $0 "$@"

こういう sh の書き方は知りませんでした。
#!
しかないと思ってた。
これでできるかも知れません。サンクス!
165デフォルトの名無しさん:02/03/25 23:47
誰か Scheme らしいお題をプリーズ!
166(define (x) (x)):02/03/25 23:49
でも盛り上がるかどうか。。。
このスレがpart4まで来るぐらいだから、SICP興味ある(or実際読んだ)人は少なくないのでは?
オンライン版なら誰でもアクセスできるわけだし。
168デフォルトの名無しさん:02/03/26 01:41
[問題]
ある地点を(x,y,z)とあらわせるとする。
x,y,zは符号付整数。
ある地点A,B,C・・・を結ぶためのパイプを設置する事を考える。
パイプのコストはなるべく安くすませたい。
パイプは長さ1に対して、コストL円かかる。
パイプを連結するのにB円かかる。
ひとつの連結パーツで最大6つのパイプを一点で連結する事ができるが、
それぞれのパイプの角度は90*n度でなくてはならない。(nは整数)
それから、パイプの方向は(1,0,0),(0,1,0)(0,0,1)のいずれかでなくてはならない。

パイプの配置方法を求めるプログラムを作成せよ。

以上、とある高校の夏休みの宿題。

作ってくれ
169SICP 問題1.5に:02/03/26 02:16
(define (p) (p))

(define (test x y)
(if (= x 0)
0
y))

(test 0 (p))

を実行してみると面白いことがわかる、と書いてあるけど、それ以前にこれ実行できないんですけど。。。。
素人目に見ても、1行目の関数定義のところが違ってるように見える。(define (p) (p))の最初のpは関数名に取られるわけだから、「引数のない関数は受付ません」というエラーが出るのも当然な気が・・・
何か間違ってるのかな? 
170追記:02/03/26 02:22
プロシージャは、必ずしも引数が必要でないことはわかりました。ここは、思い違いしていました。

(define (no-argument) 5);引数なしプロシージャの定義

(no-argument);実行!

のような、引数なしのプロシージャもOKなんですな。
>>162-163
このスレがあるからいらない。
あまり沢山アンカーつけるとdatの容量が大きくなるから控えめにね。
誤爆スマソ。。。
だれかreverseをschemeで書いてちょ。
名前付きletで書くのと、内部定義で手続き作ってからその手続きを呼ぶよう
な手続きって同じことができる?
>>169
その問題は
評価の仕方が作用順か正規順かで
とまるかとまらないかということ。
>>174
(define (my-reverse s)
(let loop ((s s) (reversed '()))
(if (null? s)
reversed
(loop (cdr s) (cons (car s) reversed)))))
>>177
ありがと。簡単そうだけど書こうと思ったら書けなかった(厨
179腰の曲がったおじいさん:02/03/26 16:05
>>145
> 正しくは、引数書き換え&goto文 だと思われ。

書き換えはatomicに起きます。
180177:02/03/26 16:30
>>178
一筋縄でいかないと思ったら、問題を分割すると良いですよ。
reverse みたいに下請けを用意するとか、相互再帰する手続きを作るとか。
偉そうな事いえた器じゃないですけど。
>>161
の方法でも大丈夫なようです。

$gosh -V
Gauche scheme interpreter, version 0.4.10

で、引数を取れることを確認しました。確認したのは、附属していたドキュメン
トのまんまですが ↓ です。

---- ここから
#!/usr/bin/env gosh

(define (main args)
(if (null? args)
(copy-port (current-input-port) (current-output-port))
(for-each (lambda (file)
(call-with-input-file file
(lambda (in)
(copy-port in (current-output-port)))))
args))
0)
---- ここまで
182デフォルトの名無しさん:02/03/26 22:17
>>180
相互再帰って何?
二つの関数がお互い同士を呼び合って、再帰するやつだったっけ?
できればサンプルプログラムを使って教えてください。
(相互再帰って3つ以上の関数同士でも出来るのかな?)
>>182
「なんでも再帰」とかおもしろいよ。
http://www.shiro.dreamhost.com/scheme/index-j.html
184177:02/03/26 22:48
>>182
そうですね。複数個の手続きを通して再帰される場合、相互再帰。

1. 対等な関係にある 2 つの状態を調べる述語を書くとき。
典型的なのは、偶数と奇数を調べるもの。実際には letrec を使うのが
良いかも。

(define (my-even? n)
 (if (= n 0)
   #t
   (my-odd? (- n 1))))

(define (my-odd? n)
 (if (= n 0)
   #f
   (my-even? (- n 1))))

2. 手続き呼出。eval をするためには apply をしなければならないが、
apply をするためには引数を eval しなければならない。

3. S 式の解析。手続き read はデータをひとつ読みますが、

データ → アトムかリスト
リスト → データ、データ、データ...

なので、read とペアになる read_form でも定義して、それらを相互再帰
させます。

他にも色々使えると思いますが、慣れるとスイスイ相互再帰な手続きが
書けるようになります。
>>181
mit-scheme ではできたの?
186177:02/03/26 23:10
要は入れ子のデータ構造を解析・解釈するような場合ですね。
長々とすみません。
187デフォルトの名無しさん:02/03/26 23:45
>>174
(define (foldl bop iv ls)
 (if (null? ls)
   iv
   (foldl bop (bop iv (car ls)) (cdr ls))))
(define (my-reverse ls)
 (foldl (lambda (y x) (cons x y)) '() ls))
188182:02/03/27 00:10
>>177
しんせつな解説有難うございます。
相互再帰かー。かっこいいなー。

リストと再帰を使いこなせるように精進します。
(zipとか使いこなせると括弧良いねー)
189デフォルトの名無しさん:02/03/27 00:27
>>183
「なんでも再帰」
なんと相互再帰つかうと、関数と状態が1対1対応出来るんですね。
関数型プログラミングのパワー炸裂ですね。
>>188

>括弧良いねー

(((・∀・)))イイ!
「なんでも再帰」の一番最後の count-words の in-paren っていう手続きは
おかしくないですか?括弧はネスト可能ってなってるけど括弧ネストしてあっ
たらエラーになる。
192191:02/03/27 21:42
>開き括弧が出て来たら、閉じ括弧が出て来るまでを 一単語とみなす。但し、
>括弧はネスト可能、つまり、 `abc (def (ghi) jkl) mno' は、`abc', `(def
>(ghi) jkl)', `mno' の3単語とみなすんだ。 但しダブルクオートで囲まれた
>文字列の中では括弧は機能しないとする。さてどうだ。

(define (count-words)
(define (in-word c count)
(cond ((eof-object? c) count)
((char-whitespace? c) (in-space (read-char) count))
((char=? c #\") (in-quote (read-char) (+ count 1)))
((char=? c #\() (in-paren (read-char) (+ count 1)))
(else (in-word (read-char) count))))
(define (in-space c count)
(cond ((eof-object? c) count)
((char-whitespace? c) (in-space (read-char) count))
((char=? c #\") (in-quote (read-char) (+ count 1)))
((char=? c #\() (in-paren (read-char) (+ count 1)))
(else (in-word (read-char) (+ count 1)))))
(define (in-quote c count)
(cond ((eof-object? c) (error "EOF in quoted word"))
((char=? c #\") (in-space (read-char) count))
((char=? c #\\) (read-char) (in-quote (read-char) count))
(else (in-quote (read-char) count))))
(define (in-paren c count)
(cond ((eof-object? c) (error "EOF in parenthesis"))
((char=? c #\() (in-paren (read-char) count) (in-paren (read-char) count))
((char=? c #\)) (in-space (read-char) count))
((char=? c #\") (in-quote (read-char) count) (in-paren (read-char) count))
(else (in-paren (read-char) count))))
(in-space (read-char) 0))
193191:02/03/27 21:45
abc (def (ghi) jkl) mno は3語になるんだけど
in-paren が #\) を見つけたときに in-space に跳んでっちゃうからいけない
んだと思うんだけどどうですか?
194Lisper:02/03/27 22:34
今マ版のLispスレageて来たからそっちにも行ってケロ
マ板つまんない。。。
schemeは入出力が弱いらしいですがお前らどうですか?R5RSにある機能だけで
作ったファイルを消したいときはどうやるんですか?
197デフォルトの名無しさん:02/03/28 03:15
あなたは、Common LispとSchemeどちらを愛してますか?
198Rubyist:02/03/28 03:19
Ruby!
199デフォルトの名無しさん:02/03/28 03:33
>>196
http://www.shiro.dreamhost.com/scheme/docs/schemersway-j.html

↑Schemer's way の Schemeプログラミングへがその質問へ回答かと。

話は変わるけど、Scheme FAQ を Scheme の勉強がてら翻訳しています。
プログラミング初心者なもので、難儀しています。
既に、日本語訳がありましたら、参考にしたいので教えて下さい。

http://www.schemers.org/Documents/FAQ/
>>198
ここではSchemerとでも名乗ってください
(assert (or schemerp lisperp))
お前らschemeで何して遊んでるんですか?
schemeを作るための勉強をしたいのですが、ソース公開してるシンプル
な処理系ってどんなのがあります?
204デフォルトの名無しさん:02/03/29 09:14
>203
SICPの4章
は冗談として、シンプルな処理系としてSECDR-Schemeはどうかな。
SECDマシンという仮想機械にバイトコンパイルして動作する。
あとmini-schemeとか。ソースコード1ファイルで約2500行
当然だけど、継続や末尾再帰もサポート。
どっちも昔niftyのFPLにあったけど、多分Webでも拾えると思う。
Tiny-Schemeはmini-schemeのコードを元に作ってるみたいだし。

Tiny-Scheme
http://tinyscheme.sourceforge.net/
205デフォルトの名無しさん:02/03/29 09:17
>>204
SICPの4章にのってるんですか?今webのやつ3章まで読んでるんですが。4章楽
しみだな。
>>205
ありがとうございます。今から見てみます。
207デフォルトの名無しさん:02/03/29 10:11
>181
> Gauche scheme interpreter, version 0.4.10

えーん。あたらしいのにしようよー。
>>205
良いね!
みんな、僕もっと大きくなったら schemacs を作るよ。待っててね。
http://gemacs.sourceforge.net/ とはちがうの?
211デフォルトの名無しさん:02/03/30 15:30
Guile Emacs
発音するとゲマクス。
カコワルイ
guile emacs って make できない。。。
213デフォルトの名無しさん:02/03/30 16:12
>207
Gauche は今 0.5.2 になってるね。
schemeやってる人って少ないのかねぇ。
厨房増えまくっても嫌だけど。
215デフォルトの名無しさん:02/03/31 01:07
まだマクロを書いたことがない初心者なんですけど,
Haskellで言うところのリスト内包表記をマクロで定義することもできるんですかね?
たとえば,1..10のうち偶数を取り出すというのをリスト内包表記で表すと
[x | x <- [1..10], even x]
のように,数学の式と同様に表現できます.
内容は,| 以降の条件をすべて満たしたxの集合を表します.
こういうシンタックスシュガーは,Schemerは好まないものですかね?
Haskellっておもろい?
ってスレ違いか。
217デフォルトの名無しさん:02/03/31 14:44
The Little Schemerをamazon.co.jpで頼んじゃった
まだ全然Schemeを使いこなせてないのにぃ
>>217
お。奇遇だね。俺もたった今注文してきたとこだよ。
俺もschemeまだまだわからないけど。多分あの本ってこれからschemeをやろうっ
ていう人が読むような本なんじゃないかな。
Little Schemerは名著です。
しばしば「Common Lisp は実践的、Scheme はアカデミック」みたいな事が
書かれている文書を見るのですが、何がそう言わしめているのでしょうか。
個人的には、Scheme は十分実践的だと思っています。
Common Lisp ライブラリ関数の膨大さ故でしょうか。

Common Lisp には Allegro CL があるから
222デフォルトの名無しさん:02/04/01 01:32
Chez Schemeはダメなんだろうか.
223デフォルトの名無しさん:02/04/01 03:47
>>220
> 個人的には、Scheme は十分実践的だと思っています。
「個人的」だからじゃないかな?
gaucheを「日常業務の中でのちょっとした処理を行うスクリプトを気軽にScheme
で書」くために使わせてもらっています。というか勉強中です。
225デフォルトの名無しさん:02/04/01 19:51
>>220
Common Lisp は remove と delete, reverse と nreverse といったように、
同じ動作で効率を重視した破壊的関数が用意されているあたり実践的なんじゃないかな。

あと、一つの関数でもキーワード引数で
* (remove 2 '(1 2 3 1 2 3))
(1 3 1 3)
* (remove 2 '(1 2 3 1 2 3) :count 1)
(1 3 1 2 3)
* (remove 2 '(1 2 3 1 2 3) :count 1 :from-end t)
(1 2 3 1 3)
* (remove 2 '(1 2 3 1 2 3) :test #'>)
(2 3 2 3)
と使いでがあるあたりも。
226220:02/04/01 22:14
>>223
「僕の個人的な意見としては」という意味だったんですが。
それとも「個人的な意見」に留まってしまっているのが原因、と?

>>225
なるほど。他にも &optional のような、一見クリーンでなくても実践的な
仕様がありますね。なにも「Scheme は実践的ではない」という意味で
捉えなくても良いって事でしょうかね。
227Gauche しゅごーい。:02/04/02 04:16
>>224
俺と同じ人がいた。
228デフォルトの名無しさん:02/04/02 07:11
Schemeで質問です。
let/let* と letrec の違いがいまいち理解できてないのですが、

let/let* はclosureが評価された値をバインド
letrec はclosureそのものをバインド

という理解でいいのでしょうか?
ちがいます。>228
>>228
このスレのPart3(いま見えないけど)にあったvarマクロ使ってるけど、
あれネストが減っていいですよ。
(var a 1
var b 2
var c (+ a b)
c
)
=>3
誰か call/cc で java 風な例外処理できるやつ書いて見せてくれないかなぁ。。
とか逝ってみるテスト
233デフォルトの名無しさん:02/04/03 15:02
>>232
(try
...(throw tag)
catch tag
...
finally
...)
って感じのならあるけど、アプしようと思って、今読み返したら、
結構長かった。
作りは、
・lispのcatch & throwのエミュ
・lispのunwind-protectのエミュ(javaのfinallyに対応)
・(try ... catch ... finally)を許す様に簡単な構文変換
の組み合わせで、
catch/throwはcatchで継続と一緒にタグをグローバルな変数へ登録、
throwでその変数を検索といった感じです。
>>233
call/cc の使い方について、ループからの脱出以外にどんなものがあるかを知
りたいので、
>・lispのcatch & throwのエミュ
だけ良かったら見せてもらえますか?これも長くなりますか?
235233:02/04/03 19:22
>>234
(define -*-root-*- '()) ;トップレベルに戻るための環境
(call/cc (lambda (cont)
 (set! -*-root-*- cont) ))

(define *exception* '()) ;例外補足用のtag環境リスト
;(catch <tag> . cont)または
;(catch all . cont)または
;(finally . cont)

(define (throw-value tag result)
 (let loop ((x *exception*))
  (if (pair? x)
   (cond
    ; catch <tag>
    ((and (eq? (caar x) 'catch) (eq? tag (cadar x)))
     (set! *exception* (cdr x))
     ((cddar x) result))
    ; catch-all
    ((and (eq? (caar x) 'catch) (eq? 'all (cadar x)))
     (set! *exception* (cdr x))
     ((cddar x) result))
    ;finally
    ((eq? (caar x) 'finally)
     ((cdar x)) ; finally
     (set-cdr! (car x) (lambda())) ; dmy-closure
     (loop (cdr x))
    )
    (else (loop (cdr x)))
   )
   (begin
    (set! *exception* x)
    (puts "Cannot throw tag and perform a reset"
     (list 'throw-value tag result))
    (-*-root-*- result)
   ))))
236233:02/04/03 19:22
;sequenceかどうか
(define (sequence? l)
 (and (pair? l)
    (pair? (cdr l))))

;sequenceを置けるthrow (throw tag seq...)
(define-macro (throw tag . body)
 (list 'throw-value tag
  (if (sequence? body)
    (cons 'begin body)
    (car body))))

(define (lisp-catch tag body)
 (call/cc (lambda (cont)
  (set! *exception* (cons (cons 'catch (cons tag cont)) *exception*))
  (throw-value tag (body)))))

(define-macro (catch tag . body)
 `(lisp-catch ,tag (lambda () ,@body)))

(define (call-with-catch tag test catch)
 (let ((throw? #t))
  (let ((result
   (call/cc (lambda (cont)
    (set! *exception* (cons (cons 'catch (cons tag cont)) *exception*))
    (throw-value tag (prog1 (test) (set! throw? #f)))))))
   (if throw?
    (catch result)
    result))))

(define (unwind-protect test finally)
 (let ((current *exception*))
  (push (cons 'finally finally) *exception*)
  (let ((r (test)))
   (set! *exception* current)
   (finally)
   r)))

237233:02/04/03 19:25
>>236
>(define-macro (catch tag . body)
> `(lisp-catch ,tag (lambda () ,@body)))

(define-macro (catch tag . body)
 `(lisp-catch ',tag (lambda () ,@body)))
でした。
238234:02/04/03 23:01
>>235-237
ありがとうございます。今から研究します。
239デフォルトの名無しさん:02/04/04 10:48
CommonLispの本、出た?
240デフォルトの名無しさん:02/04/04 12:55
>ANSI Common Lisp入門 
> -5月下旬発売予定-
http://www.pearsoned.co.jp/washo/nbindex_may.html
Schemeって最初は継続ってなかったんでしたっけ? だからSICPには載ってな
いとかこのスレかどっかで見た覚えがあるんですが。
242デフォルトの名無しさん:02/04/05 11:45
SICPの4章のschemeインタプリタを
継続対応にするにはどうすればいいんですか?
243デフォルトの名無しさん:02/04/06 11:26
GUYの論文よめ
244デフォルトの名無しさん:02/04/06 17:51
λμ計算ってなに?
継続や例外処理が使えるようにλ理論の拡張したものらしいけど・・
何か参考になる本、Web無い?
誰か教えてー。
245デフォルトの名無しさん:02/04/08 21:25
論文はたくさんあるけど、本は知らないなあ。スマソ。
かわりといっては何だがhttp://www.cs.uu.nl/~franka/refでもどぞ
プログラミング言語理論のオンラインテキスト集。(既出か?)
http://www.shiro.dreamhost.com/scheme/trans/being-popular-j.html

Lisperらしき人がCommon Lispをボロクソに言っているように見えますが、こ
のスレのLisper/Schemerな人たちどう思いますか?
Schemeはhackerのための言語でしょうか。ライブラリが充実しているかどうかっ
ていうところが問題かな?
もしかして既出だったらごめん。
 商業的な利用が少ないのもそこら辺が一番のネックなのだろうか。
 >ライブラリが貧弱
これって2001年に書かれたんだよね。
schemeについて全く触れられてないけど。。。
>>246
Gauche の開発者の人の訳文だし、このスレの人は結構見てるかも。
Common Lisp への批判は、今日の Java への批判に通じる物があるね。
この文章を書いたた人は Python が好きそう。
Common Lisp について批判しているのは、便利なライブラリが揃っていないのと
ハックに使いにくい事みたいだけど、本当ですか?
Common Lispでコードを書き始めると、最後までCommon Lispで仕上げる
ことになりがち。他の言語やツールと連携することは、可能ではあっても、
快適にできるというわけではないから。だからハック向きの言語ではない
と言って良いと思う。Perl/Python/Rubyは他の言語やツールと連携する
のが得意だし、カンタンな処理はごく短いコードで書けるから、ハック向
きの言語だよね。

件のページに書かれているように、今すぐ書いて処理したい仕事では、文
字列処理がその多くを占める。だから強力な文字列ライブラリのある言語
は「実用的」だと言えるよね。Common Lispはそうじゃない。カンタンな
フィルタプログラムを書こうと思っても、そんなにカンタンじゃない。
UNIX文化にどっぷりつかっている言語と、OS側の機能を前提としない言語
の違いと言ってもいいかもね。
253デフォルトの名無しさん:02/04/10 16:00
LISPで文字列処理するのって、何かメリットありそう?
254デフォルトの名無しさん:02/04/10 18:44
>>253
文字列処理がLISPでできるというメリット
255デフォルトの名無しさん:02/04/10 18:53
The little Schemer がいまアマゾンから届いた。
かなり変わった構成だな。
正直、
(car "あいうえお")=>\あ
とできて嬉しいのかと問いたい。

(cdr "あいうえお")=>"いうえお"
うむ。
257デフォルトの名無しさん:02/04/11 15:36
scheme制御構造めちゃくちゃ強力だね。
(call/cc (lambda (break) ....
このbreakとか。
>>257
breakくらいならたいていの言語にあるだろうけど。
継続のもっと強力な機能が知りたいな、とか逝ってみるテスト。
259デフォルトの名無しさん:02/04/11 15:53
 >>258
いや、このbreakを変数の様に持ち回れるって所は他の言語にはないでしょ?
>>258
継続あればなんでもできるよ
継続は力なり
継続難しいよぉ
「継続を使えばできるよ」
「マクロでできるよ」
……こんなのばっかりです、
>>263
だから?
>263

素晴らしすぎると思うのだが。

初めてEmacs-Lispでマクロの練習したときは、その強力さにオロロイタ。
Schemeとかで「プログラムのためのプログラム」組むのも大事だけど、やっぱエディタのマクロ組むと楽しいと思う。
実用的なマクロができあがるとうれしいもの。
scheme やってから Emacs-Lisp 見たら while にとってもとっても違和感があっ
た。
;; とか言って scheme じゃ算数の問題解くだけしかできないけど(w
267263:02/04/11 22:01
>>265
>素晴らしすぎると思うのだが。
そう言いたかったんですよ。ごめぬ。
268デフォルトの名無しさん:02/04/12 01:31
だれかLittle Schemer 読んだ人いる?
漏れは今読んでるぞ。
> Little Schemer

That was too easy!:P
I've just read a few pages and never opened it again.
Well, but it might be true the book sometimes is useful.
270デフォルトの名無しさん:02/04/12 02:36
なんで英語でしゃべってんのか知らんが(w
あの本は非常によく考えられて作られてると思うぞ。
>>265 のいってるマクロの意味が違っていると思うのは俺だけ?
言いたいことはわかるが。
>>271
みんな思ってる。
あれ・・Little Schemerって英語で読んでるんじゃないの。
Is it true that it is an atom?
atom
で始まって、答えが
Yes,
because atom is a string of characters
beginning with the letter a.
邦訳はどんな感じですかいね。
275217:02/04/12 11:24
未だにamazonから来ないのは,俺が発送料などをケチったからか…
emacs-guile の gauche 版だれか作ってくれないかなぁ、
とか言ってみるテスト。
>>275
船便で半年後にくる、に500みずぽ。
278218:02/04/12 20:29
>>275
うちもまだ来てないよ。半年も先なのか(鬱
279デフォルトの名無しさん:02/04/13 04:55
The little Schemer
アマゾンで注文して2週間できたよ。
大学の本屋で買った。>The Little Schemer
>>280
あんたがどこで買ったかなんて興味ない
EmacsLispプログラミング入門ての買った。
Lispってけっこうおもしれー。
どういう用途があるのかよくわかんないけど・・・
lisp勉強しようと思ったとき、コンパイラってどこにある?
284デフォルトの名無しさん:02/04/13 13:35
>>282
文字列処理だよ!文字列処理!!
>>283
Emacs
>>285
ありがと
emacsをlisp使ってる人は沢山いそうだけど、
逆にemacs以外のエディタでlispプログラミングしてる人いる?
おれはそんなの考えられないんだけど。
WindowsのXyzzyとか。一種のCommon-lisp Emacsだけど。
>>281
いけずぅ。
290腰の曲がったおじいさん:02/04/13 16:18
>>287
.sawfishrcを書く程度ならviを。
emacsをlisp知らないで使ってる人は
の間違い、ごめん。おれは287.
292デフォルトの名無しさん:02/04/13 19:30
俺の知り合いは、ばりばりのScheme使い&vi使い。
もちろん、Schemeのプログラムもviで書いてる。
293285:02/04/13 19:36
とりあえずxyzzy使って勉強してみることにする。

SchemeとLispの違いって何?DelphiとPascalの違いみたいなもん?
外出質問かもしれん
294デフォルトの名無しさん:02/04/13 20:57
LIsp は難しいので教育用としてSchemeが作られたんだよ!
>292

何ゆえにその人物はScheme処理系使わないの?
中途半端に絵がうまい人は、線を何度も引いて全体のバランスをとる。
真に絵がうまい人は、線は一度しか引かない。Scheme の哲学しかり。
と、自分なりに思ってみた。
結局、>>294を信用していいのかな?
298腰の曲がったおじいさん:02/04/14 07:47
いや、教育用として良く使われているのは結果。
Actor理論に基づいた(Lisp風の)処理系を作るのが当初の目的。
過去スレ読めば文献ポインタもある。
299デフォルトの名無しさん:02/04/14 09:09
ソースコード公開している Scheme の小規模な処理系を
コレクションしています。

 mini scheme
 tiny scheme
 ki-scheme
 am-scheme
 LispMe

他にもあったら教えて下さい。
ki-scheme のソースは日本語で丁寧にコメント書いてあるし、
SJIS が通るので良い感じ。
何れは俺も作ってみたいな、scheme 処理系。
s-lisp
つーかemacsでプログラムを書くなんて俺には耐えられない
俺にはだよ,俺には.
開幕から一度でも
打撃戦ってあったか?
303不覚:02/04/14 15:36
誤    爆
304デフォルトの名無しさん:02/04/14 21:07
Meadow vs xyzzy の壮絶な打撃戦か?
Meadowやxyzzyに火よってはならない!
純正のEmacsを使うのだ!
>>304
[[LK9-herTeMV3]]
<<xyzzy>>に一票!

……は置いといて、
>>293
> DelphiとPascalの違いみたいなもん?
LispとSchemeは「どちらかはもう一方の物を拡張した物」等と言った関係ではないので、違います。
実際の違いについては、>>294が一番分かりやすいと思う。
>>294はただの勘違いだけれど、そんな勘違いを生む程度の違いがあります。
307デフォルトの名無しさん:02/04/14 23:23
ようやくThe Little Schemerを配送したとの通知が.
いい加減講義も研究もしなければならないから読む暇無いぞモルァ
308デフォルトの名無しさん:02/04/14 23:24
子供さんに読ませるの?
講義をしなきゃいけないような人間が今頃the little schemerかよ・・・
教わる学生が不幸すぎる・・・
310デフォルトの名無しさん:02/04/14 23:39
うーん、でも子供向けの本って、
「ママみたいに優しく教えてよ!」ってな感じの
プログラミング苦手初心者には、効果的かも。

「プログラミング・マニアみたいな人」ばっかりだと、
この世界も広がらないしねぇー。
311デフォルトの名無しさん:02/04/14 23:51
常にカバンの中に入れておいて、食事の前に読むんだよ。
2時間で全部読むれっ!!!
313デフォルトの名無しさん:02/04/15 00:52
>>312
前書きに、rushするな!って書いてあるだろが!!ちゃんと前書きから読め!!
314デフォルトの名無しさん:02/04/15 00:58

今年の2月以降に製造された RX-2001 が、
たったの 9700 円!?↓
http://www.bidders.co.jp/user/1023585

買おうかな。
315Symbolics:02/04/15 02:11
>>314 Lisp machineでも売ってるのかとおもったぞ。
316Symbolics:02/04/15 02:16
Lispと Schemeの関係は Unixと BSDの関係みたいな物だな..
original (Lisp/Unix) があって、それが使いやすくて亜種がいっぱい
できて、そのうちの分派 (Scheme/BSD) が使いやすかったので
そのなかで大きな一派になっている。
で、その一派から originalに吸い上げられた機構 (Static scope/TCP)
もあったりして、ぐちゃぐちゃになってると。

我ながら強引な説明だ。
>> 280
部外者でも買えるの?
それともダイガクセイを装って買った方がイイ?
>>317
部外者でも買えるYO! 学生割引が使えないだろうけど。
それでも中高生ならアカデミックパックは買える。
319デフォルトの名無しさん:02/04/15 12:19
gauche でランダムな1桁の数を求めたいんですけど。

(sys-srandom (sys-time))
(modulo (sys-random 10))

とやってみたけど始めの1桁がかたよってしまいます。他にいい方法あったら
教えてください。
schemeつかてる人は、無条件でCも使えると思って良いでしょうか。
ごめん。Cは使えない。FORTRANならなんとか。。。
322デフォルトの名無しさん:02/04/15 16:59
>>321 ネタ?
初期のList処理はFortran上で行われていて、
そこからList処理拡張を持つFortranや、Lispが生まれた、とか、
Lispの初期の実装系はFortranで書かれたって、知っているよね?

>>321 は罰として、Fortran-moniterシステム使ってLisp machine作ってくだちい。
>>321-322
この繋がりが良く分からない
>>323
同じく。
325322:02/04/15 17:24
>>324
激同
326322:02/04/15 17:26
いや、>>320の質問自体意味不明なのだが?
>>325-326
この繋がりも分からない。
みんなLISPはよくつかっとるのかね?
レスつけにくいな
>>328 昔はLispコンパイラーやSchemeの実装にも手を出してたけど、
   今はEmacsとWnnの設定の時ぐらいしか使わない。
   暇があったら GIMPで遊んでみる事にしよう...。


LISPだけで食ってる奴はいるのか
Scheme メインで食っていきたい。他にも、C と Perl なら使っても良いかな。
あくまで補助として。
333デフォルトの名無しさん:02/04/16 00:39
…なんだか俺が教授扱いになっているくさいが,俺は大学院生.
講義はするじゃなくて受けると言えば良かったのか.失敬.
334デフォルトの名無しさん:02/04/16 00:43
   ★★★★★★★★★★★★★★★★★★
       This space reserved for
         JELLY STAINS!
   ★★★★★★★★★★★★★★★★★★
>>323-324
同じく。
俺の予想では Lisp スレで Fortran という単語を見た
>>322 は知識をひけらかしたい欲求にかられたのだろう。
336デフォルトの名無しさん:02/04/16 02:37
>299
Gauche はちょっと大きいかな?
http://www.shiro.dreamhost.com/scheme/gauche/index-j.html

あと、ここみたいに >299 がリンク集にしてレスしてくれると
幸せかもと思ったり……
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/scheme.html
337322:02/04/16 03:13
>>335
>同じく。
>俺の予想では Lisp スレで Fortran という単語を見た
>>322 は知識をひけらかしたい欲求にかられたのだろう。
それはどうかな?
最近このスレ、つまらなくなってきているので、
話題の転換を図ろうとしたんですけどねぇ。

もしかして、学部生レベルを超えた話題は全て、
「知識をひけらかしたい部外者」のレスって思ってませんか?
>>319
擬似乱数の生成法によるけど、手元のmanでrand(2)を見ると
上位ビットを使えと書いてある。
Cならj=1+(rand() % 10)ではなく
j=1+(int) (10.0*rand()/(RAND_MAX+1.0))とやれと。
339321:02/04/16 03:45
FORTRANは数値計算しかしないので。。。
LISPは最初はFORTRANで実装されていて、遅かったという話しは読んだことある。
CommonLispの入門書でだったかな?

http://www.jah.ne.jp/~naoyuki/Writings/VScheme1.html
を読んでやってみたい気もするが、まずはSchemeを使いこなしたい。

このスレが最近単調なのは同感だけど、歴史談議は興味がない。
リアルタイムで知ってるやつもいないだろうし。

Gauche+xml(rdf)+CGIでいろいろやりたいから、その方面の話題を希望。
#英語はなかなか読み進められないんだよ。。。
はぁ、がんばってね。

#英語はなかなか読み進められないんだよ。。。
#って意味不明
341335:02/04/16 04:08
>>337
> それはどうかな?
> 最近このスレ、つまらなくなってきているので、
> 話題の転換を図ろうとしたんですけどねぇ。
へー、そうだったんだ…。変なこと言ってゴメソ。

> もしかして、学部生レベルを超えた話題は全て
とりあえず俺には>>322は学部生レベルを超えた話題には見えない。

> 「知識をひけらかしたい部外者」のレスって思ってませんか?
思ってないよ。
>>321-322 の流れが謎すぎたからそう思っただけ。
# つか「部外者」ってなんだ?

というかこのスレは学部生レベル (ってのもよくわからんが)
を超えてるであろう話題がいっぱい出てますが
「お前はただ知識をひけらかしたいだけちゃうんかと」なんて一度も思ってないですよ。
ただひたすら「勉強になるなぁ」と。
# 実際は理解できない話題が多く、あまり勉強になってないかもしれんが…。
342デフォルトの名無しさん:02/04/16 08:46
portの汎用化とかは面白そうなんだけど。
with-in/out系が生きてくるし。
343のほほ:02/04/16 13:16
学部生って逝っても、ピンからキリまでいるし。
計算機まわりの知識とかスキルって、
自分でがつがつ食っていくもんだから、
○○レベルってのはそのへんに置いとこう。

俺みたいに単に興味本位でいじってる人間には
食え「そう」なものがいろいろ落ちてるスレってだけでいいんだけど。
食う、食わないはべつにして。
lisp,schemeがエンプラで普及しない理由が現れてるな。
schemeだけの話ってわけではないけど、これ面白い。
https://rakunet.org/TSNET/topics/compare.html
346デフォルトの名無しさん:02/04/16 15:38
で。。。

;;; 解3
;;; 継続の呼び出しでループを実現するひねくれた解
(display
(let ((total 0))
(let ((next (call-with-current-continuation (lambda (k) k))))
(let ((num (read)))
(if (zero? num)
total
(begin
(set! total (+ total num))
(next next)))))))

これを set! なしで書くことできる?解2のやつはできたけど
こっちはわかんない。
347のほほ:02/04/16 16:24
>345 イイ!
348デフォルトの名無しさん:02/04/16 17:00
>>344 lisp,schemeがエンプラで普及しない理由が現れてるな。
 企業では、AI的用途(エキスパート・システム等)でだいぶ前に導入されて、
 今は廃れているという罠
 #データ・マイニングとか、ナレッジ・エンジニアリング周りにはAIの残党も残っているけど、
 #金融/投資といったシビアな分野ではどーでしょ。(Lisp使う使わないって問題じゃないでしょうね)

 大昔から、Lispいじりは大学2年の夏休み自由課題と相場が決まっている罠
 
349のほほ:02/04/16 17:05
>348
でも Emacs を使っている人間は Lisp をいじりつづけるという罠
どういう時にLISPが必要になるんだ!?
生活感をまじえつつ教えてくれ
湾岸で戦争したくなったとき
つーか、知らず知らずのうちにLISPの恩恵を受けてると思われ
353デフォルトの名無しさん:02/04/16 19:10
>350
LISPのマクロを使いたいとき
そうだ
そのマクロをつかいたいときってどんなとき!?
>>354
楽したいとき。
>>351
Adaも使う破目に。
357デフォルトの名無しさん:02/04/16 20:44
C++など複雑な言語仕様のプログラミング言語を
触っているとき。
でLispなんて単純すぎると嘆き、結局元の言語にもどる罠
単純だからこそ発想力が求められる。一般人には無理だという罠。
自作エディタにLISPインタプリタのっけたいと思ったら
0から自作?
360デフォルトの名無しさん:02/04/16 21:21
このスレの >>299 のどれかからソース引っ張ってくれば?
361デフォルトの名無しさん:02/04/16 23:45
The Little Schemerが届いた.
本を開いた瞬間仰天した.
子供に読ませるの?というレスがあった理由が分かる気がするよ.
この程度の本なら,英語が苦手な友達も気軽に読めそうな気がする.

が,名著たるゆえんが見いだせそうにないのだが…
362デフォルトの名無しさん:02/04/16 23:51
>>361
よく読んでみろ!!
めちゃめちゃ作りこまれてるぞ!!
角度とか。
364229:02/04/17 01:23
>>336
リクエストにお答えして。
TinyScheme と Minischeme はこのスレの上の方>>204-205
にありました。

Gauche は小規模と言うには本格的過ぎます。
そう言えば、Gauche 0.5.3 がリリースされたみたいですね。

ソースコードを公開している Scheme の小規模な処理系を
集めてみました。
こうして見ると、日本人の作による物が多いですね。

TinyScheme: 下記 Minischeme の発展版
http://tinyscheme.sourceforge.net/

Minischeme: 1 ファイルに凝縮された Scheme 処理系
http://tinyscheme.sourceforge.net/minischeme.tar.gz

KI-Scheme, AM-Scheme, etc...
http://www.nifty.com/download/dos/prog/lisp/

LispMe: Palm 上で動く Scheme 処理系
http://www.lispme.de/lispme/

スレのテンプレに入れて下さると嬉しいです。
365364:02/04/17 02:52
間違った。229 じゃなくて 299 です。

>>359
KI-Scheme が良いんじゃないでしょうか。
コメントが充実していますし、SJIS も使えます。
>>364
336じゃないけどサンクス。
確かにKI-Schemeは読みやすいね。
>>361
再帰をしっかり理解できている人にとっては
不動点演算子とインタープリタの所以外は、簡単すぎるかもしれない。

再帰を知らない人に、再帰を理解させる本だね。
おいらは 「List遊び」で初めて再帰がわかった。
web で調べてもさっぱりだったけど。
>>361
うん、簡単だよねぇ。
2時間で読むれっていったら誰かさんが「急ぐなヨ」とか逝ってたけど、
オレは30分で読んだYO!
>364
まさか本当に >299 がまとめてくれるとは。THX
KI-Scheme って Makefile 修正したら cygwin で make できる?
聞く前にまず自分でやってみろ
>>372
マターリ
374371:02/04/17 22:20
>>372
いや普通にmakeしてもできなかったから、修正したらできるのかなと。
自力でMakefileいじったりできないから聞いてみた。
>>358
「自分は一般人とは違う」などと勘違いしてしまう罠
>自力でMakefileいじったりできないから聞いてみた。
はあ?
377デフォルトの名無しさん:02/04/18 17:42
http://www.shiro.dreamhost.com/scheme/index-j.html
>「なんでも継続」を書けばなんでも三部作完結

早く読みたいなぁ。。
概出だけど Gauche-0.5.3 age
378デフォルトの名無しさん:02/04/18 19:45
Is is true that this is an atom?
manko

Yes,
because manko is a string of characters
beginning with the letter a.
しまった、aで始まってなかった
>Is is true that this is an atom?
( ゚д゚)ポカーン
ぐは。
そこもまちがっとった。
もうだめぽ。
383デフォルトの名無しさん:02/04/19 07:32
http://www.shiro.dreamhost.com/scheme/docs/schemersway-j.html
を読んだんだけど、プロダククションコードでは処理系依存の
機能をばりばり使っていい、ってのは変じゃ?
その codeをほかの処理系を使ってる人に使ってもらう、とか
いうことを考えなくていいん?
そういうのを考えるのはプロダクションじゃないとか?

ちゃんと読んだかぁ?
やっぱscheme最高!
>383
しろーたん萌え (;´Д`)…ハァハァ
(define func
(lambda (arg1 arg2)
...

(define (func arg1 arg2)
...

どっち派?
どっちがきれい?
388デフォルトの名無しさん:02/04/19 21:25
>>387
わたしゃ、lambda派 
MITスタイルは好きになれない。
>>388
後者はMITスタイルって呼ばれてるんですか?
>>387
後者が好き。打つのも読むのも楽。構文糖は徹底活用すべし。
391デフォルトの名無しさん:02/04/20 18:07
SICP 2nd ed. 届いたage
392デフォルトの名無しさん:02/04/21 00:07
どっち派でもないが、
(define func (lambda (arg1 arg2) ...
(define-function (func arg1 arg2) ...
と分かれていた方が好き。

(define (func arg1 arg2 . rest) ...
これはうまいな、と思うけども。
>>387
どっち派もクソもねーだろ、このホゲ。
(define f(let(...)(lambda(args)...)))
↑みたいに特に理由が無い限り
(define(f args)...)
に決まっておろーが。
394デフォルトの名無しさん:02/04/21 18:29
>>393
まあ、どっちでもいいけど。
Kent dybvigさんの本だとlambdaを使っているね。

λ式に名前をつけるって感じでこっちが好きだけど、
構造と解釈の普及でlambda無し方が今や主流なのかな。

395389:02/04/21 20:30
で、SICPがlambda無しで書いてるから「MIT派スタイル」なんだろうか。
396デフォルトの名無しさん:02/04/21 22:51
つーかただの構文糖だろ
スタイルもなにもない
じゃあ、SICPスタイルとか、サスマンスタイルとかにしとけ。
398デフォルトの名無しさん:02/04/21 22:55
ループって、
doとnamed-let,letrecどれで書けばいいの?
399398:02/04/21 22:56
あ、schemeの事です。
400デフォルトの名無しさん:02/04/21 23:01
つーかさ、再帰で書け
named-letに一票。
ふつーnamed-letだよな。
多分。
named-letはletrecの構文糖なんだっけ?
doは括弧使いすぎ。
読みにくいよ。
405デフォルトの名無しさん:02/04/21 23:19
うるせー、カス
はぁ、なんなの?
407デフォルトの名無しさん:02/04/22 02:20
SRFIって infoになってたりしないかな...
つーか、みなさまは SRFIに乗ったライブラリとかを
使ってるんでしょうか??
Little Schemer の不動点演算子の部分は、
(Y Y) Works! A Lecture on the Why of Y
ってタイトルで
PostScriptファイルが手にはいるよ。
409デフォルトの名無しさん:02/04/23 02:13
あんま関係無いけどさ、PostScriptファイルをWindowsで簡単に見る手段ない?
GhostScript入れるとか無しに。
>>409
GhostScript入れるのが一番簡単だと思うが。
411デフォルトの名無しさん:02/04/23 09:29
>>410
このまえいれてみたんだけど、
日本語がうまく表示できなかった。
412デフォルトの名無しさん:02/04/23 11:10
激しくスレ違いだけど、
Postscriptで配布されている論文読むためだと勝手に信じて、
http://www.fsci.fuk.kindai.ac.jp/~kakuto/win32-ptex/web2c73.html
の下にあるGhostscriptのどれか。gnu-gs652j-full-w32api.zipが簡単かね。
・Adobeの製品を買う。
・UNIXを使う。
のどれかを。
>>412
確かにスレ違いだけど、このスレは論文とかpsファイルの参照って
結構多いから、こういう情報は助かります。
The Seasoned Schemer はどう?
読んでる人少なそうだが。
>>409
Adobe Acrobat 5 買いな (無料の Reader じゃなくて)。
ダブルクリックで PostScript ⇒ PDF に変換してくれるから。
ただし、よく失敗するけど (GhostScript も同じか)。
416デフォルトの名無しさん:02/04/23 12:28
GSは>>412のリンクのもの、
GSViewはここにあるのを入れて動きました。
ttp://www.matsusaka-u.ac.jp/~okumura/texfaq/bibun2e/gsview.html
素直に印刷しれ
>>299さんへ
scheme処理系を発見しました。
http://www.jah.ne.jp/~naoyuki/index.html
>>418
「Schemeを作ろう」だって。
難しくてわかんないや。
>>419
それは末尾再帰展開に対応してないので、schemeとは呼べませんな
421デフォルトの名無しさん:02/04/23 22:30
末尾再帰展開に対応してないと、schemeとは呼べないの?
実装が義務。
R5RSにも必須と書いてある。
末尾再帰をサポートしないと、ループ回すうち
スタック溢れちゃう。
424デフォルトの名無しさん:02/04/23 22:37
>>423
>スタック溢れちゃう。
常にそうなるとは限らないと思うけど・・・
プログラミング言語としては末尾再帰無いとナンセンスかな?

ちなみに継続 call/ccは必須うなのかな?
425デフォルトの名無しさん:02/04/23 22:44
ピア損の「計算機プログラムの構造と解釈第2版」って糞訳なの?
>>425
前半は気になるところがいっぱいあった。
後半はあまりそう思わなかった。
慣れただけかもしれないし、訳者が違うのかもしれない。
>>425
http://www-mitpress.mit.edu/sicp/
原文が全部のってるから、読み比べるよろし。
428デフォルトの名無しさん:02/04/24 17:57
pythonは言語標準で継続を取得できるんだっけ?
それとも一部の実装で?
誤爆ですか? Lisp Scemeスレですけど。。
430デフォルトの名無しさん:02/04/24 18:46
>>429
継続だけに繋がりが重要ということで。

>>428
継続が使えるように拡張された実装があるらしい。
今はpython本家でも使えるようになったのかな?
Stackless Python
http://stackless.com/research/stackless/


>>430
本家には入ってないようです。
432429:02/04/24 20:22
今頃気づいたけど typo してた。恥カスィ。
Sceme → Scheme
433デフォルトの名無しさん:02/04/24 20:23
rubyにも継続を付けるとかいう話無かった?
ふと思い付いた便利そうな手続き。

(define (boolean x)
(if x #t #f))
435sage:02/04/24 21:45
debian(sid) の ILISP で guile での補完機能が動くようなってる♪
って以前から動いてた?
とにかく c-w-c からいっきに call-with-current-continuation 補完されるのは最高。
and?
437434:02/04/24 22:10
>>436
and だと boolean value 以外も返しちゃうから駄目なんです。
438434:02/04/24 22:25
こんな感じで使えるかな、と。

(define (whitespace? ch)
(boolean (memv ch *whitespace-chars*)))
Scheme一般のルールとして#f以外が真とみなされるなら、
あえて#tと#fにそろえる必要もないんでは。
440434:02/04/24 23:11
>>439
それは分かるんですが、述語は真偽値を返した方が気持良くないですか?
まぁ、考え方の違いでしょうか。
考え方っつーより趣味じゃん。
442デフォルトの名無しさん:02/04/25 01:20
Cだと真偽値は整数だから、!!x は0/1になって意味があるけどねぇ…
443デフォルトの名無しさん:02/04/25 01:49
(eq? 'a #t)
=>?
これは#t/#fどっち?
当然 #f。っていうかどういう質問?
445デフォルトの名無しさん:02/04/25 02:37
>>435 ILISPってなーに?
Package for interacting with LISPs using EMACSes

ILISP is a powerful GNU Emacs interface to many dialects of Lisp,
including Lucid, Allegro, Harlequin LispWorks, GCL, KCL, AKCL, ECL,
IBCL, and CMUCL. Also some Scheme implementations are supported as
well as a preliminary version of Xlisp/XlispStat.
447デフォルトの名無しさん:02/04/25 07:50
Gauche-gl以外で,OpenGLが使えるライブラリはありますか?
とりあえず候補を色々知っておきたい.

…と調べていたら,GuileGLなるものをハケーン.
試してみるか…
http://atrey.karlin.mff.cuni.cz/~0rfelyus/guileGL/
448デフォルトの名無しさん:02/04/25 09:08
>>444
#f以外は全部#tとみなすんじゃないの?
>>448
それはこういう場合でしょ。
(if 'a 'true 'false)
=> true
450デフォルトの名無しさん:02/04/25 10:14
>>433
付いてる。callcc{}。
新バージョンでは捨てるという話を聞いたような聞かないような。

>>448
#f以外は真として扱うというだけであって、#tとして扱う訳ではありません。
偽:#f
真:#fを除く全てのもの
451デフォルトの名無しさん:02/04/25 12:36
あと、#fとnilと'()はちがうんだよ
nilはschemeだとただのシンボル
elisp の t,nil に慣れてたから #t,#f には違和感あったなぁ、最初。
あと set! とかが返り値ないのも。
453デフォルトの名無しさん:02/04/26 10:10
GuileGLが,make中にエラーを返してきたので,
おとなしくGauche-glでやってみることにしたり…
Gauche-glって何ができるんだろ。
OpenGLって何だろ。
無限ループの継続を生成してグローバル変数に束縛することってできます?継
続を生成するためには一回その無限ループを評価しないといけないですよね(?)
そうするとループから抜けられなくなるから、継続を束縛するところまではで
きるけど、その継続を評価してみることはできないってことになりますか?

;; 本に載ってるプログラムをいじって何をしてるのか実験してみたいんですが。
>>455
例えば、まず
(define top (call/cc (lambda (k) k)))
みたいにしてトップレベルへ脱出できるようにしておく。

で、欲しい継続を大域変数に保存したあとに、
top を呼び出してトップレベルに戻る。
抜粋すると
(call/cc (lambda (k) (set! global k) (top #f)))
みたいになる。
SCMのバージョンが5d6になってたよ。
http://www-swiss.ai.mit.edu/%7Ejaffer/SCM.html

>Tanel Tammet's Hobbit compiler is now integrated into the SCM distribution.
>Ported SCM to the PLAN9 operating-system.
>Ported SCM to OS/2, IBM VisualAge C++ v3.
>>456
なるほど。ありがとうございます。
勉強になりました。

下のようなコードを実行してみたのですが、
#<subr:"continuation">hoge
*** ERROR: bad procedure: #f
と言われてしまいました。

しばらく悩んでいたのですが、意味が分かりました。
(cc #f) から無限ループが始まることを期待していたのですが、(top #f)のと
ころでトップレベルに戻ってしまうために cc の値が #f になってしまってエ
ラーになっている、という解釈でいいんですよね。

;; 何がやりたいかと言うと、無限ループの継続を実行したら無限ループが始
;; まるだろう、というのを実験してみたかった。

-------------------
(define cc #f)
(define top (call/cc (lambda (k) k)))
(define (loop)
(let f ()
(call/cc (lambda (k) (set! cc k) (top #f)))
(display "hoge")
(newline)
(f)))

(loop)
(display cc)
(cc #f)
------------------
上の #<subr:"continuation">hoge
は (display cc) (cc #f) の出力です。
459デフォルトの名無しさん:02/04/26 17:48
>>458
cc の値は continuation になってるけど、 top の値が #f になってて、
(top #f) が (#f #f) になってエラーが起きているのでは。
(top #f) を (top null?) とでもすると期待どおりになるのでは。
>>458
ごめん。俺がかんちがいしてたみたい。
(define top (call/cc (lambda (k) k)))
のところからして、変だった。

(let () (call/cc (lambda (k) (set! top k))))
で、とりあえず動く。どうしてかは、よく判らん。
くわしい人に聞いて。

他の事しながら書いてるので、まだおかしいかもしれん。
461458:02/04/26 18:29
>>459さんに教えてもらった通り (top #f) を (top null?) にしたら期待通り
になりました。また (top (lambda (a) a)) でも大丈夫でした。

>>460
>(define top (call/cc (lambda (k) k)))
>のところからして、変だった。
これって変なんですか?うまく行きましたけど。

>(let () (call/cc (lambda (k) (set! top k))))
これは
(call/cc (lambda (k) (set! cc k) (top #f)))
この行を書きかえるんですよね。これでもうまく行きました。

うーん、だんだん混乱してきた(汗
462デフォルトの名無しさん:02/04/26 20:19
今現在で一番効率の良いとされてるgcって何?
gc しないことかな。
464デフォルトの名無しさん:02/04/26 23:27
scm on solarisで、
SCM version 5d6, Copyright (C) 1990-1999 Free Software Foundation.
;loading /home/research/lpsb/usr/local/lib/slib/require
;done loading /home/research/lpsb/usr/local/lib/slib/require.scm
を実行。

> (+ 1 2)
3
> (+ 1.0 2)
ERROR: unbound variable: 1.0
; in expression: (+ 1.0 2)
; in top level environment.
;STACK TRACE
1; (+ 1.0 2)

実数が使えません・・・。

> (sqrt 4)
ERROR: unbound variable: sqrt
; in expression: (sqrt 4)
; in top level environment.
;STACK TRACE
1; (sqrt 4)

sqrtがありません・・・。
なんで?
>SCM version 5d6, Copyright (C) 1990-1999 Free Software Foundation.
>;loading /home/research/lpsb/usr/local/lib/slib/require
>;done loading /home/research/lpsb/usr/local/lib/slib/require.scm

本当にこれしか表示されてないの。
5d5だと
> sqrt
#<CLOSURE sqrt "/usr/local/lib/scm/Transcen.scm": (z) (#@if (#@real? #@z) (#@if (#@negative? #@z) (make-rectangular 0 ($sqrt (- z))) (#@$sqrt #@z)) (make-polar ($sqrt (magnitude z)) (/ (angle z) 2)))>
てなってるから使えないんだろうって気がするけど。
+が知らない。rootで一回実行してみたら。
466デフォルトの名無しさん:02/04/27 09:54
>>464
-DFLOATS せずにcompileした。

scm.info読んだんか?
http://swissnet.ai.mit.edu/~jaffer/buildscm.htmlは? と小一時間(略
467デフォルトの名無しさん:02/04/27 11:38
schemeは数だけ特別あつかいしてる、ね?
468デフォルトの名無しさん:02/04/27 11:40
というか数値型で表現できる範囲は処理系に依存してる、か?
469デフォルトの名無しさん:02/04/27 11:41
CやVBみたいなinteger,longみたいな区分けをしてないだけか、ま?
470デフォルトの名無しさん:02/04/27 11:43
その割には文字型なんてものもあったりして区分けがいまいち、だ?
471デフォルトの名無しさん:02/04/27 11:46
個人的にはset!/ref/lengthとかは型によらず統一して欲しいだ、ろ?
472デフォルトの名無しさん:02/04/27 11:47
つーかなんでlistにlist-set!/list-refがない、か?
set-c[ad]r! と nth を使えば良いんじゃないかな。
474デフォルトの名無しさん:02/04/27 13:12
list-refはあるじゃん
(define animals '(inu neko buta))
(set! animals (cons 'ushi animals))

これは immutable object を変更することにはならないよね?
476デフォルトの名無しさん:02/04/27 16:20
>>475
環境が更新されるだけ。
この辺理解してない人多いね。
477475:02/04/27 17:21
>>476
ありがとう。確認の為に投稿させて頂きました。
478デフォルトの名無しさん:02/04/27 23:30
defineとset!は環境に作用するんだよ
他の関数set-car/cdr! string-set! vector-set!などは
オブジェクトに直接作用する
479デフォルトの名無しさん:02/04/28 00:51
あの〜〜、WINDOWSで使えるLispのフリーなコンパイラって何処に
あるんでしょう?
イーマックスを入れろ。
481デフォルトの名無しさん:02/04/28 01:41
windows lisp free compilerで検索しろほげ
482デフォルトの名無しさん:02/04/28 02:14
483デフォルトの名無しさん:02/04/28 02:42
へたれ学部生ですが、勉強になります。

ところでCやなんかと連携するとしたら、
みなさんはどういった風にやるのでしょうか?
大まかな感じでもいいので教えてもらえるとうれしいです。
484デフォルトの名無しさん:02/04/28 07:36
>Cやなんかと連携
組みこみって事かな?
とりあえずemacsでも触ってみれば?
485デフォルトの名無しさん:02/04/28 08:30
>>479

Petite Chez Scheme がいいよ。

コンパイラじゃないけど、めちゃめちゃ高速
486デフォルトの名無しさん:02/04/28 12:27
>>483
「みなさん」つーより、「system」によるだろ。

http://www.shiro.dreamhost.com/scheme/gauche/index-j.html
http://www.gnu.org/software/guile/

辺りを読んでみれば? (どっちもschemeだけど)
487デフォルトの名無しさん:02/04/28 12:31
guileはこっち挙げといた方がいいか。
http://www.swig.org/
488483:02/04/29 01:19
>>484-487
色々とレスありがとうございました。
自分でもよく分かってないので、要領を得ない質問になってしまい申し訳ございません。
ただ、Cとかの手続き型で書くのは面倒な部分のみをLispやSchemeで書いて、
Cとかで書いたものと組み合わせるとしたらどういった手段があるのかな?と思ったもので。
紹介してもらったものを色々調べさせてもらおうと思います。
489デフォルトの名無しさん:02/04/29 06:29
>>488
例えば始めから予測がつかない処理ってのがあるでしょ。
GUIのイベントハンドリングとか。
こういった処理をいちいちコンパイルして動作確認するのは面倒。
即席なコードどんどん書いていけるから便利だとおもう。
ある程度パターン化ができるならその部分はCとかに直して効率を上げていく。
>>489
状態遷移表を書けばいいんじゃないの?
>>489は単にインタプリタな言語ならなんでもいいように見えるが…
492デフォルトの名無しさん:02/04/29 12:42
>>490
プロトタイプから常態繊維はちょっと…
>>491
Lisp/Scheme好きなんでしょ、きっと
>>491
他のインタプリタな言語って例えば何?
LISPだとランタイム込みで数十キロ程度で済みそうだけど。
494デフォルトの名無しさん:02/04/29 14:08
schemeはCtrl+Cシグナルで継続吐く様にするだけで
プログラムの中断後にいつでも再開ができる。
これはLISPのデバッグモードみたいなのより自由度高い。

メモリーイメージダンプ取るだけで状態の永続化も簡単。
外部リソースとの連携という問題もあるけど。
suspend/resume時にフック関数を呼ぶ様にすればなんとかなる。
これがあると世界が変わるよ。
他の言語でもできる事かもしれないけど。
495デフォルトの名無しさん:02/04/29 14:49
Sexpr>>>>>>>>XML
>>495
文書の本文も文字列 "..." として埋め込むんですか?

497491:02/04/29 19:00
あ、そか、Cとschemeを比べた場合、とかいう話ね。
498デフォルトの名無しさん:02/04/29 20:21
Lispでなくちゃあ出来ない
ことって、どんなのがありますか?
>>498
Lisp 指向でプログラムを書く事かな。
Debian に乗り換えたので gauche の deb が欲しい、
とかつぶやいてみるテスト。
501デフォルトの名無しさん:02/04/30 01:45
call-with-in/output-fileとかに渡す関数の中で、
その場の継続を取得した後一旦外に脱出して、
後で再開する試みは成功するでしょうか?
(define (test)
 (let ((resume #f))
  (call/cc(lambda(suspend)
   (with-output-to-file "test" (lambda() (call/cc(lambda(cont)
    (set! resume cont)
    (suspend))))) ; with
   (if (not resume) (error "ポートが開けなかった"))
   ;ファイル'test'に"hello world\n"と出力
   (display "hello world")(newline)
   (resume)
  )) ; suspend
 )) ;let def test
>>501
残念ながら処理系依存。

(規格にはないけど)seekできる処理系ならdynamic-windを使って
「with-...から出たらcloseし、resume時にはopenしてseekして状態を復元する」
マクロを自分で書けるかも。
503デフォルトの名無しさん:02/04/30 02:22
まちがえました。正しくは↓
(define (test-open filename)
 (let ((resume #f))
  (call/cc(lambda(suspend)
   (let ((res
    (with-output-to-file filename (lambda()
     (call/cc(lambda(cont)
      (set! resume cont)
      (suspend))))) ;call/cc
     (set! resume (lambda())))) ; with
    (if res (res 'ok))
   ))) ; suspend
  (if resume (lambda()(resume (call/cc(lambda(c)c)))) #f)
 )) ;let def test-open

(define close (test-open "test"))
(display "hello world")
(newline)
(close)

これで通りました。
これが何なのかというと、ネストしまくった階層の継続を取得して
普通のファイルハンドルと同じ様に持ちまれるかどうか、
の実験です。
display〜部をトップレベルで評価し、openで得た継続(ハンドル)で
状態が戻ればネストを気にせずに色々とできそうだなということで。
504デフォルトの名無しさん:02/04/30 02:35
また間違い。これでラスト。
(define (test-open filename)
 (let ((resume #f))
  (call/cc(lambda(suspend)
   (let ((res
    (with-output-to-file filename (lambda()
     (call/cc(lambda(cont)
      (set! resume cont)
      (suspend))) ;call/cc
     (set! resume (lambda()))
    )) ; res
      )) ; with
    (if res (res 'ok))
   ) ; let
  )) ; suspend
  (if resume (lambda()(resume (call/cc(lambda(c)c)))) #f)
 )) ;let def test-open

(define test-close (test-open "test"))
(display "hello world")
(newline)
(test-close)

>>502
with系のポートをオープンしっぱなしという前提にすれば
再定義でできそうな気がするんですが。
505デフォルトの名無しさん:02/04/30 05:12
>>502
with〜をdynamic-wind前提で組まれると困ったりしない?
使い勝手を考えると制御用と、後始末(例外)の2つが必要な気がする。
積極的に使う場合>call/cc
506デフォルトの名無しさん:02/04/30 23:38
ネイティブコードにコンパイルするschemeない?
継続の辺りの仕組みが知りたいんだけど。
>>506
ネイティブじゃないけど、Scheme-to-C コンパイラなら。
使ったことないので、御満足頂けるかわかりませんが。

ttp://www.call-with-current-continuation.org/
508デフォルトの名無しさん:02/05/01 02:18
#((dv 0) (dv 1) (dv 2))
で,ベクターの要素には当然関数の計算結果であってほしいけど,
関数を計算しない状態が要素になってしまいます.
で,色々試行錯誤した結果,
(list->vector `(,(dv 0) ,(dv 1) ,(dv 2)))
などというスマートじゃない感じで落ち着いてしまいました.
普通に関数が展開されたベクターを書くにはどのようにすればいいですか?
`#(,(dv 0) ,(dv 1) ,(dv 2))
でいいはずだが。
510デフォルトの名無しさん:02/05/01 04:55
>>508
vectorは自己評価式(数値や文字列と同じ扱い)なので
外部表現#(〜)の読みこみ時に内部の要素が評価されることはありません。
>>509の様に定数式で無理やり評価するか、
新規に作ったり、
(vector (dv 0) (dv 1) (dv 2))
または、既存のvectorに対して代入します。
(define vec (make-vector 3))
(vector-set! vec 0 (dv 0))
(vector-set! vec 1 (dv 1))
(vector-set! vec 2 (dv 2))

ちなみに
list->vectorは
(define (list->vector vec) (apply vector vec))
こうやって定義できます。
511デフォルトの名無しさん:02/05/01 09:00
>>509-510
真夜中にありがとうございます.
vector-set! は,何となく気持ちが良くないので使用を控えたかったり.
使った方がなにかと楽だし,使わないとならない局面もありますけどね.
512デフォルトの名無しさん:02/05/01 15:35
>>506
Chez Schemeっていう、わりと気合いの入ったネイティブコードコンパイラもあるが、
有料なんだよな…(www.scheme.com。無料版はインタプリタ)

call/ccの実装方法を手軽に知りたかったらどうすればいいんだろうねえ。

もっとも素朴な方法としては、call/ccでsetjmpかつスタックをコピーしておいて、
その継続を適用するときにlongjmpかつスタックを復元すればいいんだけど。

あるいは、あらかじめプログラムの全体をcontinuation passing styleに変換すれば
ほとんど自明だが。
513デフォルトの名無しさん:02/05/01 18:13
>>511
vector-set!のどの辺が気持ち悪いんだよ
514デフォルトの名無しさん:02/05/01 19:50
>>506
>>512 みたいな実装するには、pthread 使えばいいと思うよ。
GCの時は、全てのスレッドを停止するか、あるいはマルチスレッド対応GC用意する必要があるけど。
515デフォルトの名無しさん:02/05/02 03:39
>>506
byte code 方式で継続サポートしてるschemeのソース見たことあるけど(Xscheme)…
いかにもbyte code VMじゃないと実装しにくそうな実装方式を使っていたなあ。
>>514
pthread使うと何がいいの?
スタックをコピーしやすいとか?
517デフォルトの名無しさん:02/05/02 09:01
>>516
結論急いではまってしまった…
>>512 スタックのコピーなら、とりあえずUNIXのfork()と共有メモリかもねー。

ところで、例の仕様書(R5...)は、
そういう仕様(スタック・コピーによる呼び出し元への戻りの保障)
を要求しているの?
518デフォルトの名無しさん:02/05/02 10:01
>>517
fork()したらset!の結果が共有できなくて困ると思うが…
だいいちコピーするのがスタックだけじゃすまない。
あ、ヒープはmmapしとくとか?

>ところで、例の仕様書(R5...)は、
>そういう仕様(スタック・コピーによる呼び出し元への戻りの保障)
>を要求しているの?

昔から、継続作ったらスタックはコピーせざるを得ない。
だって、何度でも呼び出せるんだから壊しちゃいけない。
継続作った時点でコピーするか、呼び出す時点でコピーするか。
519デフォルトの名無しさん:02/05/02 10:44
>>518
mini-schemeは継続をヒープに持ってるんだけど、この方法だと
コピーが一切必要ない。
ただし、実行と共にヒープにオブジェクトをバンバン作りつづける
仕様だからgcの呼び出し回数がやたらと多くなり、そのせいで遅くなる。
(参照切らない限りgcで回収されないという仕組みを利用してる。)
この方法でもある程度は*gcによらない回収*でgcの起動回数を減らす
ことができるけどね。
それでもスピードはちゃんとコピーして別管理する処理系には及ばない。
520デフォルトの名無しさん:02/05/02 10:53
Tiny-Schemeという処理系があるけど、コアはmini-schemeを
まるっきりそのまま使ってる。上と同様の理由で遅い。
安全にvectorオブジェクトのネスト構造が使えないのもマイナス。
(gcソース参照。ネスト深いと死ぬ可能性あり。)

組み込み用途としてはスタックレスschemeの方がいいんだけど。
>>519
うん。コピーしなくても要は上書きしなけりゃいいわけなんだが。
必ず新たに作るのは、まあコピーより遅いよね。

で、>>512はCにコンパイルするには...という話じゃないの?
522デフォルトの名無しさん:02/05/02 11:13
>>521
「Scheme compilerは」Cにcompileする処理系で、
Cのcontrol stackとSchemeのcontrol stackを共通にしているのってありますか?
Interpreterの実装が無理だと思うんだけど。

C--とcompilerのみの言語/処理系、という組合わせならありそうだけども。
Scheme→Cへのコンパイラを作って、
インタプリタをそのSchemeで書けば良いんじゃないの?
524デフォルトの名無しさん:02/05/02 12:45
bitって処理系動いた人いる?
結構シンプルそうなんで参考にしたいんだけど
http://www.iro.umontreal.ca/~dube/
525デフォルトの名無しさん:02/05/02 13:41
>>524
本体が1600行ってことはmini-schemeより小さいね。
526デフォルトの名無しさん:02/05/02 13:41
>>518 遅レスですが,,,
ヒープの内容は、共有メモリ上に置いとけばええんでないの?

いずれにせよ、ネイティブコードで継続実装する場合、
fork() か thread使わなきゃ、
言語システムと プロセス管理の混合物作んなきゃなんないから、面倒そうだね。
Windowsのスレッドに対応する場合って、
CriticalSectionの切り替えでできるかな?
オブジェクト生成や環境へのアクセス毎に呼ばなきゃいけないから
効率は悪そうだけど、UNIXのプロセスベースよりはまし?
528デフォルトの名無しさん:02/05/02 13:48
>>526
継続ってスレッドよりずっと軽くて原始的なものなので、
(少なくとも概念的には式ごとに別々の継続が出来る)
fork()とかpthreadとかの牛刀を持ち出すのはどうなんでしょう。
それに、fork()しちゃったらGCどうします?
>>527
VMで駆動するにしても1実行サイクル毎にCriticalSection呼ぶ
ってのでもいいかもね。ほとんどの場合I/O関係で時間食うわけだから、
I/O扱う処理直前でCriticalSectionをUnlockさせるとか。
>>527
"Critical Section" よくわかんないっすスマソ
UNIXのプロセスは、thread並に軽いと思うけど…

>>528 fork()したらGCどうする(略)
排他して親プロセスで共有メモリをGC または、GC専用プロセスでって、だめ?

スタックコピーが必要だっていうから、
ポータビリティ有る方法考えたつもりだったんだけど、
プロセスよりもスレッドよりも軽い継承っつうのが狙いなら、
自前でスタック管理した方がいいかもね。
>>528
mmapとかでやるんじゃないの?
大変そうだけど。
>>530
スタックのコピーが欲しいってだけなら
SCMとか参考にしてアセンブラでやったほうが良くない?
プロセスベース継続で擬似スレッド作りまくる様な
schemeのコード実行したらプロセスID枯渇するんでない?
だって継承ってスレッド実装するのによく使ってるよ
昔風にいえばコルーチンを1st classにしたやつだもの
pthreadだとsignalマスクとかthread localとか優先度とか
いろいろ持ってるっしょ。

継承使ってバックトラックやるようなプログラムだと、
継承を何万も作ったりするし。

GCについてだけど、ルートであるスタックが全部見えないと
ヒープだけ見えてもGCできない。
>>531
全プロセスのスタックを親がmmapするとか?
534533:02/05/02 14:22
あ、533は >>530ね。
535デフォルトの名無しさん:02/05/02 14:26
>>530
>"Critical Section" よくわかんないっすスマソ
Critical Sectionは関数呼び出し程度のコストでスレッド毎の
リソースロックができる機能だったはず。
状態が
o Lock
x unlock
だとして
thread1 ooooxxxxxxxxxxxoooxxo
thread2 xxxxooooxxxxoooxxxxxx
thread2 xxxxxxxxooooxxxxxxoox
oでリソース(環境)へのアクセスしてる最中は、他のスレッドはブロックされる。
このロック機構はプロセス固有なので、
コストはWindowsのロックの中では最小。(だったはず)
VM命令1回ごとに関数呼び出しほどもコストがかかったら
VMの実行がヒトケタ遅くなると思はれる。
537デフォルトの名無しさん:02/05/02 14:38
>>536
じゃあどうすればういいんだyo。
1命令毎に環境へアクセスする必要があるわけじゃないけど、
他のスレッドでgc発動されたら、いつのまにか現スレッドで
参照していたオブジェクトが無効になっていた、なんてのじゃ
使い物にならないよ。
538デフォルトの名無しさん:02/05/02 14:43
プリエンティブなスレッド使える他の処理系、例えばJavaなんかはどうしてるの?
gcはスレッドごとに別にやったりしないよ。
普通は全部のスレッドを止める。
他のスレッドとの競合は、Schemeプログラマが排他制御
するんでは?
540デフォルトの名無しさん:02/05/02 14:49
>>539
全部のthreadはどうやって止めるの?
gc発動thread以外のthreadにSuspendThread送るのかな?
いきなり止められたthreadがクリティカルな処理をしてた場合
はどうすんの?
例えばlistを生成中に他のthreadでgcによる停止が起きた場合、
作成中のlistはそのthread以外、どこにも参照されてないから
gc発動後無効objectとなったりしない?
541540:02/05/02 14:52
あ、生成中にはロック掛ける必要があるね。
プログラムカウンタ進めたり、計算した結果を数値objectとして
返したりする場合もロックは必要。
ロックしないで可能な事ってかなり限定的なものだと思うけど。
542540:02/05/02 14:55
結局、CriticalSectionで環境アクセス毎にロック掛けるのが
一番簡単なんでしょ?
全部のスレッドを止める必要はなく、各スレッドでロック機構を
使用してればどれかのスレッドでgc発動したら自然とブロック
されるわけだし。
>>540
例えばバイトコードをinterpretするVMの話で良いよね?
みんなが「せーの」でGCに入るのは、たしかにけっこう難しいんだよ。
だからSunのJVMはなかなかgreen threadからnative threadにできなかった。

例えば、100サイクルに1回グローバルなフラグを見て、立っていたら
スレッド内部の情報を全部GCから見えるところ(スタックとか)に書いて、
「OKだよ」とGCスレッドに言う。そして、GCが終了するまで待つ。
>>541-542
「環境アクセス」って、SchemeやLispだと「変数の読み書き」っていう意味だけど、
それでOK? ローカル変数を読むたびにいちいちロックするの?

オブジェクトの生成は、たとえばスレッドごとに1ぺーじずつ確保して
(ここはロック必要)ページを使い尽くすまではロックしないで良い。
545540:02/05/02 15:09
>>544
>ローカル変数を読むたびにいちいちロックするの?
正確に言うと、自分のいるローカルな環境フレームについてです。
駆動部でそれをちゃんとやってれば、schemeコードを作る側のプログラマが
リソースの排他制御を気にする必要は無いってことですよね?
管理外のリソースは別にして。

>オブジェクトの生成は、たとえばスレッドごとに1ぺーじずつ確保して
これができればいいんですが、処理系を始めから複数スレッド前提で作る
ような気合の入った実装をしないといけないですよね・・・・。
546540:02/05/02 15:14
>>543
その「待ち」と「移動」コストってどれぐらいなんですかね。
アクセス毎のロックを行うよりはマシなんでしょうか。
いっこずつ試してみたいものですが。
>>545
Schemeプログラムで、複数のスレッドで共有変数やデータを書き換える
なら、排他制御を意識せざるを得ないと思うが。
逆に言うと、Schemeプログラマが陽にロックを指示しない限りVMは
ロックする必要が無い。

>>546
「待ち」はOSが用意したスレッド間の同期プリミティブを使うんだろうね。
GCは短くても数msくらいはかかるだろうから、同期コストは問題にならない
のでは。

VMローカルのデータをGCから見えるところに書くのは、レジスタ変数を
スタックに退避する程度の手間でしょう。
548540:02/05/02 15:34
>>547
>データを書き換えるなら、排他制御を意識せざるを得ないと
ああ、おっしゃる通りでした。
駆動部による読み書きが安全であっても論理の上で正しいのか
とは別問題でしたね。となると上位側にもロックは必要ですか。
549540:02/05/02 15:36
どうやら協調型スレッドと混同してた様です。
550540:02/05/02 15:41
となると任意のタイミングで継続の切り替えが出来るschemeとしては、
プリエンティブにする旨みって、I/Oの部分ぐらいしかない気がする
んですけど・・・。
他に実装コストに見合ったメリットってあるでしょうか(おい
551デフォルトの名無しさん:02/05/02 15:57
I/Oだけプリエンティブにするトカ。
552デフォルトの名無しさん:02/05/02 18:48

括弧を見てるとめまいがする
>>552
そこが(・∀・)イイ!んだけど?
554デフォルトの名無しさん:02/05/02 20:34
schemeでまるちスレッドってどうやるの?
Cなんかで括弧 3つくらいのネスト見ても余裕で読めるようになるとか。
括弧は大気と同じようなものなので、濃すぎ (ネストし過ぎる) と酸素過多に
なってよろしくない。Lisp プログラムは字下げで読むべし。
557デフォルトの名無しさん:02/05/03 00:31
>>523
> Scheme→Cへのコンパイラを作って、
> インタプリタをそのSchemeで書けば良いんじゃないの?

そのインタプリタが動く時のcontrol stackじゃなくて、
インタプリタが実行するプログラムの方のcontrol stackです。

対象がインタプリタだろうが何だろうが、コンパイルすれば、
control stackを共通化するのは比較的簡単です。
558デフォルトの名無しさん:02/05/03 00:58
おれの自作schemeインタプリタ、
カウントアップしながら出力するコードでベンチ取ったら、
VisualC++6SP4:10秒
おれscheme:13秒
でした。
結構いい線いってる?
(ほとんどコンソールの出力に時間取られてるんだろうけど)
559デフォルトの名無しさん:02/05/03 01:06
やっぱSchemerは自作Schemeを持つべきですかね?
560デフォルトの名無しさん:02/05/03 01:07
10万回のループで、
おれschemeでは5000回に一回ほどgcが起動する割合。
Cのソース
#include <stdio.h>
#include <time.h>

main() {
 int i;
 time_t start = clock();
 for (i = 0; i < 100000; i++)
  printf("%d\n",i);
 printf("interval %d\n",clock() - start);
}
Cのコンパイルオプション
cl /O2 /GB /Og /GA /Ob2 /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD test1.c

schemeのソース
(define (call-with-time expr)
 (let ((starttime (clock)))
  (unwind-protect
   (lambda () (expr))
   (lambda () (display* "interval " (- (clock) starttime) (newline)))
  )))
(define-macro (wt . body)
 `(call-with-time (lambda () ,@body))
(define-macro (donum var s e inc . body)
 (let ((loop (gensym))(comp (gensym)))
  `(let ((,comp (if (<= ,s ,e) < >)))
   (let ,loop ((,var ,s))
    (if (,comp ,var ,e)
     (begin ,(cons 'begin body)
      (,loop (+ ,var ,inc)))
      ,var)))))
(wt(donum i 0 100000 1 (display i)(newline)))
>>559
自作しろとは言わないけど、隅々まで知ってる処理系
持ってるにこしたことない、とは思う。
562デフォルトの名無しさん:02/05/03 02:06
>>552
静かな湖畔の♪
563デフォルトの名無しさん:02/05/03 04:05
>>557

>>>523
>> Scheme→Cへのコンパイラを作って、
>> インタプリタをそのSchemeで書けば良いんじゃないの?
>
>そのインタプリタが動く時のcontrol stackじゃなくて、
>インタプリタが実行するプログラムの方のcontrol stackです。
>
>対象がインタプリタだろうが何だろうが、コンパイルすれば、
>control stackを共通化するのは比較的簡単です。

? 意味が分からない。
共通化できたんなら良いのでは。

誤解してると逝けないので言い直すと、
「まずコンパイラを作る。
インタプリタはそのコンパイラを使って『すなおーに』実装する。
(define (eval exp env) ...)と言うように。
(インタプリタからコンパイルされたprocedureを呼び出す
プリミティブだけはCで用意しておく。)
その結果、インタプリタとコンパイラで実行環境が全く共通の
処理系ができる。」

つまり、インタプリタは自分でスタックを管理したりせずに、
Schemeの関数呼び出しや継続の機能をそのまま使えばよい。
564デフォルトの名無しさん:02/05/03 11:03
>>558
入出力とかじゃなくて、アッカーマン関数とかで試そう!
http://www.bagley.org/~doug/shootout/からパクリ

(define (ack m n)
(cond ((zero? m) (+ n 1))
((zero? n) (ack (- m 1) 1))
(else (ack (- m 1) (ack m (- n 1))))))

話がそれるけど、http://www.bagley.org/~doug/shootout/は
いろんな言語のマイクロベンチマークがあっておもしろいよ。
565558:02/05/03 20:48
>>564
その辺の色々ためしたら全体的に2倍以上遅いことがわかった。
短い夢だったよ。
でもインタプリタとしてはコレ以上速くなるとは正直思えない。
数値演算や配列アクセスも含めて、C++と
2倍くらいしか違わないインタプリタが作
れたなら何かとんでもない大発明をやらか
したものと思われる。

ぜひ公開して世界を驚かせてくれたまえ。
567558:02/05/03 21:21
へえ、おれはそんな大発明をしたのか?
結構ちょろいね。大発明なんて。
セルの再利用とかキャッシュ組みこんでるだけなんだが。
まあそれなりに苦労はしたけど。
あ、公開は勘弁してくれ((((;´Д` )))))ガクガクブルブル
>>567
どうみてもただの勘違い。
C/C++で書いたインタプリタでC++ネイティブの1/2の性能が
でるわけがない。

足し算1回するのに必要な機械語命令数を考えればわかる。
>>568
まあ、そんな物凄い勢いで否定せんでもいいだろ。
2倍*以上*とかかいてるし。
たぶん特定条件でせまるって事はありえると思うよ。
LinpackでC++の半分出ればマジで大発明だと思うよ。
(行列演算プリミティブを用意するというのはナシで。)
Limpackは面倒だろうから配列の乗算でも試してみたら?

(define (make-matrix n v)
 (make-vector (* n n) v))

(define (mref matrix size x y)
 (vector-ref matrix (+ (* size x) y)))

(define (mset! matrix size x y v)
 (vector-set! matrix (+ (* size x) y) v))

(define (matrix-* m1 m2 size)
 (let ((result (make-matrix size 0.0)))
  (do ((i 0 (+ i 1)))
    ((>= i size) result)
   (do ((j 0 (+ j 1)))
     ((>= j size))
    (do ((k 0 (+ k 1))
       (sum 0.0 (+ sum (* (mref m1 size i k)
                (mref m2 size k j)))))
      ((>= k size)
       (mset! result size i j sum)))))))

(define (mat-bench size)
 (matrix-* (make-matrix size 1.0)
      (make-matrix size 1.0)
      size)
 #t)

(mat-bench 500)

mrefやmset!はマクロでも良いよ。
これがCやC++の倍の時間でできる?
手元の処理系だと100倍くらいかかったけど。
CやC++のインタプリタを相手にするなら希望はあるかもしれん。
KI-Scheme なんだけど
ApplyFunc の中でクロージャの場合、
SaveEval(EndClosure, evEnv, NIL) でスタックつんでいるから、
真の末尾再帰ではない、というのは正しいでしょうか?
574デフォルトの名無しさん:02/05/05 02:39
末尾からの無限呼び出しでオーバーフローするか試したらどうだ?
575デフォルトの名無しさん:02/05/05 02:44
C言語の
enum {A,B,C,D};
switch (type) {
case A:return B;
case B:return C;
case C:return D;
case D:return A;
}
みたいな比較を
schemeで簡潔にやるとしたらどうなるんですか?
(define A 0)
(define B 1)
(define C 2)
(define D 3)
(case type
((A)B)
((B)C)
((C)D)
((D)A))
とやると、シンボルの比較になってしまう様ですが。
(cond
((= type A)B)
((= type B)C)
((= type C)D)
((= type D)A))
とするしかないでしょうか。
Cだと名前を使いたくても数値になっちゃうわけだが、
Lispだとシンボルのまま使えて便利じゃん!
>>575
連想リストつかったら?
わざわざ数値という表現に落す必要があるのかと小一時間…
579573:02/05/05 07:49
DOS版のバイナリダウンロードして試してみたら、
Error: foo : insufficient memory
となったよ。
やっぱり、minischeme のようにスタック積む時は、
つねに環境も一緒につんだ方がいいのかね。
そんで、スタック戻すときに環境も戻す。
580デフォルトの名無しさん:02/05/05 10:31
>>563
> つまり、インタプリタは自分でスタックを管理したりせずに、
> Schemeの関数呼び出しや継続の機能をそのまま使えばよい。

インタプリタの実行するプログラムは動的に変わるから無理。

> (define (eval exp env) ...)と言うように。
> (インタプリタからコンパイルされたprocedureを呼び出す
> プリミティブだけはCで用意しておく。)
> その結果、インタプリタとコンパイラで実行環境が全く共通の
> 処理系ができる。」

「実行環境」って何の事言ってるの?
envはどうやって実装するの?
>インタプリタの実行するプログラムは動的に変わるから無理。
ハァ?

>「実行環境」って何の事言ってるの?
制御スタック。それを共通化したかったんじゃないの?

>envはどうやって実装するの?

alistでいいんじゃない?
凝った事したければcasual shallow bindingとか使っても
良いけどさ。
もっと具体的に言ってみる。

・applyは組み込み関数として用意しとく。
・evalはSchemeで書く。
 例えばifの処理は
 (eval (if 式1 式2) env)
  ≡ (if (eval 式1 env) (eval 式2 env))
 (eval (if 式1 式2 式3) env)
  ≡ (if (eval 式1 env) (eval 式2 env) (eval 式3 env))
 となるようにすれば良い。

 λ式を評価するときは、
 (eval λ式 env)
  ≡ (lambda args
 (eval λ式の本体
  (extend-env λ式の引数部 args env)))
 とする。
 (≡の右辺はコンパイルされてprocedureになることに注意。)

 (eval (関数 . 実引数) env)
  ≡ (apply (eval 関数 env) (eval-list 実引数 env))
 としてしまえば良い。
・あとはread-eval-printループを書く。

これだけでtail-recursiveなインタプリタができるし
call/ccの処理もできるだろ?インタプリタ用の実行時
スタックなんて陽に用いる必要はない。
(こんなの、よくある手法だと思うが。)
583デフォルトの名無しさん:02/05/05 12:13
>>582
> インタプリタ用の実行時
> スタックなんて陽に用いる必要はない。
> (こんなの、よくある手法だと思うが。)

必要があるかどうかじゃなくて、
もともと継続をforkやthreadでという話からの流れで、
そんなことやっている実装はないんじゃないの、と言う話をしているんです。

あなたの例では、インタープリットされるプログラムのコントロールスタックは、
インタープリター自身の局所変数ですね。Lisp 1.5と同じ。

> 制御スタック。それを共通化したかったんじゃないの?

全然一緒になってないよ。
継続を実装する時に、「制御」について別の扱いしないといけないでしょ。


>>583

>あなたの例では、インタープリットされるプログラムのコントロールスタックは、
>インタープリター自身の局所変数ですね。Lisp 1.5と同じ。

コントロールスタックという言葉の意味が分かっているか?
上のインタプリタのコードで、環境はenvというインタプリタの
変数として陽に表されているが、コントロールスタックはコードの
どこにも出てきていない。(コンパイラの実現する機能をそのまま
使っている。)

>全然一緒になってないよ。
>継続を実装する時に、「制御」について別の扱いしないといけないでしょ。

やっぱり全然分かってなかったか。
call/ccという組み込み関数は当然すでに用意してあるわけだろ?
で、それを組み込み関数applyで呼び出すだけでcall/ccはすでに
インタプリタで実現できている。別の扱いなんか必要ない。

理解できなかったらやってみ。
585デフォルトの名無しさん:02/05/05 12:23
Lisp/Schemeで普通に使うリスト処理が重たいから、
ふつ〜、リスト処理を内部的にスタックや配列に置き換える
>>585
インタプリタの話か?
まさかconsが配列処理するってんじゃないだろうな。

コンパイラがある処理系でインタプリタの速度気にしてどうする?
587デフォルトの名無しさん:02/05/05 12:31
昔Cのコードを吐き出すCommonLispコンパイラーの生成コードを見たけど、
インタープリタのプリミティブ呼び出しばっかりでちっとも速そうじゃなかったっけ。

CommonLispでも、型宣言もどき入れれば、Cと等価な使い方ができるコード吐きそうなもんだけど、(経験なし)
588デフォルトの名無しさん:02/05/05 12:32
>>586 consが配列処理になる、はLispMachineの昔から常套手段。
 Schemeチップではどーなんでしょうね?
>>588
cdr-codingの事を言ってるならあれはメモリ節約のためで
速度は速くならない(まあGCが減れば速くなるが)。

特にrplacdした時が悲惨。

いずれにせよ巨大マイクロコードの終焉とともに消えた
技術。
>>587
うまく型宣言するとCで書いたのと同じコードが出る場合もある。
KCLレポートにtakの例が載っていたはず。
591デフォルトの名無しさん:02/05/05 12:49
>cdr-codingの事を言ってるならあれはメモリ節約のためで
>速度は速くならない
LispMachine のマイクロ・コードだとそなの?

でも、どこにあるかわからないポインタ辿るのと、
配列の次の要素へアクセスするのと、
ではキャッシュのヒット率が違うと思うけど。
592デフォルトの名無しさん:02/05/05 12:53
>>589 特にrplacdした時が悲惨。
どんなお話でしたっけ?
>>591
コピーGCでも似た効果(リストのセルが連続した番地に並ぶ)
は得られる。
594デフォルトの名無しさん:02/05/05 12:59
コンパイラ・コードで、内部完結する処理だったら、
リストを使わない等価な処理でごまかしてもいいんではないか?と煽ってみる。
>>592

(setq x '(a b c))
(setq y (cdr b))

として、a b cへのポインタが連続して並んだとする。

x→a
y→b
  c

(rplacd x 1)
したときに、(b c)を上書きして壊すわけにはいかないので
forwarding pointerという「見えないポインタ(勝手にたどる
ポインタ)」をaの場所にいれ、他にセルを割り当てて、

x→→(a . 1)
y→b
  c

としなければならない。nreverseとかやっちゃうと大惨事。
スレ違いっぽいけど、AppleScriptは速度を上げるために
リスト処理を内部的には可変長配列で実装し直したという
歴史があったような。
>>596
主に線形のリストしか使わず、書き換えもあまりしないなら
良いかも。挿入は遅くなると思うが。
>>588
Schemeチップはcdr-codingしてないよ。
GCでコンパクションGCはしてたけど。

「次期バージョンではphantom stackを使う」
とストールマンが書いていたが、本当にそういうチップが
作られたかは不明。
599デフォルトの名無しさん:02/05/05 13:42
んで、けきょーく、Schemeコンパイラーにおける継続の効果的実装方法は
どないでしょうか?特にネイティブ・コード重視の場合。



>>全然一緒になってないよ。
>>継続を実装する時に、「制御」について別の扱いしないといけないでしょ。
>
>やっぱり全然分かってなかったか。
>call/ccという組み込み関数は当然すでに用意してあるわけだろ?
>で、それを組み込み関数applyで呼び出すだけでcall/ccはすでに
>インタプリタで実現できている。別の扱いなんか必要ない。

popしないスタックを使うとか‥‥‥。
環境や継続を生成しない場合だけスタックフレームを解放して、
それ以外はスタックがどんどん伸びていく?
601デフォルトの名無しさん:02/05/05 14:15
 http://www.ccs.neu.edu/home/matthias/Scheme2000/
にある
 A portable implementation of first-class continuations for unrestricted interoperability with C in a multithreaded Scheme -- page 65
 Marc Feeley, DIRO, Universitat de Montreal, Montreal, Canada
はどうか。上のほうでも誰か言ってたけど、pthreadとか普通のスレッドを利用して
call/ccを実装するっていう。
602デフォルトの名無しさん:02/05/05 14:34
fork()がプロセスのコピーをするように、
走ってるthreadのコピーを作る事って、可能でしょうかね。

もし可能なら、手抜きポータブル継続実装に使えそうですね^^)
603601:02/05/05 14:45
この論文の方法だと、(俺が誤解してなければ)「走ってるスレッドのコピーを作る」
必要はないと思ったのだが、理解に自信がなくなってきたので出直してきますsage
世界にはこんなに熱いワークショップがあったのか
605602:02/05/05 15:23
>>603 論文斜め読みしました。
   こんな感じでしょうか?
・継続を含むSchemeとCの相互運用を実現するために、[KBD98]が提案した
 「C threadを使ってポータブルにCのスタック・コピーと実行をする」方法を
 Gambit-C という実装系で採用しようと検討している。
 並列動作が主目的ではないため、thread切替のオーバー・ヘッド (2ms)が、
 すんげー気に入らない。
 
・C thread (win32, POSIX, SUN LWP)は、
 スレッド生成時に、任意のスタックを与える事ができる。
 (従って、継続したいスレッドのスタックをコピーして、
  新規スレッドに渡せば、継続の繰り返し実行も可能な感じ。
  但し、論文ではCの関数は one shot だと言って、
  副作用があるから面倒そうな事を言っている。)
606602:02/05/05 15:45
あと、言い忘れましたが、>>603 論文ありがとうございますた。

けきょーく、Scheme コンパイラで継続実装するには、
a. Schemeのローカル変数フレームを、最初からヒープ上に置くか、
b. 実装言語 (Cとか...)のスタック上に混在させておいて、
  継続の必要が生じてから、ヒープ上へ移す
ってあたりが、正解っぽいですね。
もっと良い実装もあるかもしれないけど...。
607デフォルトの名無しさん:02/05/05 17:31
>>606
c. 継続が作られた段階で使われているスタックエリアを切り離し、
継続が呼ばれたらそれをアクティブスタックエリアにコピーする、
というのもあり。ChezSchemeがそうしてるんじゃないかと。

Robert Hieb, Kent Dybvig, Carl Bruggeman, "Representing Control
in the Presence of First-Class Continuations", ACM Sigplan Notices,
25(6), June 1990. とかでそれぞれの方法が議論されてる。
>>584
> コントロールスタックという言葉の意味が分かっているか?
> 上のインタプリタのコードで、環境はenvというインタプリタの
> 変数として陽に表されているが、コントロールスタックはコードの
> どこにも出てきていない。(コンパイラの実現する機能をそのまま
> 使っている。)

あの〜、再帰で通訳した場合、
「式」を押さえているpointerがcontrol stackになってるんですよ?
Lisp1.5やSECD machineやInterLispの実装考えれば分かるでしょ?
"ret"でprogram counterにstackから番地戻すんじゃなくて、
再帰から帰ったら、局所変数が押さえてるの。

> call/ccという組み込み関数は当然すでに用意してあるわけだろ?
> で、それを組み込み関数applyで呼び出すだけでcall/ccはすでに
> インタプリタで実現できている。別の扱いなんか必要ない。

ネイティブ・コンパイラの実装の話しているのは理解できているの?
スレの上の方から読み直してみ。(ふぅ)

>>606
そういうことだと思うよ。コンパイラについては。

>>601
pthreadの生成死滅のコストが高いから、
継続の生成死滅が激しいとパフォーマンス悪そうだけど、面白そうね、これ。
609606:02/05/06 00:00
>>607
そっすね。
継続作成時にスタックのスナップショットを、ヒープに退避して、
実行用ローカル変数フレームは、常にスタック上に置いた方が、
シンプルそうっすね。

>>608
threadの並列実行機能抜きで、
stack dump/stack undump専用のシステムコールとか、
ポータブルなライブラリがあれば便利っすね。


>あの〜、再帰で通訳した場合、
>「式」を押さえているpointerがcontrol stackになってるんですよ?
>Lisp1.5やSECD machineやInterLispの実装考えれば分かるでしょ?

InterLispは知らんが、他はどれも違う。
なんで式が「control」でLisp1.5の万能関数の
どこに「stack」があるんだよ。

ひょっとしてSECDマシンのSとかCが関係あると思ってる?
C言語の制御スタックに相当するのは当然Dでしょ。

で、俺のやり方で何がまずいかを言ってみろよ。

>"ret"でprogram counterにstackから番地戻すんじゃなくて、
>再帰から帰ったら、局所変数が押さえてるの。

「control」の意味が分かってないと思われ。
再帰から「返る」機能自体を実現するのがcontrol stackだよ。
で、Cでの実装では、そこにコンパイルコードの環境を一緒に
置くかも知れない。そうでないかも知れない。インタプリタを
Schemeで書けばそれはどちらでも気にしなくて良い。

>ネイティブ・コンパイラの実装の話しているのは理解できているの?
>スレの上の方から読み直してみ。(ふぅ)

あんたはそのつもりかも知れんがこの流れのもとは、
522 :デフォルトの名無しさん:02/05/02 11:13
>>521
「Scheme compilerは」Cにcompileする処理系で、
Cのcontrol stackとSchemeのcontrol stackを共通にしているのってありますか?
Interpreterの実装が無理だと思うんだけど。

C--とcompilerのみの言語/処理系、という組合わせならありそうだけども。
だろ。つまり「SchemeからCへのコンパイラがとにかく既に存在する」
場合に、コンパイラ以前か以後かはともかく「どうやってインタプ
リタを実装するか」という疑問に答えただけだ。
SchemeからCへ落すコンパイラで一番普通なのは
Cのスタックは使わずにトランポリンを使う方法
だろう。

他に「決してreturnせず、ときどき大きくlongjmp
する」という方法もあるけど。
http://linux.rice.edu/~rahul/hbaker/CheneyMTA.html
612デフォルトの名無しさん:02/05/07 19:23
>>610
まあまあ。

Common Lispだと確かにコンパイラを先に作って、インタプリタを
Lisp-in-Lispとして作ってある処理系が多いよね。Spice LispもZeta Lispも、
S-1 Common Lispもそうだ。CMU Common Lispもそうだったはず。

これらの処理系だと、インタプリタが独自に実行時スタックを持ったりはして
いない。Lisp 1.5はコンパイラの方が後だが、スタックはどうしたんだろうね。
たぶんインタプリタにあわせたコードをコンパイラが出したんじゃないか?
call-with-continuationなんて無いから別に難しくないだろう。
>>612
Schemeでは知らないな〜、知ってる?
614デフォルトの名無しさん:02/05/07 21:08
うーん、MIT Schemeは、
InterLisp風のstacklet list使ってややこしいことやっていたような…
615デフォルトの名無しさん:02/05/08 00:10
以前からこの処理系気になってるんだけど、誰か動いた人いませんか?
68HC11がなんとかって書いてあるから、そのままx86じゃ無理でしょうか。
(無理やりコンパイルしたら駄目だった)
Bit - Implantation compacte de Scheme
http://www.iro.umontreal.ca/~dube/
616デフォルトの名無しさん:02/05/08 12:37
schemeで文字列処理って
無謀?
617デフォルトの名無しさん:02/05/08 15:06
>>616 一通りはできる。正規表現のライブラリもあるし。流用しやすい
アリモノは、PerlやAwk よりは少なさそうだけど。

>>615 おーっ、面白そうな処理系。クロス・コンパイルして組込みでも
使えるよ、ってのがウリなのか。x86 の 赤帽 7.2 で動いたよ。

適当なコードを作っといて、他の scheme でバイト・コンパイル。

scm> (load "./bit.scm")
scm> (byte-compile "foo.scm" "foo.c")

で、C でコンパイルして、a.out を実行。

gcc foo.c bit.c
./a.out

と、README 通りでいけたけど。
>>617
結果うまく表示できる?
write-charしか出力関数が無いみたいだけど
それもなんだかうまく動かなかった。
(何を出力してもヌル文字しか出て来ない。)
619615:02/05/08 20:28
>>617
ありがとうございます。byte-compileうまくいきました。
まだ動かしてはないけど。
(他の処理系から読みこませる発想だとは思わなかった。)
bit.scm自身をコンパイルして動かせるのかな?
byte-compileは通ってしまったけど。
620615:02/05/08 20:31
>>618
displayとかの他の出力系はlibrairie.scmに入ってますよ。
bit.scmの中にlibrairie.scmをロードする部分があるんで、
それをパス合わせすれば大丈夫かと。
621デフォルトの名無しさん:02/05/08 20:59
>>620 librairie.scm の write がバグってる。string? のところの名前つき let の中の cond の else のところがループになっていないので、 最初の1文字しか出てこない。
622615:02/05/09 02:42
結構問題ありみたいですね。
こっちもbccでコンパイルは通るけど一般保護で落ちるし。
common lisp の例の本は出ましたか?
624デフォルトの名無しさん:02/05/09 21:56
SICPのFull Textを、zipかなんかでまとめてあって
それをダウソできるとこってどっかにないの?
>>624
wget できないかな?
psならあった(sicp.ps.gzというファイル名だったような)。
htmlもあった。でもそのうち消えた。
627デフォルトの名無しさん:02/05/10 01:46
ページごと持ってくれば?
ふつーのダウソツールでおっけーなんじゃ
628デフォルトの名無しさん:02/05/10 12:00
h t t p : / / w w w .geocities.co.jp/SiliconValley-PaloAlto/7043/
にwgetのスクリプトがあって無事ダウソできました。

>>626
本家にpsでありましたよね。むかし・・・。
629デフォルトの名無しさん:02/05/12 00:32
形態素解析プログラム
ttp://www.unixuser.org/~euske/doc/niwatori/index.html
つーのがあった。scheme。
こういう解析処理ってググってもあんま見つからないな。
630高校生の女の子の感覚で、埴輪鶏ってどうよ?:02/05/12 07:51
どーでしょ?>>形態素解析

Lisp Schemeからは外れるけど、
オープン・ソースの検索エンジン「Namazu」って結構普及しているよね。
# MS Index Server / Contents Index って結構アレだし。

んで、その検索エンジンは、膠着語である日本語の文節を分割する目的で、
形態素解析エンジン(NAMAZUの場合JUMAN,茶筅)を使ってるよ。
最近あんまり話題にもならない日本語かな漢字変換プログラム でも、
かな文の文節を区切る目的で、形態素解析エンジン使ってるよね

ICOTオープン・ソース・アーカイブへ逝くと、
自然言語処理用の CESPソースがあるけど、
Lispソースはなかったかな?

632デフォルトの名無しさん:02/05/12 15:53
S式をHTMLに変換するやつ作ってみたんだけど
どうでしょう。
(define (sexpr->html s)
 (define (put-tag-with-attr tag)
  (if (pair? tag)
   (let loop
    ((x tag))
    (cond
     ((pair? x)
      (display (car x))
      (if (pair? (cdr x)) (write-char #\space))
      (loop (cdr x)))
     (else)))
   (display tag)))
 (define (put-tag-omit-attr tag)
  (if (pair? tag)
   (display (car tag))
   (display tag)))
 ;ここから
 (if (pair? s)
  (let ((tag (car s)))
   (write-char #\<)
   (put-tag-with-attr tag)
   (write-char #\>)
   (newline)
   (if (nlength? 1 (cdr s))
    (begin
     (for-each sexpr->html (cdr s))
     (write-char #\<)
     (write-char #\/)
     (put-tag-omit-attr tag)
     (write-char #\>)
     (newline))))
  (display s)))
633デフォルトの名無しさん:02/05/12 15:54
;食わせるS式
(define source
((html "lang=\"ja\"")
 (head
  ((META
    "http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\""))
  ((link "rev=\"made\" href=\"mailto:[email protected]\""))
  (title "更新履歴"))
 (body
  (h1 "更新履歴")
  (hr)
  (p "2002/05/11 Version 1.00")
  (ul (li "新規作成") (li "公開")))))

;変換結果
(sexpr->html source)
<html lang="ja">
<head>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<link rev="made" href="mailto:[email protected]">
<title>
更新履歴</title>
</head>
<body>
<h1>
更新履歴</h1>
<hr>
<p>
2002/05/11 Version 1.00</p>
<ul>
<li>
新規作成</li>
<li>
公開</li>
</ul>
</body>
</html>
634デフォルトの名無しさん:02/05/12 15:58
・仕様
タグの中に属性がある場合は、タグ名の部分をリストにして、
そのリストにタグ名と属性を入れる。
<html lang="ja">ほげほげ</html>
の場合、((html "lang=\"ja\"") ほげほげ)
635デフォルトの名無しさん:02/05/12 15:59
出力される結果はwith-output-to-fileなどで取りこんでください。
636デフォルトの名無しさん:02/05/12 16:01
書き忘れた雑関数
;リストlが長さn以上ならば#t
(define (nlength? n l)
 (pair? (list-tail l (- n 1))))
637デフォルトの名無しさん:02/05/12 19:22
>>632
これとか参考にしたら
http://okmij.org/ftp/Scheme/SXML.html
638デフォルトの名無しさん:02/05/12 20:44
>>634 キーワード付き引数の方が、より直感的でない?
639632:02/05/12 22:44
html->sexprを作らないと実用にはならないっぽいですね。
こっちは非常に面倒そうですが。(トークンの切り分けや省略タグの扱いとか)

>>637
うーん、ソース見たら結構大きいんですけど、
もうちょっとコンパクトなやつないですか?

>>638
キーワード付き引数とは?
(html (@ (lang "ja"))ほげほげ) ;@が属性
みたいな感じでしょうか。
640デフォルトの名無しさん:02/05/12 23:32
>>632
結構短くまとまってるね
641デフォルトの名無しさん:02/05/12 23:47
>html->sexprを作らないと実用にはならないっぽいですね。
既存のHTMLソース読みこませないと問題点がはっきりしないと思う。
642デフォルトの名無しさん:02/05/13 01:09
>>641
HTMLの場合、省略可能タグのせいで、ただのタグの切り分け
だけではどうしようもない問題がある。
単に、
<body>
<h1>
更新履歴</h1>
<hr>
<p>
2002/05/11 Version 1.00</p>
</body>
というデータを何も考えずにパースすると、
(body (h1 "更新履歴") (hr (p "2002/05/11 Version 1.00")))
となり、間違った構造になる。
hrやbrなどは例外的に処理しないと駄目っぽい。
643デフォルトの名無しさん:02/05/13 02:57
>>642
そうだね。
あとは<B></B>なんかの範囲タグは中身が無くても省略できなかったりするから、
その辺を別途切り分けできれば結構使える様になると思う。
もっと単純にしようよ。

HTML文書 ::= (ノード...)
ノード ::= (タグ 属性リスト ノード...) | 文字列
タグ ::= シンボル
属性リスト ::= ((属性名 . 属性値) ...)
属性名 ::= シンボル
属性値 ::= 文字列

(define source
 '(html ((lang . "ja"))
   (head ()
    (meta ((http-equiv . "Content-Type")
       (content . "text/html; charset=Shift_JIS""))
     (link ((rev . "made") (href . "mailto:[email protected]")))
     (title () "更新履歴")))
    (body ()
     (h1 () "更新履歴")
     (hr ())
     (p () "2002/05/11 Version 1.00")
     (ul () (li "新規作成") (li "公開")))))

(define (sexpr->html node)
 (if (string? node)
   (display node)
   (let ((tag-name (symbol->string (car node))))
    (newline)
    (display (string-append "<" (car node)))
    (for-each (lambda (pair)
          (display " ")
          (display (car pair))
          (display "=")
          (write (cdr pair)))
         (cadr node))
    (display ">")
    (for-each sexpr->html (cddr node))
    (newline)
    (display (string-append "</" (car node) ">")))))
646デフォルトの名無しさん:02/05/13 05:13
>>645
短くなったね。
属性は
(meta ("http-equiv=\"Content-Type\"" "content=\"text/html; charset=Shift_JIS\""))
程度でもいいとおもうけど。なんか真面目に切り分けしても無駄っぽいし。
あとは属性無し、中身無しのタグは(hr)(br)の様にするとか。
これがXMLだとcase-sensitiveな問題とか出てくるんだろうな。
html->sexprが待たれるところだけど、こっちはほんとに面倒そう。
647632:02/05/13 05:51
html->sexpr
まだ中途半端ですが、一応それなりの動作をするものができました。

(html->sexpr "HTMLファイル名")
とするとS式が出てくる筈です。
ただし、タグと属性は1つの文字列になります。
2ちゃんのログを読みこませても大丈夫な様です。

各自でpretty-printしてください。
長いのでこうしました。

(define (substring? key d . opt) (let ((pos (if (pair? opt) (car opt) 0))
(dlen (if (and (pair? opt) (pair? (cdr opt))) (cadr opt) (string-length d))))
(and (<= (string-length key) dlen) (let loop ((i pos) (match 0)) (cond ((=
match (string-length key)) (- i match)) ((< i dlen) (if (char=? (string-ref
key match) (string-ref d i)) (loop (+ i 1) (+ match 1)) (loop (+ (- i match)
1) 0))) (else #f))))))

(define (first-token s) (if (string? s) (let ((pos (substring? " " s))) (if
pos (substring s 0 pos) s)) s))
648632:02/05/13 05:51
(define (html->sexpr fn) (define (read-token endc) (let loop ((c (read-char))
(r '())) (if (or (eof-object? c) (char=? c endc)) (list->string (reverse r))
(loop (read-char) (cons c r))))) (with-input-from-file fn (lambda () (let loop
((c(read-char)) (stack '())) (cond ((eof-object? c) (if (pair? stack) (car
stack) stack)) ((char=? c #\<) (let ((tag (read-token #\>))) (if (char=? #\/
(string-ref tag 0)) (let* ((x (substring tag 1)) (v (find (lambda (s) (if
(string-ci=? (first-token x) (first-token (car s))) (car s) #f)) stack)))
(if v (let loop1 ((stack stack) (r '())) (if (not (eq? v (caar stack)))
(loop1 (cdr stack) (cons (cons (caar stack) (cdar stack)) r)) (begin
(set-cdr! (car stack) (append (cdar stack) r)) (if (pair?
(cdr stack)) (begin (set-cdr! (cadr stack) (append (cdadr stack) (list (car
stack)))) (loop (read-char) (cdr stack))) (loop (read-char) stack))))) (begin
(stdout-puts "警告:" tag "は対応関係が異常です") (loop (read-char) stack))))
(begin (if (memv (first-token tag) *omit-tag-list*) (begin (set-cdr! (car stack)
(append (cdar stack) (list (list tag)))) (loop (read-char) stack)) (loop
(read-char) (cons (list tag) stack))))))) (else (let ((s (string-append (string
c) (read-token #\<)))) (if (pair? stack) (set-cdr! (car stack) (append (cdar
stack) (list s))) (stdout-puts "警告:" s "はばどのタグにも所属してません"))
(let ((xc (peek-char))) (if (eof-object? xc) (loop xc stack) (loop #\< stack
))))))))))

stdout-putsは強制的に標準出力などに吐くputsです。
(with-input-to-fileを使用してるので)
putsは最後に改行するdisplay*です。
display*は引数リスト全てにdisplayを適用する関数です。
649632:02/05/13 05:53
これで最後
(define *omit-tag-list*
'("br" "BR" "hr" "HR" "meta" "META" "input" "INPUT"))
>>649
本来なら「今はliの中だから、来て良いタグはこれとこれ」という
文脈情報を使って、<p>や閉じてない<li>を処理するんだろうね。
この辺をデータ駆動にしてきちんとやるとSGMLパーザになっちゃう。

難しさは、
SGML parser >> validating XML parser >> non-validating XML parser
だから、右から作っていかない? XHTML目標で。
651632:02/05/13 20:45
>>648で変換したS式からAタグのHREFを抜き出す関数。
(define (get-href s)
 (define (proc x)
  (if (string-ci=? (first-token x) "A")
   (let ((pos (substring-ci? "href" x)))
    (if pos
     (puts (substring x pos))))))
 (define (seq x)
  (if (pair? x)
    (cond
     ((pair? (car x))
      (begin (seq (car x)) (for-each seq (cdr x))))
     ((string? (car x)) (proc (car x)) (for-each seq (cdr x)))
     (else (for-each seq (cdr x)) ))
    #t))
 (seq s))
652632:02/05/13 20:55
>>642
その辺は一応考えてみました。(*omit-tag-list*参照)
ただ、こちらの思いこみで処理を書いてる可能性が多々有るので、
あれで全てうまくいくかどうかは判りません。
それと、HTMLのコメントを考慮して無かったので、<!-->〜などはネスト
してしまいます。ブラウザはそんな出力も一応読みこんでくれてますが。

>>644
そういう風に単純化できるとは思いつきませんでした。
現在、タグと属性の分割方法を検討してます。
(できればhtml->sexprも短くして欲しい・・・)

>>650
あんまり厳密にやろうとすると工数ばっかり掛かる(割にあまり面白くなさそうな)
んで、とりあえず今回はこれにちゃんとしたタグと属性を付ける所までを目指します。
ところで、
>SGML parser >> validating XML parser >> non-validating XML parser
HTMLはどこに当てはまるんでしょうか?


思ったより素のschemeで文字列処理をするのはしんどいです。
特に、文字をlistで溜め込んだり、substringで新しい文字列を作って抜き出す
事に抵抗を感じたりします。(直接オフセットが使えないもどかしさ、等)
Guileは共有文字列とかいうのでこの辺のコストを軽減できるみたいですが、
良さそうな方法は無いでしょうか。
653デフォルトの名無しさん:02/05/13 22:40
文字列バッファに溜め込んで最後にsubstringする方法と、
char-listを作って、最後にreverse & list->string
どっちがいいんだろうねえ
そんなチュウニングは、まともなものが出来た後でプロファイルしてから考えよ。
何のためのLisp/Scheme, GCか?

考えずにGC任せもまたよし。
655デフォルトの名無しさん:02/05/13 22:58
LISPだと自己投影プログラムが作れると聞きますが、
プログラムが正しいかを証明するプログラムを作れますか?
プログラムが正しいかを証明するプログラムが正しいかを証明するには
プログラムが正しいかを証明するプログラムで正しいかを証明する事で、
プログラムが正しいかを証明するプログラムが正しいかの証明になりますか?
656デフォルトの名無しさん:02/05/13 23:11
>>655
プログラムが正しいかを証明するプログラムが正しいかを証明するには
プログラムが正しいかを証明するプログラムでは役不足だ。
プログラムが正しいかを証明するプログラムが正しいかを証明するプログラム
でないと証明できない。
や く ぶ そ く ?
658デフォルトの名無しさん:02/05/13 23:19
プログラムが正しいかを証明するプログラムを作るには、
プログラムが正しいかを証明するプログラムが正しいかを証明するプログラム
を作らないと駄目って事ですか?
プログラムが正しいかを証明するプログラムが正しいかを証明するプログラム
が正しいかを証明するにはどうしたらいいんですか?
'プログラム'をメタ化すると、実は
プログラムが正しいかを証明するプログラム
で十分。
660デフォルトの名無しさん:02/05/13 23:32
アキレスと亀の話を思い出したよ。
なんとなく。
Brownの3-Lisp、Reflective Tower、Reflection
「プログラム」の範囲と、「プログラムが正しい」ってのがどう
いう意味かによる。これらを定義せんと作れるとも作れないとも
言えん。

例えば、「1階の型付きλ計算のプログラムが任意の引数につい
て停止して正しい型の値を返すかどうか」なら判定できる。

「オレが思う通りの結果をちゃんと返すかどうか」なら、「オレ
が思う結果」(仕様)をきちんと書いて入力に渡す必要がある。

「任意のSchemeプログラムが、ある引数について停止するかどう
か」なら、そういう判定をするプログラムは書けない。
>>652

>>SGML parser >> validating XML parser >> non-validating XML parser
>HTMLはどこに当てはまるんでしょうか?

HTMLの文書型定義をデータとして与えて動くようなものならSGML parserそのもの。

HTML専用にハードコードしてあるなら、validating XMLとどっちが楽だろ?
>>652
>(できればhtml->sexprも短くして欲しい・・・)
考え方だけだけど...

(define (parse-node tag attributes sub-tags)
 (let ((subnodes '()))
  (case current-token
   (tag
    (let ((desc (assq token-value dtd)))
     (or (null? desc)
       (begin
        (next-token)
        (parse-node (car desc)
              (parse-attributes (car desc))
              (cdr desc))))))
   (close-tag
    (if (eq? token-value tag)
      (next-token))
    `(,tag ,attributes ,(reverse subnodes)))
   (text
    (set! subnodes (append-text token-value subnodes))))))

ただし、next-tokenは、次のトークンを1つ読み込んで、その種類を
current-tokenに、値をtoken-valueに入れる手続き。

読んだ文字列 current-token token-value
<TAGNAME   tag      シンボルTAGNAME
>      gt       不定
</TAGNAME>  close-tag   シンボルTAGNAME
=      eqsign     不定
"      quote     不定
それ以外   text      文字列(空白または区切り記号まで)

変数dtdには、(TAGNAME その中に直接あらわれるTAG名のリスト)
のリストが入っている。
(define dtd '((html head body) (body ul ol p ... ) (ul li) ...))

(append-text string list)
は、リストの先頭が文字列なら、その後ろに空白とstringをappendし、
文字列でなければリストの先頭にstringをconsしたリストを返す。

(parse-attributes tag)は、「attrib1=value1 attrib2=value2 ...>」を
parseして((attrib1 . "value1") (attrib2 . "value2") ...)を返す。
(べつに逆順でも良い。)
665664:02/05/14 04:16
ごめん。parse-nodeはループしなきゃだめだった。

(define (parse-node tag attributes sub-tags)
 (let ((subnodes '()))
  (letrec ((loop
       (lambda ()
        (case current-token
         (tag
          (let ((desc (assq token-value dtd)))
           (cond ((null? desc)) ; 知らないタグは無視
              ((member token-value sub-tags)
              ;; 自分の子供
              (next-token)
              (set! subnodes
                 (cons (parse-node
                     (car desc)
                     (parse-attributes (car desc))
                     (cdr desc)))
                 subnodes))
              (else
              ;; 自分の子供でない
              ;; 今のノードを暗黙の内に閉じる。
              `(,tag ,attributes ,(reverse subnodes))))))
         (close-tag
          (if (eq? token-value tag)
            ;; 今のノードが閉じた。>を読み飛ばす。
            (next-token))
          ;; いずれにせよ、今のノードを閉じる。
          `(,tag ,attributes ,(reverse subnodes)))
         (text
          (set! subnodes (append-text token-value subnodes))
          (next-token)
          (loop))))))
   (loop))))

(define (html->sexpr filename)
 ...
 (next-token) ; トークンを1つ先読み。(ホントは何かタグが出てくるまで)
 (parse-node tag ...))

うーん…
666666:02/05/14 12:03
Fibonacciの末尾再帰版を本からコピペしてscmでtraceさせたのですが,
普通にCALL, CALL, .... RETURN, RETURN, ... と,
全然末尾再帰されていないように感じたのですが,scmのtraceが変なだけ?
traceの作りを考えれば当然かと。
668デフォルトの名無しさん:02/05/14 12:38
>>648
なにげに十分短いのではないかと。
副作用のある部分をなんとかしたいところだけど。
669LV:02/05/14 12:41
ワーム製造ソフトを無料で入手出来るサイト知ってたら教えてください
>>655-660
正しいかどうか分からないプログラムから
正しい結果が出力されることを期待してはいけない。
よって、
'プログラムが正しいかを証明するプログラム'が正しいことを、
'プログラムが正しいかを証明するプログラム'によって証明する為には、
前提条件として、
その 'プログラムが正しいかを証明するプログラム' が正しいということが
既に証明されていなければならない。
671デフォルトの名無しさん:02/05/14 20:36
>>501ですが、やっと汎用的な形になりました。
ネストの深い処理やwith系関数を、後付けで任意のポイントからポイントまで
の区間に適用する機構です。

;骨組み
(define (divide-continueation-prototype proc)
 (let ((resume #f)(after #f)(result #f))
  (call/cc(lambda(suspend)
   (set! result (proc (lambda()
    (set! after (call/cc(lambda(cont)
     (set! resume cont)
     (suspend #t)))) ;call/cc set!
   ))) ;proc lambda set!
   (if after (after #t))
  )) ; suspend
  (if resume (lambda()(resume (call/cc(lambda(c)c)))result) #f)
 )) ;let def

;使用例)任意の区間の出力を文字列として得る
(define (escape-string)
 (divide-continueation-prototype (lambda(divide-point)
  (with-output-to-string (lambda ()
   (divide-point))))))

(define end (escape-string)
(display "出力")

(end)
=>"出力〜"
672デフォルトの名無しさん:02/05/14 22:12
HTMLタグをS式にすると、何のメリットがあるんだ?
673デフォルトの名無しさん:02/05/14 22:28
>>672
(tag)
<tag></tag>
記述量が倍違う。

は冗談として、
そのままLISPリーダーとして活用できたりするとか。
(with-input-from-string
 "<begin><display>hello world!<newline></begin>"
 html->sexpr)
=>(begin (display "hello world!") (newline))

(eval(with-input-from-string
 "<begin><display>hello world!<newline></begin>"
 html->sexpr))
hello world!
よし。じゃそろそろ C コンパイラでも作ろうか。
>>672
HTMLがS式になったなら、それでHTMLがパーズできたってことじゃん。
あとはLispで加工できる。
676デフォルトの名無しさん:02/05/14 23:05
>>673
eval通るっつーのはいいね
677デフォルトの名無しさん:02/05/14 23:32
タグと属性の分割はこんなのでどうでしょうか。
(define (split-quote-string s)
 (let loop ((si 0)(i 0)(quote? #f)(r '()))
  (if (< i (string-length s))
   (cond
    ((char=? #\" (string-ref s i))
     (loop si (+ i 1) (not quote?) r))
    ((and (not quote?) (memv (string-ref s i) '(#\tab #\space #\newline)))
     (loop (+ i 1) (+ i 1) quote? (if (= si i) r (cons (substring s si i) r))))
    (else (loop si (+ i 1) quote? r)))
   (reverse(if(= si i)r(cons (substring s si i) r))))))

(define (split-tag-string s)
 (let ((tag (split-quote-string s)))
  (if (nlength? 2 tag)
   (cons (string->symbol (car tag)) (cdr tag))
   (string->symbol (car tag)))))

>(split-tag-string "A HREF=\"http://\" target=\"_blank\"" )
=>(A "HREF=\"http://\"" "target=\"_blank\"")
タグだけシンボルにしてみました。

この辺はperlなら数行で出来てしまえるかも
>>674
がんばってね
>>677
やっぱ連想listにしないと検索しにくいよ…
680デフォルトの名無しさん:02/05/15 01:34
<pre>〜</pre>
という問題が。
681680:02/05/15 01:36
あ、中身をそのまま取りこむなら、あのままで問題ないか。
のぶさんの日記より:
#1 [misc] XML

最近、みるたび思う。「なんで S 式にせんかった!」
これが、S 式だったら、今ごろ、世の中は Java ではなくて Scheme だったかも。

そっか。 世の中が Perl や Java だったから S 式になんなかったのか。ガクッ。
こんなの見つけた。
http://www.ipa.go.jp/NBP/12nendo/12mito/mdata/12-7h.htm
なんでしょうこれ
684デフォルトの名無しさん:02/05/15 01:56
>>679
(("A HREF=\"http://\" target=\"_blank\"") ...)

(A ((HREF "\"http://\"") (target "\"_blank\"")) ...)
に変換するフィルタープログラムを作るというのはどうか。
685デフォルトの名無しさん:02/05/15 02:17
S式がXMLよりも優れている点など

拡張可能アプリケーションの設計 第3回
: ブラック・ボックスはどんなとき、どこで、どのように最もよく機能するかを調べる
http://www-6.ibm.com/jp/developerworks/java/020315/j_j-diag1120.html

拡張可能アプリケーションの設計 第4回
: S式がどのように軽量のブラック・ボックス拡張性を実現するか
http://www-6.ibm.com/jp/developerworks/java/020322/j_j-diag1211.html
686デフォルトの名無しさん:02/05/15 02:27
みなさんなんでDSSSL使わずに自分で書こうとするんですか?
http://www.netfolder.com/DSSSL/
>>686
そこまで大袈裟にしたくないんでしょ
>>686
結局S式じゃダメだと気づいて、皆が捨てたからでしょ。
>S式じゃダメだ
なにがだめなんですか
691デフォルトの名無しさん:02/05/15 03:11
S式は内部的な処理、
XMLは外部とのやりとりに使えば?
XMLはコスト掛かりすぎだよ。
ここで議論するのもアレだな。
>>686
Lispがそうさせるから
693デフォルトの名無しさん:02/05/15 21:15
XMLとS式による開発速度を比べた場合、かなりの差が出そうだけど。
そうだね。XMLの方がはるかに速いだろうね。
なにしろツールやライブラリの蓄積が違う。
いちいち仕様考えながら作ってたんじゃ追い付くわけがない。
695デフォルトの名無しさん:02/05/15 22:25
>いちいち仕様考えながら作ってたんじゃ追い付くわけがない。
考えろよ
>>694
なにかの冗談でしょ?
697デフォルトの名無しさん:02/05/15 22:44
ステップ数はnに対数的に増加する
ってどういう意味?教えて。ください。
あほらし
700げとずざ
>>697
スレ違いだからアルゴリズム総合スレへでも逝った方が良いと思うが、
ひょっとしてSICPの話だったりするのかな?
702632:02/05/15 23:30
>>653
こんな感じでしょうか。
(define (string-resize s n)
 (if (<= n (string-length s))
  (substring s 0 n)
  (string-append s (make-string (- n (string-length s))))))

(define (read-token endc)
 (let ((s (make-string 128)))
  (let loop ((c (read-char))(i 0))
   (if (or (eof-object? c) (char=? c endc))
    (substring s 0 i)
    (begin
     (cond ((< i (string-length s)) (string-set! s i c))
        (else (set! s (string-resize s (* 2 (string-length s))))
           (string-set! s i c)))
     (loop (read-char)(+ i 1)))))))
SchemeやLispってのは過去の蓄積を再利用せず
車輪の再発明ばっかりする伝統があるのかな。

なんでDSSSL使わないんだよ?
704デフォルトの名無しさん:02/05/16 00:01
>>703
すいません。使い方わかりません。
どうやって使うんですか?
例をください。
>>703
国際規格になったようなものは使わないという反骨精神なんだろ、きっと。
せっかくSchemeの応用が大っぴらに規格化されたのにね。手をこまねいているうちに
XSLTができて「Schemeはヤパリ洋梨」ということになっちゃった。
なんでここで車輪の再発明の話がでてくるんだ?
707デフォルトの名無しさん:02/05/16 00:06
>>703
DSSSLって何?
>>703=>>705
なんかSchemeに恨みでもあるのかね?
>>706
今さらSchemeでHTMLパーザ書いたりしてるからでは?

>>707
ちょっとくらい前の発言を読めば?
710デフォルトの名無しさん:02/05/16 00:12
DSSSLやNetscape JavaScript DOMが世の中に出た頃、
SGMLベースの本格的なタグ記述言語が欲しいと思った。
Javaにうつつを抜かしている漏れを差し置いて、
SunとMSはコソーリXMLを作っていた。

今、一部の人々は S式と XMLの関係に夢中になっている。
数年後に結果が出ていればいいなーと、マジで思う。
711705 (!= 703):02/05/16 00:14
恨みなんかないよ。むしろSchemeは好きだが、どうして
Schemeコミュニティにはこう自殺傾向というか
過去の財産をあっさりすてて一から書き直してはまた崩しての
非建設的なことばかりする傾向があるのかイライラしてるだけ。

XMLの世の中になったってのに「S式使えば何でも解決!」しか
言わない奴もいるし…
712デフォルトの名無しさん:02/05/16 00:16
>>710
創作意欲を摘み取る様な事言うなよ。
君の都合で今さらパーサ書いたらいけないのか?

それはともかく、DSSSLの使い方がわからんので
やさしく説明してくれ。
713712:02/05/16 00:17
710じゃなくて709
>>711 オナニーが好きだからです。
sexpにまみれていられるし。
>>711
>過去の財産をあっさりすてて一から書き直してはまた崩しての
そう見えるのはコミュニティが弱小だから、情報が集まり
にくいってのがあると思う。特に日本では。
Variantな処理系が沢山ある割に、
横のつながりが弱いっていうか。
ただDSSSL使えって言われても、わからん奴にはさっぱりだと思うよ。
せめてどうやって使うとか、サンプルソースコードでもなんでも
情報提供してくれれば悪い印象にもならないと思うけど。
717デフォルトの名無しさん:02/05/16 00:38
>>715
LisperもSchemerもみんな独自に処理系を作りたがるから、
伊達を気取りたくなるんだよ。
>>716
>>686のリンク先にあるだろ。
消えてった処理系は、数知れず。
うぷぷ、
>>718みたいに、英語サイトのリンク先示すだけで終わるのも
問題のひとつだと思うよ。
721デフォルトの名無しさん:02/05/16 00:52
わかんないやつはDSSSLなんか使わずに一からパーサでも書けや
>>721
あーあ、期待してたのに。
そうやって突き放すから、新規ユーザーも増えないし、
閉鎖的になるんだよ。
>>722
もしかして対話してる相手が1人だけだとでも思ってるのか?
比較的まともっぽいコミュニティがあるのはemacsかな。
エディタで人望を得た。
725722:02/05/16 01:01
>>723
なんかそんな感じだったんで。
これ以上書くと、スレの雰囲気が悪くなりそうなんでやめるよ。
Schemeはすきなんだけどね。
>>724
lispで遊ぶのが目的ではなくて、完全に手段としてだからね。
1つの処理系で統合されてるというのもある。
分家はあるけど。
727デフォルトの名無しさん:02/05/16 01:08
だれかCコンパイラ作って
Sexpr vs. XML
>>727
おめーはだまってる!
730デフォルトの名無しさん:02/05/16 01:29
>728
視認性 Sexpr>>>XML
柔軟度 Sexpr>>>XML
処理系 Sexpr>>>XML
互換性 XML>>>Sexpr
知名度 XML>>>Sexpr
実装難度 XML>>>Sexpr
本の多さ XML>>>Sexpr
>本の多さ XML>>>Sexpr
これだよ!LISPも本を沢山出版するんだ!






・・・そして在庫の山
> 実装難度 XML>>>Sexpr

両方作った人いるのかな。
XMLのパーザくらいなら
CommonLispの実装作るより
ずいぶん簡単だと思うんだが。
>>732<Sexpr vs. XML
CommonLispとXMLを比較すんなよ
ここのスレ住人は揚げ足取りばっかだな
734デフォルトの名無しさん:02/05/16 01:55
2chの性でしょう
735デフォルトの名無しさん:02/05/16 01:59
(あ、この場合「せい」じゃなくて、「さが」と読みます。)
>>733
じゃ何と比較すんだよ。
実装って何だよ。
頭の硬いひとだね
>>737
(゜Д゜)ハァ?
頭が固いのは今どきS式マンセーとかいってるヤツらだろ。
>>736
S式じゃないの?
ま、なにがなんでもXMLを勝たせたいわけね。
>>739
S式の実装がS式?
馬鹿ばっかだな…
>それだから粘着厨房って呼ばれるんだよ
>>740
きみがバカなだけだとおもうよ
743デフォルトの名無しさん:02/05/16 02:13
んじゃ
実装の容易さ XML>>>Sexpr
ってことで。

〜〜〜〜〜〜〜〜〜〜〜〜 糸冬 了 〜〜〜〜〜〜〜〜〜〜〜〜
これにツッコムやつは粘着厨房。
ところで視認性はどう見てもXMLの方が上なわけだが、
<そんなむきになってXML擁護して何になるんだろう>
746デフォルトの名無しさん:02/05/16 02:17
約1名、変なのがいるみたいね。
XMLはクソ。これ定説。
そんなむきになってLispやScheme語って何になるんだろう…
>>746
禿げ同。
XMLスレの惨状見れば明らか。
そんなムキになって2ちゃんに書き込んで何になるんだろう。
そんなむきになって世界を支配してるXMLから目をそむけてなんになるんだろう
これは、話し合いに失敗したんで、
無言電話掛けるってパターンかな。
>>751
アンチパターンやね
753デフォルトの名無しさん:02/05/16 02:23
今夜のお祭りはここですか?
754デフォルトの名無しさん:02/05/16 02:23
まあ、我々SchemerもXMLには逆立してもかなわないことは
潔く認めて次の話題逝こうや。

まず、S式を廃止してXML化するには
XML化するには?
756デフォルトの名無しさん:02/05/16 02:33
・・・(XMLを使うと思考停止する様です。)
754は静かに息を引き取りました
─fin.

(eval 'XML)
=>"<クソ>"
>>758
フ゜quoteも評価できないevalって壊れてるよ。
760デフォルトの名無しさん:02/05/16 03:00
だが壊れているのは759の評価器だった
晒しage
>>759
メタ意識が足らんよ
762759:02/05/16 03:06
良くわかんない。解説して?
(eval 'XML) => XML
じゃないの?
763デフォルトの名無しさん:02/05/16 03:14
>>762
説明しよう。
(eval 'XML)を評価する段階でまず
eval => <primitive eval>
'XML => (quote XML) => XML
と、なるわけだ。これで全ての引数の評価が終了した。

次の段階で適用(apply)が起き、
XMLはどこかで"クソ"とbind(XML . "クソ")されてるんで、
(apply <procedure eval> XML)
の適用結果は"クソ"と、なるわけだ。
…つまらな〜い。

しかも変だし。
しかもさっきと結果違ってるし。
結局なにも知らないアホだったか
766デフォルトの名無しさん:02/05/16 03:23
>764
SICPでも読んどけ
ヤレヤレだぜ
(「つまらない」はおいといて)
764の言ってることは正しいと思うが? 何とbindされてようが
クォートされてるアトムをエバッたら困るし、
"<クソ>"と"クソ"が違ってる。
>>764はアフォ
>>765-767はLisp1.5 Programmers' Manualから読み直せ。
771764:02/05/16 03:28
SICPは初版も2版も読んだけど…
772763:02/05/16 03:29
>>768
そうだな。
どうせクソだからどうでもよかったんだが、
XMLは"<クソ>"が正解だ。
773デフォルトの名無しさん:02/05/16 03:30
755=756=757=765=766=767=無知
>>771
読んでその結果なら、もう関わるなよ。
775デフォルトの名無しさん:02/05/16 03:32
見事な糞スレage
776764:02/05/16 03:33
>>774
まー悔しいのはわかるけどサー
間違いを指摘してもらったら感謝するのが
筋ってもんじゃないの?

知ったかぶってごまかすんじゃなくて。
XMLに叩きのめされたS式厨房が毒づいてウサを晴らすスレはここですか?
778763:02/05/16 03:36
おっと。こんどは違う角度で責めてきたな。

>間違いを指摘してもらったら感謝するのが
ありがとう。

>知ったかぶってごまかすんじゃなくて。
君に言われたくないね(藁

>>777
どう見てもそんな展開には見えません。
780デフォルトの名無しさん:02/05/16 03:38
わーい祭り再開だー!
XML
=>"クソ"
クソ書くな
783764:02/05/16 03:44
Schemeのevalは2引数なんだけど…
それにapplyの最後の引数はリストじゃないとダメなんだけど…
マダナンカイッテルヨ
>>783
難しいこと言うから厨房が逃げちまったじゃねーかヴォケが!
>>783
schemeとはどこにも書いてないし、
applyは例で書いたんだと思うよ。
んで、そろそろウザイよ?>きみら
787764:02/05/16 04:02
Schemeじゃないのにprocedureと呼ぶの?
Schemeじゃないのにリストの最初の要素を評価するの?

…チッ、またごまかしてやがる。
764の自作自演uzeeee!
>>763は恥ずかしさのあまり自殺しますた。
粘着だな
無言電話からストーカー行為へと移りましたな
792デフォルトの名無しさん:02/05/16 04:21
■■■■■■■■ 結 論 ■■■■■■■■
763はただの知ったか消防で、764は神で、XMLはクソじゃありませんでした。
■■■■■■■■ 終 了 ■■■■■■■■
そのくらいにしとけよ。
どうせまともに答えられないんだから。
自作自演はおわりましたか?
もーね、アホかと。

evalなんて喜んで使う奴はScheme使いとしては三流に
決まってるんだから、問い詰めたってしょうがねえだろ。

XMLは糞だがオマエも糞じゃ。
オマエモナー

つか、みんな痛すぎ。特に>>763
初心者を装った764の手にうかうか載ってどうする。
つかみんなすごい時間にあそんでるね(w


オレモナー
みんな必死だったんだな。
(´-`).。oO(……自分の嫌いなもののスレにノコノコあらわれるのは何故だろう……
今日の今日までLIPSだと思っていた折れは何罪でタイーホですか?
>>799
猥褻物陳列罪と予想。
まあ、いずれにしても quoteの levelをまちがえてる
764の方がいたいと思うけど。っていうかそれもネタ?

普通 schemerなら evalなんて使わないし。
っていういか、なんで R5RSで入ったの? 消してほしいものだ...
compiler makerはどうしてるの?

802デフォルトの名無しさん:02/05/16 19:22
803デフォルトの名無しさん:02/05/16 21:22
html->sexpr/sexpr->htmlですが、
(tag attr-list contents..)の形に直しました。(attrは相変わらず文字列です。)

元HTMLに対しては正確ではないですが、以下の様な可逆変換が可能です。
(with-output-to-file "out.html" (lambda()
(sexpr->html
(with-input-from-file "read.html" (lambda()
(html->sexpr))))))

たまにタグの対応関係が取れない場合があります。
これは元HTMLが正常である場合、バックトラック解析によるまちがい修正で
それなりに回避できそうですが、read-charやset!等の副作用関数がむきだし
なのでそれを直す必要があります。

以下、全ソース
(define (split-quote-string s)
 (let loop ((si 0)(i 0)(quote? #f)(r '()))
  (if (< i (string-length s))
   (cond
    ((char=? #\" (string-ref s i))
     (loop si (+ i 1) (not quote?) r))
    ((and (not quote?) (memv (string-ref s i) '(#\tab #\space #\newline)))
     (loop (+ i 1) (+ i 1) quote? (if (= si i) r (cons (substring s si i) r))))
    (else (loop si (+ i 1) quote? r)))
   (reverse(if(= si i)r(cons (substring s si i) r))))))

(define (string-resize s n)
 (if (<= n (string-length s))
  (substring s 0 n)
  (string-append s (make-string (- n (string-length s))))))

(define (read-token endc . first-char)
 (let ((s (make-string 128)))
  (let loop ((c (if (pair? first-char)(car first-char)(read-char)))(i 0))
   (if (or (eof-object? c) (char=? c endc))
    (substring s 0 i)
    (begin
     (if (= i (string-length s))
       (set! s (string-resize s (* 2 (string-length s)))))
     (string-set! s i c)
     (loop (read-char)(+ i 1)))))))

(define (first-token s . opt)
 (if (pair? opt) (set! opt (car opt)) (set! opt 0))
 (if (string? s)
  (let ((pos (or(substring? " " s opt)(string-length s))))
   (if pos
    (substring s opt pos)
    s))
  s))

(define (split-tag-attr s)
 (let ((tag (split-quote-string s)))
  (if (nlength? 2 tag)
   (list (string->symbol (car tag)) (cdr tag))
   (list (string->symbol (car tag)) '()))))

(define *omit-tag-symbol-list* '(br hr meta input BR HR META INPUT))
(define *reuire-endtag-list* '("B" "TEXTAREA" "b" "textarea"))
(define (sexpr->html node)
 (define (require-endtag? node)
   (or (pair? (cddr node))
    (memv (symbol->string(car node)) *reuire-endtag-list*)))
 (if (pair? node)
  (let ((tag-name (car node)))
   (display* "<" tag-name)
   (if (pair? (cdr node))
    (for-each
     (lambda (pair)
      (display " ")
      (if (string? pair)
       (display pair)
       (begin
      (display (car pair))
      (display "=")
      (write (cdr pair)))))
     (cadr node)))
   (display ">")
   (if (require-endtag? node)
     (begin(for-each sexpr->html2 (cddr node))
     (display* "</" tag-name ">"))))
  (display node)))
(define (html->sexpr)
 (define (omit-tag? tag)
  (find
   (lambda (s) (eq? (car tag) s))
   *omit-tag-symbol-list*))
 (define (find-tag tag-string stack)
  (let ((tag (string->symbol (first-token tag-string 1))))
   (find
    (lambda (s)
     (and (eq? tag (car s)) (car s)))
    stack)))
 (define (make-tag tag) (split-tag-attr tag))
 (let loop
  ((c (read-char)) (stack '()))
  (cond
   ((eof-object? c)
    (if (pair? stack) (car stack) stack))
   ((char=? c #\<)
    (let ((tag-string (read-token #\>)))
     (if (char=? #\/ (string-ref tag-string 0))
      (let ((v (find-tag tag-string stack)))
       (if v
        (let loop1
         ((stack stack) (r '()))
         (if (not (eq? v (caar stack)))
          (loop1 (cdr stack) (cons (car stack) r))
          (begin
           (set-cdr! (car stack) (append (cdar stack) r))
           (if (pair? (cdr stack))
            (begin
             (set-cdr!
              (cadr stack)
              (append (cdadr stack) (list (car stack))))
             (loop (read-char) (cdr stack)))
            (loop (read-char) stack)))))
        (begin
         (stdout-puts
          "警告:"
          tag
          "は対応関係が異常です。読み飛ばします。")
         (loop (read-char) stack))))
      (let ((tag (make-tag tag-string)))
       (if (omit-tag? tag)
        (begin
         (set-cdr!
          (car stack)
          (append (cdar stack) (list tag)))
         (loop (read-char) stack))
        (loop (read-char) (cons tag stack)))))))
   (else
    (let ((s (read-token #\< c)))
     (if (pair? stack)
      (set-cdr!
       (car stack)
       (append (cdar stack) (list s)))
      (stdout-puts "警告:" s "はどのタグにも所属してません"))
     (let ((xc (peek-char)))
      (loop (if (eof-object? xc) xc #\<) stack)))))))
807デフォルトの名無しさん:02/05/16 21:26
>>804-806
荒らしはやめて
>>807=嵐という罠
>>808=>>803-806という罠
全ソース貼り付けるのはいかがなものかと。
Lisp板、今日はなんでこんなにレベル低いの...?
807=809
>>808
放置も出来ない厨房はすっこんでろと言われる罠
Lisp板?
確かにcar板やcdr板はあるけどさ
>>812
プログラム板をLisp板と勘違いしているだけ。
Lisp以外、眼中にないから。
>>813
そんなに括弧まみれが好きなの?
>>814
lisperにとって括弧は空気みたいなものです。
Lisp・・・・初めて見たときはプログラムだと思わなかった・・・・
高級言語でプログラムを書くと、理由も無しに「んじゃこれを C で…」等と
言ってくる愚か者がいるんですが。みなさんはどう対処します?
高級言語の中でも、Lisp が最も顕著なもののひとつかなと思って。
818デフォルトの名無しさん:02/05/16 22:22
>>814
括弧と括弧の谷間でムギュッ、が好きですが何か?
>>817
Cの括弧はふくらみがたりない
>>817
Cトランスレータ使うとか。
トランスレータが吐いたコードをメンテナンスする
気にはならんだろうけど。
820デフォルトの名無しさん:02/05/16 22:51
処理系にあまり依存しない様なCトランスレータある?
(define Y
(lambda (le)
((lambda (f) (f f))
(lambda (f)
(le (lambda (x) ((f f) x)))))))
822デフォルトの名無しさん:02/05/17 00:09
>>820
LISPからCへのトランスレータってlambdaとかあるから一筋縄じゃいかなそう。
一旦bytecode化してからやるのかな。
823デフォルトの名無しさん:02/05/17 01:55
CLOSってどうよ?
824デフォルトの名無しさん:02/05/17 02:54
>>823
ACL体験版使ってみれば?
普通のLISP関数と同様に扱えるのが強み。
ただしVariantが沢山ある。
実際、チープな処理系でもマクロの様なものがあればCLOSモドキは
いくらでも生産できる。これは凄いことなのかもしれないけど、
各々で独自のObjectSystem作れる事が逆に災いして、
そのシステム上でのプログラムを作っても他と交流できず
いつのまにか消滅して発展しないってパターンが多い気がする。
825デフォルトの名無しさん:02/05/17 04:42
マルチメソッドディスパッチ
826デフォルトの名無しさん:02/05/17 22:09
誰か
list->csv csv->list
作ってください。宿題とかではないです。

インタフェースは、
(list->csv l)でリストlをcsvに直して標準出力に吐く、
(csv->list)で標準入力のcsvをlistにする。

入出力に使用するリストは
((r1c1 r1c2 r1c3 ...)
 (r2c1 r2c2 r2c3 ...)
 (r3c1 r3c2 r3c3 ...)
 ...)
こんな感じで。
csvの引用符の処理は適当でいいです。
やだ
828デフォルトの名無しさん:02/05/17 23:19
書けこのやろう
829デフォルトの名無しさん:02/05/17 23:44
お前が、書け!
最近こんな応酬ばっか
831デフォルトの名無しさん:02/05/18 05:05
>>826
Gaucheで
(use text.csv)
(define (csv->list) (port->list (make-csv-reader #\,) (current-input-port)))
(define list->csv (let ((w (make-csv-writer #\,))) (lambda (l) (for-each (lambda (r) (w (current-output-port) r)) l))))

832デフォルトの名無しさん:02/05/18 11:13
read-char遅え。
やっぱバカ正直に1文字ずつ読みこんで懐石してくのは
インタプリタでは荷が重いな。最低read-lineだな。
833デフォルトの名無しさん:02/05/18 14:37
Scheme as an Extensible Enterprise Kernel (SEEK)
http://mappy.mobileboat.net/~seek/co/
834デフォルトの名無しさん:02/05/18 16:51
make-csv-reader
make-csv-writer
こんな関数あるの?
835デフォルトの名無しさん:02/05/18 16:52
>>817
いるいる。しかも情報系の大学教授あたりでも。
卒論発表なんかで関数型言語の話をすると、
「CやJavaのような実在の言語には適用できないのでは?」とか発言するDQN教官。
お前らのせいでプログラミング言語の進歩が阻害されとるんじゃゴルァ
836817:02/05/18 17:00
>>835
そりゃ教官の罠なんじゃないですか? 実は激しい Haskeller だったりして。
ま、違うだろうな。
837デフォルトの名無しさん:02/05/18 17:13
>>822
lambdaそのものは、常にクロージャ(=「関数へのポインタ+自由変数の値」の構造体)
を作ることにすば、バイトコードにまでしなくても、わりと楽にできそう。性能はともかく。

それよりもガベコレが問題かも。
Boehm GCっていう、CやC++用のガベコレが使える環境ならいいんだけど。
838デフォルトの名無しさん:02/05/18 17:34
この人、エヴァ見て綾波に憧れてたかしらないけど、綾波ソックリに整形するっ
てすごい。
エヴァ好きなら要チェック。↓整形板

http://life.2ch.net/test/read.cgi/seikei/1021620014/l50


839デフォルトの名無しさん:02/05/18 17:35
named-letをlambdaに展開すると、こんな感じになりますが、
(let loop()(display 'hoge)(loop))
=>(((lambda(loop)(set! loop(lambda()(display "hoge")(loop)))) '()))
これをCとかに変換しようと考えると、鬱になってきます。

tail_recursion_loop:
display("hoge");
goto tail_recursion_loop;

named-letのまま考えた方がいいんでしょうか。
>>839
うん。
841839:02/05/18 18:19
自分はこんなの1)をこんな感じ2)に変換したいと思ってるんですが、
どれぐらいのコード書かないといけないんでしょうか。
if文や関数を(f)->f()に変換するぐらいはできますが、
末尾再帰の認識や変数のバインディングのところで躓いてます。
(gcなどの問題は棚上げして考えてます)


1)
(define (list->csv l)
 (for-each1
  (lambda (col)
  (let loop ((s col))
   (if (pair? s)
     (begin
      (display (car s))
      (if (pair? (cdr s))
       (write-char #\,)
       (newline))
      (loop (cdr s))))))
  l))

2)
obj_t list2csv(obj_t l) {
  obj_t result = nil;
  obj_t args = l;
for_each1:
  if (pairp(args)) {
    obj_t col = car(args);
    obj_t s = col;
  loop:
    if (pairp(s)) {
      display(car(s));
      if (pairp(cdr(s))) {
        write_char(',');
      } else {
        newline();
      }
      s = cdr(s);
      goto loop;
    }
    args = cdr(args);
    goto for_each1;
  } else {
    result = t;
  }
  return result;
}
>>841
禿しく外出な話題だが、
なぜアリ物(Gambit-Cなど)ではだめなのか? 趣味?

まあ、あんまり凄い解析しないでちゃんと末尾再帰まで
実装するなら、Cのスタックは使わず、trampolineを使う
のが良いでしょう。

1. 元のSchemeプログラムは、関数呼び出しごとに別の
C関数に分けて変換する。

2. グローバルな変数fun, valと、引数を渡す仕組み
(グローバル変数や、配列で作ったスタック)を用意する。

3. トップレベルでは、
while (1) {
(*fun)();
}
みたいにする。

4. Scheme関数を呼び出すコードは、
(1)環境を閉じ込めた継続を作り、
(2)継続を配列で作ったスタックやヒープに退避し、
(3)引数をセットし、
(3)funに呼びたい関数を入れてreturnする。

5. Scheme関数からreturnするコードは、
(1)返す値をvalueに入れ、
(2)継続を取り出してfunにセットしreturnする。

頑張って解析すれば、継続や環境をなるべくヒープに
割り当てないようにできる。

(SICPが参考になる。)
843839:02/05/18 23:24
>>842
ありがとうございました。
継続も考えるとさらに鬱になってきますね。

>なぜアリ物(Gambit-Cなど)ではだめなのか? 趣味?
趣味です。
アリ物でシンプルなやつがあればそれ参考にしたいんですけどね。
844デフォルトの名無しさん:02/05/18 23:48
>>841
末尾再帰の判定は関数内を辿っていって、
例えば
(if test true false)ならば
test x
true false o
(begin seq1 ... seqn)ならば
seq1 ... x
seqn o
と末尾再帰可能か?を伝播していけばいけるんじゃないかと。
>>844
認識は簡単だけど、Scheme関数1つをC関数1つに変換するという
方針では、末尾再帰を実装できないよね。自分自身に再帰する
特殊な場合だけはgoto使えば良いけれども。
846839:02/05/19 01:01
レスありがとうございます。

>>844
その様ですね。
条件式、関数の引数についてはx
とか。

>>845
named-letは多用するんで、
その辺をまず考えていきたいと思います。

ちょろっと書いてみましたが、
(sexpr->c
 '(let loop ((s col))
  (if (pair? s)
    (begin
     (display (car s))
     (if (pair? (cdr s))
      (write-char #\,)
      (newline))
     (loop (cdr s))))))
という入力に対し、
=>"{
obj_t s=col;
loop:
if (pair?(s)) {
display(car(s))
if (pair?(cdr(s))) {
write-char(,)} else {
newline()}
loop(cdr(s))
}
}
"
という文字列を返すところまでできました。
いまのところコード中には副作用無しです。
式文の終端のセミコロンや、letの右側のバインド式など、まだ課題は沢山ありますが。
「関数を関数に、ifをifに」
ってな具合いに変換するのは、すぐ壁に突き当たると思う。

SICPの5.5節を嫁。
848デフォルトの名無しさん:02/05/19 06:47
関数を全部labelにしろ。
849839:02/05/19 14:56
現在こんなかんじです。
いまのところソースは100行ぐらいです。
解析関数にローカル変数のリストを加えたので
末尾再帰loopシンボルの処理まではできました。
for-eachはlambda限定で1リストの決め打ちです。

(sexpr->c
  '
 (for-each
  (lambda (col)
  (let loop ((s col))
   (if (pair? s)
     (begin
      (display (car s))
      (if (pair? (cdr s))
       (write-char #\,)
       (newline))
      (loop (cdr s)))))) l)))
=>"
{
  obj_t g162=l;
  for_each_g162:
  if (pairp(g162)) {
    obj_t col=car(g162);
    {
      obj_t s=col;
    loop:
      if (pair?(s)) {
        display(car(s))
        if (pair?(cdr(s))) {
          write-char(,)
        } else {
          newline()
        }
        s = cdr(s);
        goto loop;
      }
      
    }
    g162 = cdr(g162);
    goto for_each_g162;
  } else {
    result = t
  }
}
"
※実際はこんな綺麗にインデントはされません
850デフォルトの名無しさん:02/05/19 15:07
末尾再帰じゃないnamed-letはどんなコードになるの?
851839:02/05/19 15:49
>>850
末尾再帰判定で弾かれるので最初の出力の様な、ただの関数呼び出しになります。
今のところloop関数は別途出力される予定はないので、おかしな事になります。
手動でコピペして修正する必要があります。
852デフォルトの名無しさん:02/05/19 21:32
sicp ex1.24
O(log n)の関数フェルマーテストを使って実験しました。

1009と1000003では、2.3倍
10007と100000007では、2.4倍になりました。

2倍になってません。違いを説明できません。
助けてください。

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.6
>>852
小さい整数と大きい整数の演算では速度が違うからね。
そのくらいのずれはしょうがない。ぴったり2倍になるわけはない。
854デフォルトの名無しさん:02/05/19 22:16
計測には誤差はつきものだね。
855デフォルトの名無しさん:02/05/19 22:28
問題:データはその予想を支持するか。違いがあれば説明できるか。
解答:誤差だと思われ。

でいいんですね。ありがとうございますた。
GC時間は差し引いた?
857デフォルトの名無しさん:02/05/20 18:15
>>847
横着なソースだと関数引数やifの条件式の中にletとかあったりするよね。
(func (let ...))だったら
(let ((tmp (let ...))) (func tmp))
みたいにすればいいかな。
858デフォルトの名無しさん:02/05/20 19:58
Cに変換すると速度はどれぐらい違うんでしょうか?
859デフォルトの名無しさん:02/05/20 21:45
CをLispに変換すると、どれくらい速いんでしょうか!
>>858
S式をインタプリトするのと比較して?

元のインタプリタにもよるけど、
単純な変換だと、実はそれほど速くならない。

高速なインタプリタと比較すると、
普通のリスト処理だと3倍くらいじゃないか。

整数演算とかだと、うまく型宣言すると
30倍くらいになる。

まず、「S式をたどって式の種類を判別する」
オーバーへッドを省くだけで、やることが変わ
らないような変換だとせいぜい3倍。関数をイ
ンライン展開しないとそれ以上の速度向上は
望めない。

次に、GCが遅いようなインタプリタだとどう
やってもだめ。例えば処理時間の40%がGC時間
のインタプリタは、どんな凄い最適化をしても
(メモリ割り付け量が減らない限り)2.5倍に
しか速くならない(アムダールの法則だね)。
>>859
開発速度は桁違いに早くなるでしょう。実行速度はわからん。
全体として見れば、下手な奴が書く C プログラムよりずっと良いと思う。

862839:02/05/20 23:56
ようやくある程度使えそうなものができました。(インデント処理も含め)
schemeコード副作用なしで、500行ぐらいです。
まだ普通の再帰、継続、クロージャその他もろもろに未対応ですが。
ここまで思ったより短い期間で作れたんで満足してます。以上。

変換結果
obj_t list_to_csv(obj_t l) {
 obj_t result = nil;
 {
  obj_t g2 = l;
  for_each_g2:
  if (pairp(g2)) {
   obj_t col = car(g2);
   {
    obj_t s = col;
    loop:
    if (pairp(s)) {
     display(car(s));
     if (pairp(cdr(s))) {
      write_char(',');
     } else {
      newline();
     }
     s = cdr(s);
     goto loop;
    }
   }
   g2 = cdr(g2);
   goto for_each_g2;
  } else {
   result = t;
  }
 }
 return result;
}
なんか、むちゃくちゃレベル高くなったな。
いっときはクソスレに片足突っ込んでたのに(w
864デフォルトの名無しさん:02/05/21 11:04
http://flex.ee.uec.ac.jp/texi/eljman/eljman_69.html#SEC69
のcopy-alistの説明を理解できないんだけど誰か教えてくれない?

(setq alist '((a . 1) (b (2))))
=> ((a . 1) (b (2)))
(cdr (car (cdr alist)))
=> ((2))

(cdr alist)
=> (b (2))
(car (b (2)))
=> (b)
(cdr (b))
=> nil
としか思えない…
865デフォルトの名無しさん:02/05/21 11:14
実際に走らせてみたら?

(cdr alist) => ((b (2)))
(car ((b (2)))) => (b (2))
(cdr (b (2))) => ((2))
866デフォルトの名無しさん:02/05/21 14:05
(cadr alist)
=> (b (2))
(cdr '(b (2))) => ((2))
じゃねーの?
慣れると
cadr→2番目
cdr→残り
と脳内変換されるよ。
867デフォルトの名無しさん:02/05/22 00:32
WindowsでLISPやる場合はどんな処理系がありますか?
868デフォルトの名無しさん:02/05/22 00:36
xyzzy
869デフォルトの名無しさん:02/05/22 00:38
emacs-lisp
870デフォルトの名無しさん:02/05/22 00:42
>>867
自分で作れ
871デフォルトの名無しさん:02/05/22 00:47
LISPからVBにトランスレートするコード誰か書いて!
872デフォルトの名無しさん:02/05/22 00:53
>>871
リストってVBで表現できたっけ?
Variant型の配列使うしかないのかな。
873864:02/05/22 01:53
>>865
>>866
DQNな質問に答えてくれてありがとう。
874デフォルトの名無しさん:02/05/22 01:54
>>867
Win32 LISPで検索しろ
875デフォルトの名無しさん:02/05/22 02:42
Gaucheってcygwinで動くんだね。
>871
VBに変換してどうするんだろう
877デフォルトの名無しさん:02/05/22 02:55
LISPからトンパ語にトランスレートするコード誰か書いて!
ネイティブコードやJavaVMとかに変換した方がいいとおもう。
変換後、すぐ実行できるし。
メンテは大変かもしれないけど。
879デフォルトの名無しさん:02/05/22 03:59
>>878
実際オープンソースでネイティブ変換してるやつ、
ググって探してみたけど無いもんだね。製品ばっかり。
JavaVMはKawaってのがあるみたいだけど。
880デフォルトの名無しさん:02/05/24 16:37
(method object ...)

(object.method ...)
ってやってる処理系ってありませんか?
'.'をフックすればできるのかな。
見た目的にマルチメソッドではなくなってしまうだろうけど。
881デフォルトの名無しさん:02/05/24 18:48
Arcが x.y を (x y) と読む、とかいう略記法を採用していたような。
CommonLispで '.' のリーダーマクロを書いて、x.y を (slot-ref x 'y)
と読ませるようにしたことはあります。
882881:02/05/24 18:52
違った。CommonLispはslot-valueだ。
883デフォルトの名無しさん:02/05/24 21:47
>>881
ありがとう。
x.y.zの場合は(slot-ref (slot-ref x 'y) 'z)か。

>Arcが x.y を (x y) と読む、とかいう略記法を採用していたような。
Arcって実装は存在するのかな。
884デフォルトの名無しさん:02/05/24 22:44
>>883
全部とは言わないけど、ほとんどマクロでなんとかなると思う。
既存のsyntaxに対しての上書きもあるのが問題だけど。
Arcのラッパーマクロ集みたいなの公開してくれないかなあ。
(object message args ...)
組み込み apply を再定義できないものでしょうか。
オブジェクトを表現するのにクロージャとタグを使って、

(define apply
(let ((orig-apply apply))
(lambda (proc args)
(cond ((object? proc) (dispatch proc args))
(else (orig-apply proc args))))))

みたいな感じで出来ればいいなぁ、と。
886デフォルトの名無しさん:02/05/24 22:56
>>885
SLIBが動く様な処理系ならapplyの再定義なんかは普通にできると思うよ。
あれのtranscriptの実装は入出力全部再定義してるし。
887デフォルトの名無しさん:02/05/24 23:03
>>885
あ、良く見たら組み込みapplyの方ですか。
CommonLispみたいにフックを登録できる様な処理系じゃないと。
現状のschemeの規格範囲内では無理です。
888デフォルトの名無しさん:02/05/24 23:12
内部に手を加えない手段としては、objectをclosureにして、
もう一段上でdispatchする方法があります。(過去スレにありますけど。)
これだとscheme規格範囲内での実装ができます。
889885:02/05/25 09:59
>>888
ありがとう。SICP を読んでいるので、一段上で dispatch するやりかたは
愛用させてもらってます。

((obj 'msg) args ...) の形に書き換えるマクロを作ったりしたのですが、
なんだかなーと思っていた所なんですよ。
890デフォルトの名無しさん:02/05/26 00:29
Float-Point Number Lispって論文読んだことある人いる?
検索しても密館内。
もう少し正確な論文名きぼん。
892デフォルトの名無しさん:02/05/26 01:00
>>889
procedure?とobject?のきリ分けができなくても困らない?
893889:02/05/26 09:40
>>892
ん? 質問の意図するところが分からないんですけど。

894デフォルトの名無しさん:02/05/26 16:15
sicpの図形言語を実際にやってみたいんですけど、
なにとなにをインストロールすればよいのでしょうか?
OSはWindowsです。
895デフォルトの名無しさん:02/05/26 16:44
>>893
例えば
(define object1 (make-object <a-class>))
として<a-class>に属するobject1を作ったとして、
そのobject1が<a-class>なのかプリミティブなのかを判定したくても、
中身はclosureそのものだから、(class? object1)
とかが作れない。
(define (class? object) (procedure? object))
でもいいの?ってこと。
クラスメソッドとして(object 'typeof)というのを作っても解決しないし。
896893:02/05/26 21:05
>>895
その場合はタグを付ければ良いんじゃないでしょうか。
演繹的に実装する場合、いずれにせよ何らかのプリミティブに
置き換えられるわけで。
897デフォルトの名無しさん:02/05/26 23:35
>>896
いや、タグを付けるのはいいんだよ。
けどそうなると特別扱いしなくてなならんので、その辺どうなのかということ。
どのみち処理系に手を加えるなりしないとこの問題は解決しそうにない。
(method object)形式なら話は簡単なんだけど。
898デフォルトの名無しさん:02/05/26 23:51
名前に連結されてるdot(.)にフックを持てる様な処理系なら
(object.method-a.method-b)
に対して
(method-b(method-a object))

((object 'method-a) 'method-b)
に変換するのは可能でしょう。

あたかも事前に
(define (object.method-a.method-b) ...)
としていたかの様に使える。
既存のdot表記とは、シンボルとくっついてる限り区別できるから
互換性が保てるはず。
シンボル以外の任意の式だと…?
((if (foo) object1 object2).method1 ...)
これは無理だよね。
900896:02/05/26 23:57
>>897
その前に、僕のどの発言に対しての意見なのでしょうか?
議論がすれ違っているように思えるんですけど。
901デフォルトの名無しさん:02/05/27 00:33
>>898
こういうのできたら面白いよね
>(define a (list 'b 'c 'd))
>(a.car)
=>b
>(a.cadr)
=>c
>(a.cdr)
=>(c d)
902897:02/05/27 00:41
>>900
(object method)に対してapplyしたい>>885

objectをclosureにすればいい>>888

そうなるとprocedureとの区別がつかない>>892

意味がわからない>>893

に対してのレスのつもりなんだけど。
特別扱いはapplyの時ね。
903デフォルトの名無しさん:02/05/27 01:02
(object method-selector arg1 arg2 ...)っていうのをばんばん使うなら、
>>897の言うように実装を隠す機構が必要だと思うな。

それにarg1でdouble dispatchingするくらいなら、
CLOS風のgeneric functionがelegantだと思うし。

904デフォルトの名無しさん:02/05/27 01:08
>>901
あくまでもシンボル(読みこみ時に解決)に対してだから、
lambdaやletかますしかないかと。
((lambda(a)(a.method1 ...)) (if (foo) object1 object2))
(let ((a (if (foo) object1 object2)))(a.method1 ...))
あと、右辺に適用できるのが1引数を取る関数になってしまう様な。
(a.method1 b)みたいなことはできないと思う。
(a.method1 b)を
((lambda args (apply method1 (cons a args)) b)
に変換するならできるかもしれないけど。
905デフォルトの名無しさん:02/05/27 15:30
質問です。 smob (smobsか?) ってなんですか?
データ構造みたいなんだけど、googleとかで探しても
使ってる場面しか見つからなくて、意味が
わかりません。
906デフォルトの名無しさん:02/05/27 16:41
>>905
ここを見る限りだと
「Defining New Types (Smobs)」
http://www.red-bean.com/guile/notes/data-rep/data-rep.html#SEC25

Guile(とその派生元のSCM)に対して新しいschemeオブジェクトを
定義するインタフェースだね。
Cで組み込みデータ型を作る時に使うんでしょう。
'smob'の名前の意味はわからんけど。
907デフォルトの名無しさん:02/05/27 16:47
The term "smob" was coined by Aubrey Jaffer, who says it comes
from "small object", referring to the fact that only the CDR and part
of the CAR of a smob's cell are available for use.
908デフォルトの名無しさん:02/05/27 16:54
smob ==> "small object"
の略と↓に書いてあった。
http://www.red-bean.com/guile/notes/data-rep/data-rep_foot.html
909908:02/05/27 16:55
かぶった
910デフォルトの名無しさん:02/05/27 17:20
>>904
*dot-hook*というドット連結シンボルを読みこみ時に呼び出される
フック関数があるとしたら、こんな感じになる。

;argsはドットから切り離されたシンボルのリスト
(define (*dot-hook* args)
 (let loop ((x (cdr args))(expand (car args)))
  (if (pair? x)
   (loop (cdr x)
    (if (pair? (cdr x))
     ;ドット連結が続くなら1引数を取る関数しか使えない
     (list (car x) expand)
     ;最後のシンボルに対しては外部から引数を取ることができる様にする
     `(lambda args (apply ,(car x) (cons ,expand args)))))
    expand)))

>(define a 'string)
>(a.symbol->string.string-append "-append")
=>"string-append"

(a.symbol->string.string-append "-append")

((lambda args (apply string-append (cons (symbol->string a) args))) "-append")
と変換される。

名前でアクセスする必要がある&途中の関数に対しては1引数しか取れない、
という限定的なものだけど。
911905:02/05/27 17:53
なるほど、Guileの用語でしたか。
どうもありがとうございます。
912デフォルトの名無しさん:02/05/27 20:09
>>910
いっそのこと、
a.method<c,d>
=>(method a c d)
に変換するってのはどお?
a.methodとした場合はclosureを返す。
a.method<c,d>.method<e,f>
(a.method<c,d>.method e f)
こういう風に両方で書けるし。
でも結局<>内はシンボルなんだなあ。
913デフォルトの名無しさん:02/05/28 03:11
>>912
いいね。
ただしカンマの間に間違えて空白とか入れちゃうと意味変わるのが怖いけど。
ただのa.method<c,d>.methodというシンボルに対してのリーダー展開
マクロってだけだからねえ。
これ以上はname<〜>を別の意味に解釈する(内部)readを作る必要があるね。
914デフォルトの名無しさん:02/05/28 07:11
>>910
1つのS式の読みこみ毎に呼ばれる*READ-HOOK*関数を定義できるとすれば、
もうなんでもありだと思う。
1つのS式つーのは、読みこむS式が
(e (a b c) (d))
だとすると
(a b c) ... x
(d) ... y
(e x y)
のパターンそれぞれで呼び出されるってこと。
xとyはそれぞれの*READ-HOOK*の結果が入る。
S式の一番根っこの時点でexpandかければ、macroの展開も同時に
作用させられる。
CommonLispにも同様の機能があるけど、S式の読みこみ段階で
1度処理が走るだけだから、後のeval実行プロセスには影響ない
ってのがかなり使えると思う。
処理系を自作で持ってたるする人は試してみよう。
せっかくLispなのに中置記法やカンマなんて出てくるのは欝。
916デフォルトの名無しさん:02/05/28 17:42
>>914
>のパターンそれぞれで呼び出されるってこと。
evalの評価順序と逆になる?
eがマクロだとしたら、(a b c) (d)を先に変更するのはまずい気が。
eがcaseみたいな特殊なカッコの使い方をする時とか。
917900:02/05/28 23:18
>>902
最近忙しくて、返信が遅くなってしまいました。
ずーっとこの問題について考えていたんですが、やっぱり
(method object args ...) が一番な気がしてきました。
918デフォルトの名無しさん:02/05/28 23:54
ソウダロソウダロ
>>915
カンマ→ピリオドじゃねーの?
,はbackquoteで使うよん。
920デフォルトの名無しさん:02/05/29 07:56
質問です。
Case sencitiveなSchemeの
string->symbol と string->symbolは、
1-to-1 だと仮定して大丈夫なんでしょうか? また、
その二つの合成関数は常にidentityと仮定してよいんでしょうか?

921デフォルトの名無しさん:02/05/29 19:24
>>920
>string->symbol と string->symbolは、1-to-1 だと仮定して大丈夫なんでしょうか? また、
symbol->stringとstring->symbol
の間違いじゃない?
この辺は規格書とr4rstest.scm見ればわかると思う。

>その二つの合成関数は常にidentityと仮定してよいんでしょうか?
identityってなに?
922デフォルトの名無しさん:02/05/29 19:34
>>916
>evalの評価順序と逆になる?
逆になります。
S式の根っこで呼び出した方がいいかも。
923デフォルトの名無しさん:02/05/29 22:34
substringはあるのにsublistやsubvectorが無いのは何ででしょうか。
924920:02/05/30 01:12
>>921 「...の間違い」
そうです。

R5RSをちらっとみてみた範囲では、例はあげられていたものの、
単射でなければならないとは書いてないような気がして。
ところで、RnRS以外の規格書ってあるんですか?

identity 云々は、
∀x (xはSchemeのオブジェクト)
{(string->symbol (symbol->string x))
≡ (symbol->string (string->symbol x))
≡ x}
(あるいは、
{(lambda (x) (string->symbol (symbol->string x)))
≡ (lambda (x) (symbol->string (string->symbol (x))
≡ (lambda (x) x))}
は仮定して大丈夫なんでしょうか?という意味です。
925920:02/05/30 06:45
あ、いけね。前半は

∀x (xはSchemeのシンボル)
{(string->symbol (symbol->string x)) ≡ x}

∀x (xはSchemeの文字列)
{(symbol->string (string->symbol x)) ≡ x}
なのかどうか、です。
(後半の式もかっこの対応が変だけど。)
926KOKUYO:02/05/30 14:06
質問!!member関数を、第2引数のリストの深いレベルまで
第1引数を探索して取り除くように拡張した関数はどうやって
作ればいいんですか?
>>926
なんだマルチか。
関数型言語スレにヒント書いておいたよ。
>>926
memberを自作してcarがconspな時に再帰する様にしてけばつくれるよ。
取り除くって事は破壊/非破壊の2パターン作れるかと。
この場合非破壊バージョンはちょっと難易度高いかも。
929デフォルトの名無しさん:02/05/30 17:17
>>924
>(lambda (x) (string->symbol (symbol->string x)))
>(lambda (x) (symbol->string (string->symbol x)))
>(lambda (x) x)
これ、それぞれの意味全く違うと思うけど。
何がしたいの?
930929:02/05/30 17:27
あ、質問の意味がわかった(きがする)

>(lambda (x) (string->symbol (symbol->string x)))
引数と戻値はeqv?で一致すると保証されてる。
>(lambda (x) (symbol->string (string->symbol x)))
引数と戻値はeq?で一致すると保証されてる。
>(lambda (x) x)
引数と戻値はeq?で一致すると保証されてる。

これでいいかな?
symbolはuniqueなので比較は同一だけど、
一旦stringになった場合、それが同値(コピー)なのか同一なのか
は保証されていないって事で。
931929:02/05/30 17:28
>>930逆だった
>(lambda (x) (string->symbol (symbol->string x)))
引数と戻値はeq?で一致すると保証されてる。
>(lambda (x) (symbol->string (string->symbol x)))
引数と戻値はeqv?で一致すると保証されてる。
932920:02/05/30 18:21
>>929 これ、それぞれの意味全く違う[...]

どうもありがとうございます。
よく考えたみたら、そりゃそうですよね。疑問点を
頭の中で明確にする前に質問書込んでしまいました。
すみません。
933デフォルトの名無しさん:02/05/30 19:54
誰かguile-gtkのwindowsバイナリ作ってください。
おねがいします。
934デフォルトの名無しさん:02/05/30 20:06
>>933
知ってるかもしれないけどcygwinでguileコンパイルする方法が載ってるよ。
ttp://www.geocities.co.jp/SiliconValley-PaloAlto/7043/
gtkについてはわかんない。
cygwinでもXは動くらしいから不可能ではないんでしょ。
935デフォルトの名無しさん:02/05/30 20:31
>>923
なんでだろね。対称性悪いよね。
Gaucheにはsubseqがあるな。
(use gauche.sequence)
(subseq '(a b c d e) 1 4) => (b c d)
(subseq '#(a b c d e) 1 4) => #(b c d)
(subseq "abcde" 1 4) => "bcd"

936デフォルトの名無しさん:02/05/30 21:10
>>920
ちょっと(or たくさん)外してるかも知れませんが、
common lisp の
Read-read consistency
Print-read consistency
Print-print consistency
を調べてみると、考えをまとめる手がかりになるかも知れません。
この辺を突っ込んで行くと、2-lisp、3-lisp とどんどん腐海世界に
(scheme からは離れて行っちゃうけど)入り込んで行けます。
Gauche には debugger はないのか?
938デフォルトの名無しさん:02/05/31 00:39
>>937
debuggerとはソースの修正も入るやつ?
インテリジェントなやつは多分ないと思う。

エラー個所の特定ならtraceするって手段があると思うけど。
たぶんそれぐらい入ってると思う。(この手はLISP系だと作るのが簡単)

ステップ実行もできるといいとは思うけどね。
evalされる毎に式を表示してリターン押すと実行とか。
>>923
> substringはあるのにsublistやsubvectorが無いのは何ででしょうか。

そう言う意味での「完全さ」を求めるとCommon Lispみたいに肥大しちゃう
から。(stringとlistはそもそもn番目の要素のアクセス法が全く異なるし。)
940デフォルトの名無しさん:02/05/31 07:08
>>939
CommonLispみたいに汎用的なのはマクロで作って、
:stringみたいに型を明示的に指定するってのはどうですか。
実行時判定を行わずに展開時で切り分けできるし。
941920:02/05/31 10:57
>>936
こういう誘導はとても助かります。どうもありがとうございます。
>>936
申し訳ありませんが 2-lisp,3-lispについて解説しているページを教えて戴けませんか?
ぐぐっても、まともにヒットしてくれません。
943無名λ式:02/06/01 00:39
>>942
http://www2.parc.com/publications/pubs-hst.html

Interim 3-LISP Reference Manual
Brian C. Smith, Jim des Rivieres, July 1984

The Implementation of Procedurally Reflective Languages
Jim des Rivieres and Brian C. Smith, July 1984

Reflection and Semantics in LISP
Brian C. Smith, June 1984

;; "3-Lisp"と引用符付けてる?
944デフォルトの名無しさん:02/06/01 16:18
>>943
どこに説明が?
945デフォルトの名無しさん:02/06/01 19:54
みなさん、Linux上でおすすめのCommon Lisp処理系は何ですか?
Allegroって凄く高いですよね?

946デフォルトの名無しさん:02/06/01 19:57
豪華2本立てage
http://www.shiro.dreamhost.com/scheme/index-j.html

>>945 clisp, gcl(kcl) あたりはいかが?
CommonLispはよくわからん
947デフォルトの名無しさん :02/06/01 22:29
>>945
それ知りたい。今使ってるのはGCLだけど、他にあれば教えてください。
>>945
確かに高いが、すごくってほどでもない。
個人じゃ手が出ないが
949デフォルトの名無しさん:02/06/01 22:55
ACLなん万だっけ?20万ぐらいで買えた?
じゃ2年ローンで・・

>>945
LinuxだったらGNUの洗礼を受けたgclかな。
メンテナンスされてるのか知らないけど。
>>949
桁が一つ違う
951デフォルトの名無しさん:02/06/01 23:39
>>950
マジで?
952デフォルトの名無しさん:02/06/01 23:49
>>945
LinuxでもACLのTrial版動くみたいだけど。
http://www.franz.com/downloads/
953デフォルトの名無しさん:02/06/02 00:28
>>945
cmucl http://www.cons.org/cmucl/ がよさげ。
gcl のコンパイラ遅杉。
954デフォルトの名無しさん:02/06/02 00:36
>>953
Windowsバイナリがみあたらないんですが、
無いんでしょうか。
955デフォルトの名無しさん:02/06/02 00:41
http://jp.franz.com/
>2002年6月26日(水)から6月28日(金)に東京ビッグサイト(有明)で開催
>される 「第11回 ソフトウェア開発環境展 SODEC」(リード エグジ
>ビション ジャパン(株)主催) で、新日鐵ソリューションズ(株)
>ブースにおいてAllegro CL6を出展いたします。

興味のある人は行ってみたら?無料招待券と貰えるのか知らんけど。

ソフトウェア開発環境展
http://web.reedexpo.co.jp/SODEC/japanese/index.html
956デフォルトの名無しさん:02/06/02 00:41
>>954
Win厨は氏ね
そろそろ次スレかなあ。
959デフォルトの名無しさん:02/06/02 01:45
>>958
>価格
>・デスクトップタイプ プロフェッショナル版 130万円〜
>_ エンタープライズ版 200万円〜
>・サーバータイプ プロフェッショナル版 260万円〜
>_エンタープライズ版 400万円〜 アカデミックプライスもあります。

ACL5だから情報がちょっと古いとはいえ、
こりゃ個人では手がでませんな。


関係ないけど

>MOEBIUS (メビウス)
>Common Lisp to C translator 理想の言語変換ツール
>価格
>1,000,000円より

ってどんなだろ。
lispをcに変換するのは、schemeをcにするよりは継続とかがない分
簡単かも。
CommonLispを完全に変換するのは量的に苦労しそうだけど。
>>959
ライブラリとしてインタプリタを持っていて、変換しきれない分はインタプリタで実行。
perlccと同じ
961名無しさん@Emacs:02/06/02 11:22
>> 945
> cmucl http://www.cons.org/cmucl/ がよさげ。
に二票。
Debian ならパッケージがあるし、
/etc/apt/sources.list に
deb http://www-jcsu.jesus.cam.ac.uk/ftp/pub/debian local lisp
を加えておけば、AllogroServe や UnCommonSQL も使える。
962無名λ式:02/06/02 17:33
>>944
すまん、論文本体ここにはないね。しかもどこでも見つからん…
手元にあるのもthesis.psなんて名前で検索しようがない…

http://www.amazon.co.jp/exec/obidos/ASIN/4320025350/qid%3D1023006305/250-7641766-9377045
の最後の節「メタプログラミングとリフレクション」田中二郎で許して。
それって、えーとR田中二郎???
どなたか
そろそろ次スレ立ててください。
自分は「スレッド立てすぎです・・」が出てしばらく立てられそうにないです。
Common Lisp の本は出ましたか?
次スレ立ってました。

LISP Scheme Part5
http://pc.2ch.net/test/read.cgi/tech/1023091882/
ちょっほ〜いとまちなは>>963
さあ歌え。
969デフォルトの名無しさん:02/06/10 17:38
 
970デフォルトの名無しさん:02/06/14 23:20
すいません、
だれかスタンダードなLISPてどれか教えていただけませんか
処理系がおおくて。
>>970
commonという名を持つLISPがいますがね。
>>970
Common Lispなら、

GCL, CLISP, LispWorks(パーソナルはフリー)などなど。
探せばいくらでもあると思うんだけど。
973踊る名無しさん 12:02/07/09 04:11
O)-< O\-< O|-= O|-= O(-<
974デフォルトの名無しさん:02/07/14 00:04
SICP に出てくる cons-stream ってどう書いたらいいんですか?
定義が載ってないので stream 系の例題が全部試せないし、自分で書こうにも
stream も macro もわかってないのでお手上げです。(多分 macro で書けるん
だろうと思っているのですが)

;; stream 系の手続き実装してる処理系使うのが一番早いんでしょうけど。
旧スレageられてもねぇ…
ごめんなさい。旧スレ眺めてたら誤爆してしまいました。
>>974
素直に delay 使えば出来ません?
978デフォルトの名無しさん:02/07/16 06:16
>>977
フランジャーのほうが良い。
もうちょっとヒネレよ
このドアホ
こっちはもうsageてくれ
981デフォルトの名無しさん:02/07/16 16:07
age
ここは旧スレ、ageるなボケ

LISP Scheme Part5
http://pc.2ch.net/test/read.cgi/tech/1023091882/l50