1 :
デフォルトの名無しさん :
04/11/12 12:16:06
連続投稿でひっかかるし関連リンクは別ページにおかないか?
そことは余り関わりたくない。
とりあえず個人ページの直リンはやめてくれないか flatline自体コテハンみたいなものだとしても
14 :
名無しさん@お腹いっぱい。 :04/11/14 17:54:04
だからtemplateはジェネリックプログラミングでオブジェクト指向とは別物だっちゅ〜の!
やっても〜た〜^^; 誤爆ごめん m(_ _)m
きもいな
ネタ切れみたいなのでお題を提供します。 リスト内の任意のシンボルに対して、unquote付加を自動的に行いたい という要件が発生しました。 以下の様なただのリストの入力に対し、指定したシンボル全てにunquoteを付加し、 擬似リストとして返す関数quotifyを実装してください。 ただし、リスト内のlambda文の変数スコープ規則を解釈する事。 書式: (quotify <unquoteしたいシンボルを列挙したリスト> <入力リスト>) 呼び出し例: (quotify '(proc list) '((lambda (f r rr list) (while (pair? list) (set! rr (cons (proc (car list)) '())) (if (pair? f) (set! r (set-cdr! r rr)) (set! r (set! f rr))) (set! list (cdr list))) f) '() '() '() list))) 期待する出力結果: `((lambda (f r rr list) (while (pair? list) (set! rr (cons (,proc (car list)) '())) (if (pair? f) (set! r (set-cdr! r rr)) (set! r (set! f rr))) (set! list (cdr list))) f) '() '() '() ,list) つまり、この出力をそのまま実行するとunquote部分がカレント環境で変換されます。 上の例の変数listの様にきちんとlambdaの中と外を区別する必要があります。 ただの変換なら簡単ですが、lambdaの解釈で多少複雑になると思います。
マクロによってシンボルが束縛変数になるかどうか判定するのが不可能っぽい気がする。
使う処理系によっては比較的簡単かもしれないな。 たとえばchez(petite)なら (sc-expand '(let ((x 1)) (let ((y 1)) (+ x y) (proc list)))) --> ((lambda (#{x |?dp~%SaUTn<X\\*|}) ((lambda (#{y |?dp~%SaUTn<X\\+|}) (+ #{x |?dp~%SaUTn<X\\*|} #{y |?dp~%SaUTn<X\\+|}) (proc list)) 1)) 1) てな感じだから >lambda文の変数スコープ規則 ってやつは考えなくて良くなるような気がする。 ただ、sc-expandはquotifyマクロの展開中に使われてもトップレベルで展開してしまうので。 (let ((expr (quotify '(...) '(...)))) (expr ...)) みたいなやつはどうなるかな? 実験してみたいが、時間がないので直感だけですまね。
あ、そうそう >関数quotify ってあるけど、quotifyが`(,proc ,list)みたいなものを返したとしても、これを評価するにはevalしないといけないと思うのだが、それは意図した事だろうか?それともquotifyマクロの書き間違いかな?
返ってきた結果をそのまま評価するわけじゃないのかも。 他の macro から呼び出して使うとか。 # macro だから Schemer は syntax-rules で書くこと、とか言われたら一気に大変になりそうだし。 特定の symbol を置き換えてくような処理は、 ELisp だと CL package の lexical-let 辺りが似たようなことをしてるね。 私も簡易名前空間作ろうとして、そんな感じのコード書いたことあるし。
>>18 入力はマクロ構文等が全て展開された後のリスト、ということにしておいてください。
lambdaに対応しとけば他に応用もできると思いますので。
これ考えたときはlambdaに渡される引数を与えてquotifyを呼び、
結果をevalだけでα変換できるというのがありでしたが、
unquoteする代わりに直接置換リストを与えても良かったかもしれません。
>>19 たぶんそのsc-expandの名前付け替えと同じことをします。
例えばquotifyの応用で簡単なインライン展開処理が書けると思います。
((lambda (x) ((lambda (y) (+ x y) (proc list)) 1)) 1)なら
((lambda (x) ... ) 1)という並びに注目し (quotify '(x) '((lambda (y) (+ x y) (proc list)) 1)) => `((lambda (y) (+ ,x y) (proc list)) 1)
この結果からさらに
((lambda (y) ... ) 1)という並びに注目し (quotify '(y) '((+ ,x y) (proc list))) => `((+ ,x ,y) (proc list))
という感じでquotifyを再帰的に適用してx=1 y=1の環境でevalすると
((+ 1 1) (proc list))というシーケンスが得られます。
ただしこの変換はxやyが変数や定数の場合に限定されます。
(もしxが呼び出しだったら意味が変わってしまうので。)
>>20 マクロを書け、となるとschemeではややこしくなるので、
ただのリスト変換関数ということにしておいてください。
要は任意のシンボルにタグ付けするということです。
こっちで用意した解答は週末ぐらいに貼り付けます。
このままでもサンプルが変換できる程度の作ってみた。 こんな感じでよいのかな? もうちょっとちゃんとしたやつは時間がないから今は書けん。 このままでは(lamda arg ...)とか(lamda (arg . rest) ...)とかはだめだよん。 (define quotify-rest (lambda (ids vars expr) (if (pair? expr) (cons (quotify-head ids vars (car expr)) (quotify-rest ids vars (cdr expr))) expr))) (define quotify-head (lambda (ids vars expr) (if (pair? expr) (cond ((eq? (car expr) 'lambda) (list 'lambda (cadr expr) (quotify-head ids (append (cadr expr) vars) (caddr expr)))) (else (cons (quotify-head ids vars (car expr)) (quotify-rest ids vars (cdr expr))))) (if (and (memq expr ids) (not (memq expr vars))) (list 'unquote expr) expr)))) (define quotify (lambda (ids expr) (list 'quasiquote (quotify-head ids '() expr))))
いかーん間違えとる(涙
これでいいと思う (define quotify-rest (lambda (ids vars expr) (if (pair? expr) (cons (quotify-head ids vars (car expr)) (quotify-rest ids vars (cdr expr))) expr))) (define quotify-head (lambda (ids vars expr) (if (pair? expr) (cond ((eq? (car expr) 'lambda) (list 'lambda (cadr expr) (quotify-head ids (append (cadr expr) vars) (cddr expr)))) (else (cons (quotify-head ids vars (car expr)) (quotify-rest ids vars (cdr expr))))) (if (and (memq expr ids) (not (memq expr vars))) (list 'unquote expr) expr)))) (define quotify (lambda (ids expr) (list 'quasiquote (quotify-head ids '() expr))))
(quotify '(x) '(lambda (x) (quote x))) にはどういう出力を期待しますか?
あ、おれも質問 (quotify '(x) '((lambda (x) (display x)) '(lambda (x y) (+ x y))) で後ろのquoteされたlambdaのxの方もシャドウする?
>>23 可変引数はあまり本質的ではないと思いますので
省略でも良いです。
>>26 その場合の出力は
=> `(lambda (x) 'x)
ということで変化なしです。
あと書き忘れましたが、正当なlambda関数かどうかの判定は
リストのcarがシンボルlambdaの場合のみです。
(a b c lambda ...) の様なリストは関数とみなしません。
(lambda <引数リスト> ... )で始まるリストのみとします。
>>27 考えてませんでした。
その例ではたまたま結果は変わりませんが、
=> `((lambda (x) (display x)) '(lambda (x y) (+ x y)))
つまり入力リスト内にquoteがあっても特別な解釈は不要です。
quoteタグリスト内でlambdaが出現したら他と同じ様に解釈してください。
あまり凝った実装しても逆に使いにくくなると思うので。
えーと、Schemeの場合だと、 '((lambda (lambda) (lambda (a b) (list a b))) list) みたいな入力リストがあったら、3番目のlambdaは束縛変数になる わけだが、それはどうしよう。 出題者はLisp-2を考えてるみたいだから考えなくてもいいんかな。
>>29 うむむ、それも考えてませんでした。
今回はその判別は任意ですね。
より完全さを目指したい人はやってみてください。
こんどはちゃんとできてるつもりでふ (define quotify-iter (lambda (ids vars expr head) (if (pair? expr) (if (and head (eq? (car expr) 'lambda)) (append (list 'lambda (cadr expr)) (quotify-iter ids (append (cadr expr) vars) (cddr expr) #t)) (cons (quotify-iter ids vars (car expr) #t) (quotify-iter ids vars (cdr expr) #f))) (if (and (memq expr ids) (not (memq expr vars))) (list 'unquote expr) expr)))) (define quotify (lambda (ids expr) (list 'quasiquote (quotify-iter ids '() expr #t)))) (quotify '(a) '((lambda (x y a) (+ x y a)) (a b c))) -->`((lambda (x y a) (+ x y a)) (,a b c)) (quotify '(a) '((lambda (x y a) (+ x lambda a)) (a b c))) -->`((lambda (x y a) (+ x lambda a)) (,a b c)) (quotify '(a b) '((lambda (x a b c) (x a b c)) ((lambda (a) (+ a b)) x a b))) --> `((lambda (x a b c) (x a b c)) ((lambda (a) (+ a ,b)) x ,a ,b)) (quotify '(a b c) '((lambda (x c) (list a b c)) '(1 2 3 . c))) --> `((lambda (x c) (list ,a ,b c)) '(1 2 3 . ,c)) どかな?
和田さん並だ
36 :
デフォルトの名無しさん :04/11/20 22:07:19
Lisp 関係の文書で和訳やってほしいのって何かある? 暇だったら訳してあげる。
38 :
デフォルトの名無しさん :04/11/20 23:41:19
>>36 AMOP
SICPは平易な英語なので、英語の勉強ついでに読むのが良いと思った。
GNU Clispのソース内にいまだに残るドイツ語を英語に直すと喜ばれそう.
では忘れないうちに解答を貼り付けておきます。
>>23 さんご参加ありがとうございました。
ほぼ同じ内容になってしまったので可変引数と
>>29 のケースに対応してみました。
(define (quotify unqlist x)
(define (last-cdr x)
(if (pair? x) (last-cdr (cdr x)) x))
(define (dotlist->list x)
(let ((r (last-cdr x)))
(if (null? r) x (reverse! (cons r (reverse x))))))
(define (seq x vars)
(if (pair? x)
(cons (q (car x) vars) (seq (cdr x) vars))
(q x vars)))
(define (q x vars)
(if (pair? x)
(cond
((and (not (memq (car x) vars)) (eq? (car x) 'lambda)) ;;
>>29 のケース
(list*
'lambda
(cadr x)
(seq (cddr x)
(append (dotlist->list (cadr x)) vars)))) ;; 可変引数
(else
(seq x vars)))
(if (and (not (memq x vars))
(memq x unqlist))
(list 'unquote x)
x)))
(list 'quasiquote (q x '())))
seq要らないしdotlist->listが(reverse x)で動かんだろ。
letは無視していいの?
LispでJAVA+tomcatみたいなことは出来ないですか? lispなら掲示板作るのが楽そうなので。
>>41 seqは例えば(a b c lambda ... )というリストに引っかかるのを防ぐため、
リストの頭にあるかどうかを区別するために必要です。(
>>28 )
>>23 さんのコードでもseq相当をheadというフラグで処理しています。
それとdotlist->listが動かないという意味がわかりませんでした。
試した処理系など、もう少し詳細を教えてください。
Scheme的には大丈夫だとは思っておりますが。
>>42 let等はマクロとして展開可能なのでlambdaだけにしました。(
>>22 )
JAVA+tomcatで作れば?
>>43 cgiじゃだめなのか?
どうしてもサーブレットを使いたいならkawa + tomcatでできるかも
javaで実装したschemeとtomcat組み合わせたりできない? できたらノウハウ公開して欲しい、かも。
49 :
デフォルトの名無しさん :04/11/21 23:48:20
>46 CGI? LISPでどうやってCGIをやるのですか? 当方LISP初心者ですが、LISPでCGIできるのなら やりたいです。windowsでも出来ますか??
ちょいちょい調べたらAllegroServeなるものが出てきた。 これがtomcatの代わりになるのだろうか??
CGIなんて標準入出力さえあればなんだってできるだろが
たとえばアパッチとかでできますか??
知障は普通にapache動かしてperlなりなんなりで書いてみて、CGIとは 何かを知るところから始めれ。
>53 お前が知障。死ね そしてオヤスミ♪
55 :
デフォルトの名無しさん :04/11/22 00:30:02
一応あげとく
既出だが普通に aserve+webaction で良いだろ あ、 apache は別にいらないから念のため
>>44 (reverse '(a . b))
がSCMじゃエラーだな。
58 :
デフォルトの名無しさん :04/11/22 02:14:40
Paul Graham, ANSI Common Lisp の練習問題の解答を載せた ホームページ等、ご存知でしたら教えていただけませんでしょうか。
Gauche MinGW盤が出たね。
>>58 「"ANSI Common Lisp" 練習問題 解答」でぐぐれ。
……出てこないね。漏れの使ってるYahooだとそれっぽいの出るんで試してみれ。
>>59 あ、ほんとだ。Bugsに報告されて重い腰を上げたのかな? (・∀・)
61 :
デフォルトの名無しさん :04/11/22 09:06:43
LispじゃなくてSchemeだけど、ふつうにGaucheをインストールして CGIできてますよ。
63 :
デフォルトの名無しさん :04/11/22 15:55:04
`,age
64 :
デフォルトの名無しさん :04/11/22 20:32:07
(このスレ的に)ごく身近にWilikiというのがあるじゃないか LISPのWikiって他にあるかなあ?
65 :
デフォルトの名無しさん :04/11/22 20:47:36
tomcatみたいなやつっていうのであればKahuaが...
66 :
デフォルトの名無しさん :04/11/23 03:16:43
Common Lispで数値式からなる通常の書式(中間記法)の四則演算式を受け取って、 その計算を行う関数を作りたいのですが、四則演算やカッコの優先順位付けに かなり苦戦しています。一応再帰でカッコを順にはずす関数を作ってはみたんですが・・・ (defun flat (x) (calc (cond ((null x) NIL) ((atom x) x) ((atom (car x)) (cons (car x) (flat (cdr x)))) (T (append (flat (car x)) (flat (cdr x)))) ) ) ) 実際に計算するcalc関数ができない上、この方法だと実装不可能なような気も。 どなたか別なアプローチで組める方いませんか? 【入力】 【期待する出力結果】 (calculate '(1 + 2)) → 3 (calculate '(1 + 2 * 3)) → 7 (calculate '(1 + 2 * (3 + 2)))→ 11
>>66 普通に左から右に読んでくだけだと思うけど
難しく考えすぎじゃないかな
優先順位の括弧とリストの括弧ごっちゃにしてる気がする
LISPでやるとしたら
中置記法→LISPの前置記法に直してevalするだけ
(1 + 2 * (3 + 2))なら(+ 1 (* 2 (+ 3 2)))に変換してeval → 11
前にEmacsLispで書いた記憶があるな。 普通かっこの部分はcalculateに渡して再帰させるんじゃない?
>>67 >>(1 + 2 * (3 + 2))なら(+ 1 (* 2 (+ 3 2)))に変換してeval → 11
おっしゃる通りです。
再帰で階層をどんどん潜らせて、リストの中のリストに含まれる演算子を捜して、
「×」を見つけたらその前後を含めてリストを作らせるというようなことをやりたいのですが、
ソースがどうもわからなくて。
友人がlengthを使って要素数を判定させながらひたすら二項演算のカッコ(←つまりリストの中のリスト)を
作る方法はどうだと言ってましたが、それもコーディングがよくわかりません・・・。
>>68 calculateはこの場合flatを呼び出す再帰のときに実行されると思うのですが、
全く的はずれなことをしているのでしょうか・・・?
どこでflatを使うの? 優先順位がめちゃくちゃになるよ。 足し算、引き算にぶつかるまでずっとたどっていけばいい。 で繰り返して使う。
>>69 こんなかんじでできるのでは。
例: '(1 + 2 * 3 / 4 - 3)
;とりあえず最初の二項を。
'(+ 1 2)
* ;+より強いので第二引数を書き換え。
'(+ 1 (* 2 3))
/ ;+より強いので第二引数を書き換え。
;/は*と同じなので(* 2 3)の外側に。
'(+ 1 (/ (* 2 3) 4))
- ;+と同じなので外側に。
'(- (+ 1 (/ (* 2 3) 4)) 3)
>>70 考え方としてはflatはリストの中のリストの()の中身を計算して
その後にカッコをはずすという関数にしたかったのですが、
現段階では確かに計算順序がくずれるかも・・・。
つまり式のカッコははずさずに演算子に注目する
>>71 さんと同じ考え方でしょうか?
>>71 丁寧な説明ありがとうございます!これは入力されたリストAとは別に新しくリストの変数Bを宣言して、
Aを見ながら、Bにどんどん上書き更新していくという感じでしょうか?
そうすると再帰的な関数で組めるかかなり不安です(´・ω・`)
こんなんでどお? (define operator-prec-alist '((* 20) (/ 20) (+ 10) (- 10))) (cadr (assq '+ operator-prec-alist)) (define (compare-operators-by-precedence comp op1 op2) (comp (cadr (assq op1 operator-prec-alist)) (cadr (assq op2 operator-prec-alist)))) (define (parse exp) (cond ((not (list? exp)) exp) ((= (length exp) 1) (car exp)) (else (parse-op (parse (list-ref exp 0)) (cdr exp)))))
続き。 (define (parse-op arg1 restexp) (let ((op1 (list-ref restexp 0))) (cond ((= (length restexp) 2) (list op1 arg1 (parse (list-ref restexp 1)))) (else (let ((op2 (list-ref restexp 2))) (if (compare-operators-by-precedence < op1 op2) ; eg. op1=+, op2=* (list op1 arg1 (parse (list-tail restexp 1))) (parse-op (list op1 arg1 (parse (list-ref restexp 1))) (list-tail restexp 2))))))))
Emacsのバッファから直接貼ったのでゴミが入っちゃった。
>>73 > (cadr (assq '+ operator-prec-alist))
これは無視してください。
>>72 > そうすると再帰的な関数で組めるかかなり不安です(´・ω・`)
簡単に書けるよ。二変数A, Bを取る末尾再帰の関数で、
f (A:入力リスト) (B:空リスト) で呼び出して、
で入力Aを削りつつ、Bを書き換えていって、Aが無くなったらBをかえす。
>>73-75 ちょっと知らない命令(cadr assq parse等)が多い感じなので勉強しながら
読み解いてみたいと思います。Common Lisp ・・・ですよね?
関数定義の仕方が微妙に違うのはLispから派生した言語とかだからでしょうか?
一応自分はxyzzyとemacsを併用して考えております(;´Д`)
>>76 末尾再帰は一度調べたことあるのでもっかいググってきます!
希望の光が見えてきた(ノ∀`)
>>73 さんのはscheme
安直で冗長だが
* or / が出てきたら前後の項をあわせて括弧でくくる
というやり方でもいける
(defun sub (exp)
(cond ((atom exp) exp)
((case (length exp)
(1 (sub (car exp)))
(3 (cons (cadr exp) (list (sub (car exp)) (sub (caddr exp)))))
(t (case (cadr exp)
((* /) (sub (cons (list (car exp) (cadr exp) (caddr exp)) (cdddr exp))))
((+ -) (list (cadr exp) (sub (car exp)) (sub (cddr exp))))))))))
(defun calculate (exp) (let ((stack '())) (while (consp exp) (if (memq (car exp) '(* /)) (setq stack (cons (funcall (car exp) (calc (car stack)) (calc (cadr exp))) (cdr stack)) exp (cddr exp)) (setq stack (cons (car exp) stack) exp (cdr exp)))) (while (consp stack) (if (memq (car stack) '(+ -)) (setq exp (funcall (car stack) (cadr stack) exp) stack (cddr stack)) (setq exp (car stack) stack (cdr stack)))) exp))
(if (memq (car exp) '(* /)) (setq stack (cons (funcall (car exp) (calc (car stack)) (calc (cadr exp))) (cdr stack)) は (if (memq (car exp) '(* /)) (setq stack (cons (funcall (car exp) (calculate (car stack)) (calculate (cadr exp))) (cdr stack))
(if (memq (car stack) '(+ -)) (setq exp (funcall (car stack) (cadr stack) exp) は (if (memq (car stack) '(+ -)) (setq exp (funcall (car stack) (culculate (cadr stack)) (culculate exp))
間違いが多くてすみません。 無駄なcalculateの再帰が多くてすみません。 (defun calculate (exp) (let ((stack '())) (while (consp exp) (if (memq (car exp) '(* /)) (setq stack (cons (funcall (car exp) (calculate (car stack)) (calculate (cadr exp))) (cdr stack)) exp (cddr exp)) (setq stack (cons (car exp) stack) exp (cdr exp)))) (while (consp stack) (if (memq (car stack) '(+ -)) (setq exp (funcall (car stack) (calculate (cadr stack)) exp) stack (cddr stack)) (setq exp (calculate (car stack)) stack (cdr stack)))) exp))
(defun calculate (exp) (let ((stack '())) (while (consp exp) (if (memq (car exp) '(* /)) (setq stack (cons (funcall (car exp) (car stack) (calculate (cadr exp))) (cdr stack)) exp (cddr exp)) (setq stack (cons (if (consp (car exp)) (calculate (car exp)) (car exp)) stack) exp (cdr exp)))) (while (consp stack) (if (memq (car stack) '(+ -)) (setq exp (funcall (car stack) (cadr stack) exp) stack (cddr stack)) (setq exp (car stack) stack (cdr stack)))) exp))
funcallをlistに変えたら前置記法になりそうだな。
問題投下 #'consを作れ。 carとcdrは使って良い。 それ以外はとくに指定しないけど、#'consと同等の機能を果たすもの、高階関数などは当然不可。 実はANSI Common Lisp3章の問題にあります。
listは使えんの?
(defun cons (a b) `(,a . ,b))
(defun cons (a b) (append (list a) b))
(defun cons (&rest a) (rplacd a (car (cdr a))) a)
ああそうか、どこからconsセルを持ってくるかと思っていたが、 引数リストのを使うわけか。
ACLのGUI環境の使い方を載せてあるHPとかってありませんか。
数値が書かれた空白区切りの文字列 (UNIX で言うレコード) は, (multiple-value-bind (read-from-string ...) ...) で読むより (let ((s (make-string-input-stream ...))) で (read s) した方が速いんですね.cmucl でしか試していませんが. 常にこうなるものですか? stream を作るって大した仕事じゃないのかな?
フィールドの数によったりしないかね。 多値ってのはそんなに多くの数を想定してるわけじゃないから。
>>78 ソースありがとうございます!これなら何とかわかりそうです!
実装できたので後は後半部分を読み解いてみます。
>>79 残念ながら課題です・・・。
>>80-84 ソースありがとうございます!xyzzyで実行したのですが、memqで怒られました。
シンボルの一致のeqlのことでしょうか?そこを変えて実行したら以下のようになりました。
まだスタックが使えないのでエラーの原因がわかりませんが・・・。
(calculate '(1 + 2 * 3 + (43 - 3))) → 1
>>96 (defun memq (item list)
(member item list :test #'eq))
Dr.SchemeのLisp版みたいなのってありませんかね?
>98 XYZZY
emacs の lisp-mode がもっと見やすくなる設定 or elisp を教えてください. mapcar が見辛いという理由で loop の collect を使ってしまいます. 他にもエディタに助けてもらいたいことがいろいろあります (失念). それと,みなさんの (format t str ...) の str の書き方が知りたいです. これが長い場合,C 言語みたいに "abc" "def" <===> "abcdef" になれば 次の行に書くことができますが,そうはいかないので どうしたものかと思っています. コーディングスタイル tips のサイトがあればいいのですが...
>66 あいにくSchemeしか知らんのでSchemeですまぬ (define transform-1 (lambda (head rest) (if (null? rest) (transform head) (case (car rest) ((+ -) (list (car rest) (transform head) (transform-1 (cadr rest) (cddr rest)))) ((* /) (transform-1 (list (car rest) (transform head) (transform (cadr rest))) (cddr rest))) (else 'syntax-error)))))) (define transform (lambda (expr) (if (and (pair? expr) (not (memq (car expr) '(+ - * /)))) (transform-1 (car expr) (cdr expr)) expr))) (define calc (lambda (expr) (eval (transform expr))))
結果 (calc '(((1 + 2) - 6) * 3 )) == -9 (calc '(1 + 2 * 3 + (43 - 3))) == 47 (calc '(1 + 2 * (3 + 2)) ==> 11
だ〜またまちがえた 9行目の (transform-1 (cadr rest) (cddr rest)))) は (transform (cdr rest)))) だった
最初からheadはtransformしといたら?
>>104 むむ、おぬしなかなかできるな(笑
(define transform-1
(lambda (head rest)
(if (null? rest)
head
(case (car rest)
((+ -) (list
(car rest)
head
(transform (cdr rest))))
((* /) (transform-1
(list
(car rest)
head
(transform (cadr rest)))
(cddr rest)))
(else 'syntax-error))))))
(define transform
(lambda (expr)
(if (and (pair? expr) (not (memq (car expr) '(+ - * /))))
(transform-1 (transform (car expr)) (cdr expr))
expr)))
(define calc
(lambda (expr)
(eval (transform expr))))
こうか?
(not (memq (car expr) '(+ - * /)) もいらないだろ。 一回変換したやつを省いているだけだろ。
107 :
66 :04/11/25 01:34:30
>>97 >>101-103 丁寧にありがとうございます!
Schemeはまだ守備範囲外なのでソースとっておいて勉強します!
逆ポーランド記法に基づいて計算をする関数を
同じくCommon Lispで今考えているのですが、
スタックを使わなくてできる方法ってないですか?
リストでできるらしいのですが・・・。
リストをスタック代わりに使う。
リストでスタック実現すればいいのでは?
>>106 ほんとだ、それもいらなくなるね〜
勉強になりました m(_ _)m
>>100 format文字列が長くなるときは
(format t "abc~
def~
ghi")
みたいに書いたりするね。(表示は"abcdefghi"、インデント部分は消える)。
エディタのautoindentが効かないのがちょっとアレだけど。
(format t "abc~ def") >> abcdef =>> nil
代入とかの右結合の演算子も対応して '(a := b := 1 + 2 + (c := 3)) => (:= a (:= b (+ 1 2 (:= c 3)))) (:= c 3)はschemeなら(begin (set! c 3) c)という感じのマクロつーことで
>>111 知らなかった...
format の書式は膨大だなぁ.
これを elisp の lisp-mode がサポートしてくれないだろうか.
(setf *my-hand* '((king hearts) (3 spades) (7 spades) (jack diamonds) (ace clubs))) トランプの種類(スーツ)を数える関数ってどうすればいいですか? (count-suit 'spades *my-hand*) -> 2
(define (count-suit x y) (do ((y (memq x (map cadr y)) (memq x y)) (n 0 (+ n 1))) ((not y) n)))
(define (count-suit x y) (length (apply append (map (lambda (z) (if (eq? (cadr z) x) (list x) '())) y))))
119 :
デフォルトの名無しさん :04/11/25 22:02:20
Scheme + srfi-1 (define (count-suit suit hand) (count (lambda (card) (eq? (cadr card) suit)) hand)) CL (defun count-suit (suit hand) (loop for card in hand count (eq (cadr card) suit)))
(define (count-suit x y) (apply + (map (lambda (z) (if (eq? (cadr z) x) 1 0)) y)))
素直に CL で書いたらこうじゃねーか? (defun count-suit (suit hand) (count suit hand :key #'second))
前の初心者スレはどうなったんだ?
PocketPC用のLispって無いですか?
127 :
ミミ :04/11/27 15:18:18
>>125 SCM は PocketPC に対応しているかも。
ソースコードにマクロ定義されていたし。
Pocket PC用のApacheとかEmacsとかPerl作ってる有名な人、 (確かドイツ人だったような) その人がなんか作ってたと思う。SCMかCLISPか忘れたけど。
PocketSchemeね。RSR4+αくらいの仕様で、Windows APIも叩けたはず。 サンプルデモにグラフィックスの表示とかあった。
↑誰か反論の書き込みしてきてくれんか? 反論:いや、なにより一番足りないのは「人気」だ・・・
(´・ω・`)ショボーン
前の CL スレではいろいろ書いてたけど,今度のはなんか荒れてるから近寄り難いな. Common Lisp にゃ規格には足りないけどライブラリや処理系独自拡張で大抵あるけどな. GUI : Tk (ltk), GTK (lambdaGTK), CLX, CL-SDL, OpenGL, CLIM, CAPI, Allegro の GUI ... cgi : AllegroServe, PortableAserve, WebActions, Araneida, CL-HTTPD, ... Win32 : スマン,Windows 良くしらん.FFI では駄目なん?商用処理系ならそれなりに サポートがあると思うけど… DB : 今なら CLSQL か?処理系によっては PostgreSQL, MySQL, Oracle, SQLite2/3 あたり へのインターフェースを備えているし つーかスレッドとかネットワーク API も処理系毎にバラバラだしなー.そんあ 欠点はわかっちゃいるけどね.止められないなぁ.
足りないものより充実してるものを挙げればいいのに。
>>136 それは欠点から目を逸らそうとしているだけにしか見えないのですが…。
入門だからまず得意な分野に目を向けさせるべきだ。
初心者だけど、正直reverseとかappendとかの関数を作っても、 なんも楽しくないよ。
作りたくなければ作らなければいい。
楽しくなければやらなければいい。
そしてまた一人、初心者が去っていった。
strcmpを作らせるC言語入門とかは最近の流行りでないしなぁ... まぁ記号微分でも書くのがいいんじゃないかと. でも正直,Lispでなければできないことって最近あまりない希ガス. 洩れはプロトタイピングだったらRubyで済ませることが多い. 現在,Lispでなければできないことといったら,on Lispで解説されたテクニックに代表される, マクロを駆使したメタプログラミング/プログラム変換/部分評価による大規模開発だよね. 「人間の扱い切れない複雑膨大なコードをLisp処理系に書かせる」みたいな. 入門者は普通やらないよな... 「構文に対する抽象化」ってのの存在を知るだけでも後々ご利益があるとは思うけど. Lispの普及度がある臨界を超えれば, 現在の様々な問題領域における標準的なDSL定義環境として重宝されると思うんだけどな... GUIしかりRDBしかりXML Webサービスしかり. Paul Grahamが言うには「ある言語が普及するには, クールなシステムの標準スクリプト言語としての位置づけが必要」だってさ. CはUnixのスクリプト言語だって.N88-Basicもそのクチかもね.
Common Lispにはcontinuationはないんでしょうか? 一応Hyperspecもつつきまわしてみましたが、載ってないので……。 continuationって他の言語(特にC++とか)と組み合わせるのを とっても難しくしてるように思うんですけど、そんなことないですかね?
一般のcontinuationはない. 脱出だけならブロックがあるからそれを使う. On Lispにはマクロとクロージャでcontinuationまがいを実装する話が載ってるけど,効率悪そう. C++の例外も他の言語と組み合わせるのにハードルだよね. ちょっと複雑な言語になればそう簡単に組み合わせるわけにはいかなくなるんじゃないかな.
Franzが監視してるに違いないACLのメーリングリストに 「オマエのACLフルバージョンくれよ」ってポストしてたバカが居たね。 商用処理系の割れ物を欲しがる奴が居るってことはまだ死んでないのかな。Lisp.
>>139 まぁ,そのへんは基本だから我慢してみてよ.動作を含めてあたりまえだと思えるよ
うになればいろいろ便利な事がある.reverse カンペキだと思ったら C 言語でリスト
構造とその reverse 処理を書いてみてください.
>>143 Lisp は(当時は比較的クールだった) Lisp マシンの標準スクリプト言語だったけ
ど普及しなかったじゃん….
悟りを開くまえに挫折する奴が多すぎるからだ
emacs がクールなシステムなら scheme が来るということですか.
150 :
デフォルトの名無しさん :04/12/01 01:39:44
Lisp で悟りを開いたかどうかを検査する方法ってある?
>>150 Lisp試験紙を口につっこんでみて、Lispの文字が浮き上がってきたら悟ってる。
>>147 その「いろいろ便利な事」を先に教えてあげればやる気が出るんじゃない?
>>143 Lispマシン自体の「普及」が限られていたからね…
Lispマシン業界にSUNが出現しなかったことが不幸だったのかな。
PC-8801のROMにN88-LISPが入ってたら普及してたかもね
FM7のROMにF-LISPが入ってたら普及してたかもね
MZ80にSHARP-LISPのテープが付いてたら普及してたかもね
ファミコンで、ファミリーLISPが出てたら
マイクロソフトが悪いのかい?
ビル・ゲイツとポール・アレンが売り出したのが Lisp だったら、 VB の代わりの Visual Lisp が厨房向け言語になってただろう。 Common Lisp は Microsoft の横槍によってもっとグダグダになり、 Allegro 等の ISV はすでに生き残ってないかも。
MacのかわりにEmacsをパクって出来たEmacs NTがUnixとの統一を実現する。
IBMあたりがEclipse+Groovyでそれを狙っているような気がしなくもない
IPLって現存する?
この4月から、SICPにてSchemeを習い始めたものなんですが、 プログラムを書いたところ、エラーがでて、その原因をお伺いしたかったのですが、このスレでよかったでしょうか? SICP 問題1.37 連分数展開の問題 ”コード” (define (cont-frac n d k) (define denom (d k));分母 (define numer (n k));分子 (define (cont-fraction p) (if(> p 1) ((set! denom (+ (d (- p 1)) (/ numer denom))) (set! numer (n (- p 1))) (cont-fraction (- p 1))) )) (cont-fraction k) (/ numer denom) ) ”入力” (cont-frac (lambda(i) 1.0) (lambda(i) 1.0) 10) ”エラー” procedure application: expected procedure, given: #<void>; arguments were: #<void> #<void> ”環境” Dr.scheme
ifの下、(set!...) の前にbeginが要るんじゃないの。
>>164 と結論は同じなんだけど、
>>163 はまだLisp(Scheme)のカッコの意味が
分かっていないと思われ。
補足すると、Schemeインタープリタはリストの最左端を手続きとみなすが、
((set! denom (+ (d (- p 1)) (/ numer denom)))
(set! numer (n (- p 1)))
(cont-fraction (- p 1)))
というリストの最左端は (set! denom (+ (d (- p 1)) (/ numer denom)))
という式になっていて、それが返す値が #<void> だ、ということ。
もしこれが何かの手続きを返すのなら意味があるだろうけど、ここでは
それは意図していることではない。
(+ 1 1)
に対して、
(let ((plus +))
(plus 1 1))
とか、
((if #t +) 1 1)
とか、
((lambda (a b) (+ a b)) 1 1)
とかを比べてみればいい。
(define (cont-frac n d k) (define (cont-fraction p denom numer) (if (> p 1) (cont-fraction (- p 1) (+ (d (- p 1)) (/ numer denom)) (n (- p 1))) (/ numer denom))) (cont-fraction k (d k) (n k)))
167 :
デフォルトの名無しさん :04/12/05 17:31:40
The Art of the Metaobject Protocol ってフリーで入手できませんか?
>163 >このスレでよかったでしょうか? 気味の悪い日本語やめろ。Schemeの前に日本語やれよ。
>>168 それね、京都のファミレスでウェイトレスがよく使う言葉だよ。
慣れるとどうってことないよ。
京都から出た事ない京都人が寝言言ってるが、 ちょっと前に全国の飲食店のバイトが良く使う間違った敬語として有名だ
>>169 なれればシンタックスエラーも気にならないってか。
京都人の神経はわからん。
>>170 は根拠なしに「間違った敬語」と言っている。
それが正しいことである根拠を示せ。(有名というのは根拠に非ず)
>173 そういうのが説明されないとわからないのはまずいと思うよ
>>172 一般的なコンパイラが出すsyntax errorと同様に考えてはいけない。
それは即失敗していることを意味するが、自然言語の場合は自分が普段使っている
言語の表現と違った表現をしていたとしても、それは誤りではない。
現にその表現を使っているシーンを何度も見ている人はその表現の意味を理解できる。
私には
>>172 の神経は解かるよ。一般的なコンパイラと人を同一視してしまっている
んだ。
>>175 説明できないから、相手の能力を否定することで説明逃れをするつもりか?
低能だな。
178 :
デフォルトの名無しさん :04/12/05 19:40:58
179 :
デフォルトの名無しさん :04/12/05 19:41:58
>176 自然言語は意味が通じるからといってそれだけで問題無しとしてはいけない。 プログラミング言語のように技術的な便益だけで考えてはいけないからね。
>>177 おまいはこのCommonLispスレで、
「質問されてもいない内容を、さも既に質問済みであって
これが二回目の問いであるかのように過去形で述べる事の
押付がましさの、本来敬語が持つべき敬意とか遠慮とかとの
相容れなさ云々」とか長々と聞きたいのか?
>>180 疑問に思った事は聞いておきたい。
それがスレタイと関係なくても問題はない。
なぜなら、スレタイはスレ内容を縛るものではないからだ。
>>168 -
日本語の進化は京都が最先端。そこから全国へ下っていく。
(gc)
さいたま
芹沢君
うざったい
自然言語でも誤りは誤りだろ。強力なエラー訂正が効くだけで。
つまり全てが誤りってことですね!
私の言っていることは間違いである
でLispWorksはどうなったのよ。 4.3のEnterprise Edition評価版ちろっと使った経験しかないから漏れからなんとも。 いまこれが動かせればACL 7.0リリース版とベンチ採って比較したりできたんだけどな。
>190 変わるのと変えるのは違うし 正しいものを正しいものと言い続ける事は大切だ 自然言語だろうと関数型言語だろうと
いいえ大切ではありません。
>>195 誰かが変えたと言わなくても変わるもの。
大昔の日本語と現在の日本語は誰かが変えたと言ったわけでもないのに変わっている。
そして、その変化に順応している。
正しいかどうかという問題ではない。
ただそこにあるということだけだよ。
それに、自然言語とコンピュータ言語の出自は全く異なっている。
こんなところで自然言語についての俺理論を展開したところで、一般の板で 見掛ける「友達のスーパーハカー」と同様、噴飯ものなんだよね。 ちゃんと議論したいのなら専用の板にいらっしゃい。
"Metaobject Protocol" でググると3番目に↓が見つかって,
ttp://www.lisp.org/mop/ んでここには
> The book The Art of the Metaobject Protocol, sometimes called the AMOP,
> includes the CLOS Metaobject Protocol specification as chapters 5 and 6.
> These chapters are reproduced here in hypertext.
とあるんだけど,
>>167 はここをもう見た上で「第1-4章がないのか?」と質問してるのかな?
>>199 そうです。全部読むことはできないのかなと。。
R5RSを読むと、errorの扱いについて何も書いてないんですが、 これはどうするかは実装まかせで例えば即座にabort()しちゃっても 許されるということでしょうか?
202 :
デフォルトの名無しさん :04/12/06 00:07:16
Lisp で関数を定義する場合、C と同じようにエラーコードを返す設計でよいのでしょうか? たとえば、JPEG ファイルをロードする関数 (jpeg-load filename) があるとして、 filename で指定されたファイルが存在しない、読み取れない、JPEG 形式でない、 などのエラーがあった場合、それぞれに対応するエラーコードを返すという設計が 一般的ですか?
(jpeg-load filename)した後どうしたいのかによると思う。 読み込んだJPEGファイルをオブジェクトとして操作する予定があるならクラスにして おいてloadメソッドを定義しておいて、メソッドの値をオブジェクトそのものにするか 失敗したらnilにするかしておくかな。状態を調べるのはスロットの値を覗け、と。 まぁ、アクセサ定義しとけばいいんだけど。 一般的とか正しい方法なんてのはあってないようなもんなんで、好きに書けばいいじゃん。
全文読める場所があるなら↑からリンクの一つや二つ張られていそうなもんだけど < AMOP まぁ何だ,買え(ぉ # 1-4章はチュートリアルらしいね
>>201 そうです。abort()したって、ランダムな値を返したって、「R5RS準拠」と
名乗ることはできます。
それが本当に使える実装かどうかは別問題。
>>206 なるほど。ありがとうございました。
さすがにランダムな値を返す実装はそうはないと思いますけど、
プログラムカウンタがsemanticに正しくないコードにきてしまった時点で
そこから先は未定義になるってことでしょうか。
こう書くと杓子定規の最たるものみたいですが、
「お前は本当はこうしたいんだろ? こうに違いない! 俺にまかせとけ!」
てな具合に勝手に(必要ならコードを書き換えて)動作を続けていってくれるのも
R5RS準拠なのかもw
>>202 > Lisp で関数を定義する場合、C と同じようにエラーコードを返す設計でよいのでしょうか?
> たとえば、JPEG ファイルをロードする関数 (jpeg-load filename) があるとして、
> filename で指定されたファイルが存在しない、読み取れない、JPEG 形式でない、
> などのエラーがあった場合、それぞれに対応するエラーコードを返すという設計が
> 一般的ですか?
Common Lispが規定しているライブラリ的な関数の挙動を参考にすると、
エラーが発生した時、関数は、エラーコードを返すのではなく、error(というLisp Object)を
error関数で発信(signal)する。
プロトタイプ的にどんどん書くときは、
(error "file ~A is not in jpeg format." filename)
などとsimple errorを発信しておいて、後から仕上げをするときに、適切な
型のerrorを発信するようにする。
chezってscheme界のaclみたいなもん?
なんだ、Gauche-gtkってcygwinで動くじゃん
c.l.sでandはsyntaxだからapplyには渡せないね、ってのを見ました。 たしかこのスレか前スレあたりで似た話があったのを思い出したんだけど (そのときの結論はたしかguileだけ純インタプリタなので変態的に動作する)、 syntaxをfirst-class objectにしておいて、実行時にsyntaxがapplyされると evalが走るようにすればどうでしょうね。 もちろん引数は先に評価されちゃうわけだけど、それは覚悟の上ということで。 (apply and (list #t #f 何かの式)) とすると、「何かの式」は評価されてしまうが、 (eval (cons and (#t #f 「何かの式」の値))) と同義な動作をするというようにするのです。 goshだとsyntaxをapplicable objectにすればできると思うんですけど。 (define-method object-apply ((syntax <syntax>) . args) (eval (cons syntax args) (interaction-environment))) とかすればできるのかしら。でもやってみると無限ループに入ってしまいました。 object-applyが優先されちゃうんですかね。
(every values args) でいいじゃん (srfi-1) andに限らず引数先に評価していいなら普通に高階関数化できるでしょ
(not (memq #f (list #t #f 何かの式)))
(define (functional-and . function-list) (let loop ((l function-list) (r #t)) (cond ((null? l) r) (((car l)) => (lambda (x) (loop (cdr l) x))) (else #f)))) (functional-and) => #t (functional-and (lambda () 'a) (lambda () 'b)) => b (functional-and (lambda () 'a) (lambda () #f) (lambda () 'b)) => #f
意味が分からんが (define (functional-and . function-list) (or (null? function-list) (and ((car l)) (apply function-and (cdr function-list)))))
UNIXのシステムコールをそれなりに呼べる(select(2)とか)実装って なにがありますか? Common Lispだと CMUCL、Schemeだと Gaucheが良いんですが、 他にもあるでしょうか。
FFIつかえるならどれでも呼べるだろ。
いるんだよね. 単語だけ聞きかじって具体的なこと何も知らないのに知った風なこと言うヤシ. 自分は一度でもFFI使って意味のあるプログラム作ったことあんのかね.
具体的なことを何もいわない220も同罪だな。
>>218 記憶だと guile, scsh もオッケーのはず。他の処理系でもあったはず
だけど思い出せない。
>>219-223 ありがとございます。普段48使ってるんですが、scshがいけるとは盲点でした。
biglooは Serializationが面白そうな予感。
Scheme48で3.14秒のコードが scshだと69.16秒になってしまいますた。
226 :
デフォルトの名無しさん :04/12/10 23:05:30
>>222 bigloo よさげだよね。
でも Windows の GUI プログラム書ける?
>>226 ハァ?
UNIXのシステムコール呼びたいんじゃなかったの?
228 :
デフォルトの名無しさん :04/12/11 11:28:06
>>228 お、安いな。買いだ買い!
で、日本語通るのか?
230 :
デフォルトの名無しさん :04/12/13 00:28:19
金鯛焼きage
>>229 4.2 Personal版では通りました。(UNICODEですが、エディタとかもデフォルトで化けないで表示されます)
速度的にはどうか私も知りたいのですが、ACL7持ってませんです。
232 :
デフォルトの名無しさん :04/12/13 12:46:48
"The Little Schemer"を読んでいると、atom?が重要ということが わかりました。しかし、Gaucheにはないようなのですが、何か、 深い理由でもあるのでしょうか? 作るならこう? (define (atom? x) (and (not (pair? x))(not (null? x))))
空リストはアトム
define-syntaxってdefine-macroと違って書いたものがそのまま展開される と思うんですが、define-macroみたいにメタな場合分けってできないんでしょうか。 だとしたらパワーが全然違うと思うんですけど。
gauche には atom? じゃなくて 同じ機能の not-pair? があります。
>>231 Personal版をダウソしてみた。
時々出るダイアログが烈しくウザ!
>>231 LW4.3との比較であればBill Clementson's Blogにベンチマーク採ったの載ってるよ。
LW4.3からLW4.4でどの程度高速化されたか早く知りたい。買わないけど。
>>234 世の中にはdefine-syntaxだけでquasiquoteの展開を書く人もいるわけだが....(汗
やっぱりsyntax-caseかdefine-macroがないとつらいよね。
239 :
デフォルトの名無しさん :04/12/14 18:36:08
>>233 >>235 空リストはアトムなんですね。
ということで、not-pair? ってのでいいんですね。ありがとうございました。
schemeにatomは無いんじゃなかったっけ
atom 型ていうのはないですね、仕様上。 非共有性に基づいて型を定義している以上、当然ではあるけれども。
ACL7.0 EnterpriseがUS$99.00って・・・学生ウラヤマスィ。 研究室遊びに行って後輩捕まえて代わりに買ってもらおうかな(w
>>242 学生じゃなくても個人ユースならその値段で売って欲しいぞ。
憶測だけど、完成したアプリはたぶん無制限に配布してはいけないのだろうな。
245 :
デフォルトの名無しさん :04/12/15 21:38:44
CLOSを常用してる人って、いるんですか? 同名のメソッドは引数を合わせないといけないので、 パッケージを分けたくない時は、javaとかでいう抽象クラス名みたいなものを プレフィクスに付けたりしないと名前が被りますよね。 メッセージ伝達モデルのほうが型ごとに名前空間を分離できるし、 タイプ量も減って手軽だと思うんですけど、 普段は、そういうオブジェクトシステムを使ってるって人いないですか?
>>245 >>同名のメソッドは引数を合わせないといけないので、
何言ってんのあんた。
247 :
デフォルトの名無しさん :04/12/15 23:47:36
>>246 パラメータリストを整合的にしないといけないということです。
メッセージ伝達モデルだと、関係の無いクラスで
同名の引数の数が違うメソッドが定義されていないかなどといったことは
気にしませんから、それがわずらわしく感じないかということを言いたかったのですが。
>>247 言いたいことがよく判らない。
簡単なものでいいから、具体例を出して説明して頂けないか。
お隣のスレの80ですか?
250 :
247 :04/12/16 01:54:47
構造体のメンバの参照でも同じことですが、 変数名 . 動詞or名詞 と普通のオブジェクト指向言語では書けるところが、 (パッケージ名:動詞 変数名) あるいは、 (型名-動詞or名詞 変数名) となって、タイプ量が増えて面倒だと言いたいだけです。 普通はパッケージ名は書かないのかもしれませんが、 複数のパッケージからインポートして、それぞれに整合的でないメソッドが 含まれている場合、シンボルのインポートを諦めるか、 メソッド名に基底クラス名等のプレフィクスを付けるか、 全く違う名前に変更してユニーク性を確保する羽目になります。 型の名前やパッケージ名が繰り返し書かれると、 情報の多重化になりますから、名前を変更する時も面倒です。 本当に複数の引数の型でディスパッチしたい状況というのは少なそうですから、 この負担が割りにあってるかは疑問です。 日常的に使いたくなるのはメッセージ伝達モデルの方であり、 総称関数を使いたい状況の方がむしろ特殊じゃないかと。 オブジェクトをキーワードやシンボルを引数に取るクロージャにして (funcall 変数名 '動詞) Schemeなら単に (変数名 '動詞) と書けるようなオブジェクトシステムを実装するのは簡単なので やってる人は結構いるんじゃないかと思ったのですが。 総称関数モデルとメッセージ伝達モデルのトレードオフくらい ここの人は分かってると思ったので、単に 「メッセージ伝達モデルの奴が欲しいんだけど、いいのない?」 みたいな聞き方でも充分通じると思ったのですが。
で、結局のところ何を聞きたいわけですか?
>>250 いや、だから具体例を出してくれはしないだろうか。
何で generic function の名前に型名をつける必要があるのか理解できない。
パッケージについても、まあ名前の衝突はありうるけれども、
それがメッセージ伝達型だと何で解消できるの?
それは総称関数モデルの問題じゃなくて、
Common Lisp のパッケージシステムの問題じゃなかろうか。
取りあえず、何というか、手続きの総称化ということについて
よく判っていないのではないかという印象を受けた。
ちなみにメッセージ伝達モデルの oo については
Paul Graham の"ANSI Common LIsp" で例題として実装している。
まあ、Common Lisp でわざわざ oo 実装するやつも少ないので、
Scheme の方で探して、気に入ったのがあったら移植でもしたらいいんじゃない?
CLOS like なのしか思い浮かばないんで、紹介は出来ないけど。
> 取りあえず、何というか、手続きの総称化ということについて > よく判っていないのではないかという印象を受けた。 俺も。何か気の毒だからちゃんと勉強して出直すことを期待。
型名をprefixにつけるなんて間抜けすぎ。最近ではOO界でもDuck Typingが 推奨されてるのに。
prefix が問題ではなくて、こんな感じにすると、 1番目の add と2番目の add の引数が違うのでだめじゃんってのが問題なんじゃない (defclass surface () ((poins :initform () :accessor points))) (defclass point () ((x :initarg :x :accessor x) (y :initarg :y :accessor y))) (defmethod add ((surface surface) (point point)) (push point (points surface))) (defmethod add ((surface surface) x y) (add surface (make-instance 'point :x x :y y)))
>>255 俺もその手の、同じ名前でラムダリストが違う場合を言いたいのだろうなと思った。
あと、それとは逆でラムダリストはたまたま合同になるけど、処理の内容が
ほとんど別のことを表しているときはどうだろう。なんとなく気持が悪くない?
パッケージで分割できればいいけど。
>>255 ん?
今 Common Lisp の処理系が手元にないので Gauche で試したけど、
それ、ちゃんと動くよ? CLOS だと駄目だったっけ?
CLOSはラムダリストが同じじゃないとダメ。 stklosとかgaucheは制限が緩い。 CLOSでだめなのは最適化かなんかの都合なの?
>>255 >>256 言いたいのはそういうことです。良い例をありがとうございます。
>>258 それは知りませんでした・・・
てっきり回避不可能に近い制限なのだろうと思ってたので。
その仕様だと、効率を除けばデメリットは無いですよね・・・
gaucheでいろいろ試してみます。
>>238 quasiquoteの展開ってこういうのじゃ駄目でしょうか?
(define-syntax qq
(syntax-rules (uq)
((_ ()) '())
((_ (uq a)) a)
((_ (a . b)) (cons (qq a) (qq b)))
((_ a) 'a)
))
理論上は define-syntaxでなんでも書けるらしいですね。
なにか面白いマクロネタありませんかね。
後 quasiquoteを使った quoteの定義 (define-syntax q (syntax-rules (uq) ((_ ()) (qq ())) ((_ (uq a)) (list (qq uq) (q a))) ((_ (a . b)) (cons (q a) (q b))) ((_ a) (qq a)) )) うーん、なんか見落してる気がする。
あ、unquoteの時は計算結果に置き変えないといけないんですか。 evalじゃないだろうし、どうやったらいいか想像できないです。 unquoteがマクロ展開時に計算されるっていうのは、処理系がマクロ展開時、実行時 の2ステップに分かれていれば意味あると思うんですけど、そうでない場合 なにか意味あるんでしょうか? 計算結果は変わらないですよね。
263 :
sage :04/12/18 14:50:19
こんな処理をする手続きrember* をつくりました。 (rember* 'b '(a b c (a b c))) => (a c (a c)) これをcall/ccを使った大域脱出させたいです。 (rember* 'b '(a b c END d (a b c)) => (a c END (a b c)) しかし下のコードでは希望する動きをしません。 => (rember* 'b (a c END (a c)) 下のコードをつかって、うまく脱出する方法はあるでしょうか? (define rember* (lambda (a l) (call/cc (lambda (escape) (cond ((null? l) '()) ((not-pair? (car l)) (cond ((eq? (car l) a) (rember* a (cdr l))) ((eq? (car l) 'END)(escape (cons 'END '()))) (else (cons (car l) (rember* a (cdr l)))))) (else (cons (rember* a (car l)) (rember* a (cdr l)))))))))
264 :
sage :04/12/18 14:53:28
>>263 見やすく書き込む方法はあるのでしょうか?
2ちゃんねる初心者です(^^;
それ以前に、仕様を明確に定義しろよ。 なんとなくは分かるが、前半の例と後半のコードが一致しないし、typo も多いし、 正しくはどうやりたいのかがみえない。
>>264 とりあえず、下げたいのなら、sageはメール欄に書こうな。
>>264 ` ' (半角スペース) を ` ' に置換する.
call/ccを使う必要ないんじゃ?
ENDは特別扱いなのか? 何がしたいのかわかんねえよヴォケ
>>263 説明不足でご迷惑かけました。改めて
手続きrember* a l は、リスト「l」から再帰的に「a」を除くものです。
(rember* 'b '(a b c (a b c) ((a) (b) (c))))
; -> (a c (a c) ((a)()(c)))
-------------------
(use srfi-1)
(define rember*
(lambda (a l)
(cond ((null? l) '())
((not-pair? (car l))
(cond ((eq? (car l) a)
(rember* a (cdr l)))
(else (cons (car l) (rember* a (cdr l))))))
(else (cons (rember* a (car l))
(rember* a (cdr l)))))))
>>270 実際にやりたい処理は次です。
『'END にぶつかったならば、処理を終了して、最後に"LAST" を付け
たリストを得る』
具体的には、下のような処理です。
(rember2* 'b '(a b c (a b c END d e) ((a) (b) (c))))
;-> (a c (a c "LAST") ((a) (b) (c)))
こういう処理は、270以外のやり方の方がいいのかもしれません。
ただ、270は「The Little Schemer」で紹介されている定石なので、
270から発展させた解決策をしりたいです。
アドバイスをお願いします。
PS
>>268 call/cc はいらないですね。ども。
>>271 下のrember2* では、....((a)(b)(c))) にはなりません。再帰がとまらないのです。
(rember2* 'b '(a b c (a b c END d e) ((a) (b) (c))))
;-> (a c (a c "LAST") ((a) () (c)))
(define rember2*
(lambda (a l)
(cond ((null? l) '())
((not-pair? (car l))
(cond ((eq? (car l) a)
(rember2* a (cdr l)))
((eq? (car l) 'END)
(cons "LAST" '()))
(else (cons (car l) (rember2* a (cdr l))))))
(else (cons (rember2* a (car l))
(rember2* a (cdr l)))))))
汚ないけど一応動くかも (define rember2* (lambda (a l) (letrec ((iter (lambda (a l c) (cond ((null? l) (c #t l)) ((not-pair? (car l)) (cond ((eq? (car l) a) (iter a (cdr l) c)) ((eq? (car l) 'END) (c #f '("LAST"))) (else (iter a (cdr l) (lambda (b ll) (c b (cons (car l) ll))))))) (else (iter a (car l) (lambda (b ll) (if b (c #t (cons ll (iter a (cdr l) (lambda (b l) l)))) (c #f (cons ll (cdr l))))))) )))) (iter a l (lambda (b l) l)) )))
長い行は (else (iter a (car l) (lambda (b ll) (c b (cons ll (if b (rember2* a (cdr l)) (cdr l))))))) の方が綺麗かな。
(define (rember* a l) (let loop ((l l) (cont (lambda (x) x)) (end (lambda (x) x))) (cond ((null? l) (cont l)) ((eq? (car l) a) (loop (cdr l) cont end)) ((eq? (car l) 'END) (end (list "LAST"))) ((list? (car l)) (loop (car l) (lambda (x) (loop (cdr l) (lambda (y) (cont (cons x y))) (lambda (y) (end (cons x y))))) (lambda (x) (end (cons x (cdr l)))))) (else (loop (cdr l) (lambda (x) (cont (cons (car l) x))) (lambda (x) (end (cons (car l) x))))))))
さいきんちらほらとム板スレで出てくるIoって言語は LISPの思想に近いらしく、基本はすべて object method(...) らしい。ただ、これとは別に演算子もある。 これはこれでかなりまとも(というか普通)な発想だと思う。 また、objectとmethodに対するありがちな.(ドット)連結を廃止して、 symbol symbolという並びをobject methodに簡略化した点でも評価できる。 methodの引数をそのまま関数引数形式にしたのもC/C++勢力にも受けると思う。 さて、 object method1(...) method2(...) とすればmethod1の結果のオブジェクトに対してmethod2を連鎖適用できる。 この書き方はC/C++でもほぼ同じだから馴染み深い。 LISP(Scheme)の関数は適用がいつも先頭引数という決まりなので (method2 (method1 object ...)) と、見た目の順序が逆になる。 ((object method1 ...) method2 ...) という風にも書けないことはないが、 細工をしない限り機能しない。(言い換えればLISPの一般的な書き方ではない。) ※ここでいう細工とは、マクロで専用インタフェースを書くか、 自分でメソッドディスパッチする必要があるという事。 ここで思うことは、主流のオブジェクト指向をする際、 この連鎖適用における順序の違いが思考の妨げになるのではないかということ。 今主流の言語は(関数型でさえも) object method形式だから、 LISP(Scheme)でやろうとする場合、専用の頭が必要になる。
そもそもオブジェクトとはどういう概念なのか説明してくれないか。
そこでArcですよ
ではIoの構文はどうか。 Ioではifなどの構文もメソッドであるという。 メソッドというからには何かのオブジェクトに従属するはずだが、 Ioでは暗黙のrootオブジェクト(Lobby)という概念を作ってカバーしたらしい。 例えばif式だと if(test_part, then_part, else_part) という書き方になる。 構文要素をカンマで区切る辺りが少し不気味な気がするが、 LISPの怒濤の括弧ほどショッキングではないのかもしれない。 ここで注目したいのは、Ioの構文はメソッドであるため、 どうやらマクロの様な特殊な機構は必要ないらしい。 ただし肝心の評価順序の制御がどういう原理で行われるのか正確には不明。 (thisMessage という機構でえらい騒ぎになるらしい) 構文に対する特殊化を先送りしているだけにすぎない様な気もするが、 表向きメソッドとして統一した事に意義があるのだと思う。 ただ、構文をメソッドとして定義するということは、マクロの様に展開する機会がなく、 毎回作成した専用構文の解釈を行うということになるので、 実行効率はかなり犠牲なるはず。 マクロ的な展開機構が導入されれば解決するのかもしれないが、 その辺はかなり道のり遠そうである。 この辺を追求していくとIoの雲行きが怪しくなってくる。 ともあれ、実用性や効率に目をつむればかなり洗練された言語であることは間違いない。
Ioスレでやれ
いや、別にIo使う気ないけど。 LISPでもシンプルなオブジェクト指向ってできねーのかなと思って。 似た言語の筈のIoと何が違うのかなって知識の整理。 要はIoの構文はマクロの代わりにメッセージという裏技でカバーってことね。 基本概念違うから(CLOS程大きいシステムならともかく)適用してもあんま旨みがない。
構文なんて些細な違いにすぎないんだが
>>282 おれは逆にえらい違いだと思ってるわけで。
object method1(...) method2(...)
に対して
(method2 (method1 object ...)...)
((object method1 ...) method2 ...)
やっぱ連鎖適用で括弧がネストするのは美しくないなと。
Ioでは現状おまけみたいなものだけど、
連鎖適用とメッセージを駆使すれば適当な構文が書けたりする。
if (test_part) then (then_part) else (else_part)
とか。
たぶんこれ遅いんだろうなあ。
ここは281のメモ帳じゃない。
数学で、f(g(x), h(y))っていう書き方があるでしょ、 これはLispの表記法と一緒だよね。おれはこの部分でLispに違和感を感じたことはない。
普通に(f (g x))と連鎖適用で括弧がネストするが?
CommonLispにloopみたいなオブジェクト指向用の汎用マクロ作ってもらえ。
いやそうだけど、括弧がネストするのが思考のさまたげにはなりにくいのでは ないかい? 算数や数学でこの表記法に慣れているから。
いや、数学の話じゃなくて、一般的になりつつある object methodの書式の話なわけで。 Ioの object method1(...) method2(...) はC++では object->method2()->method2() ね。 無理解を装ってるだけだろうけど。
上のC++の例は object->method1(...)->method2(...) の間違いね。 LISPの場合これぐらいならフロントエンド書けばおしまいだけどね。
いや、無理解を装っているわけじゃないよ。 object methodの書式の話だとして、 CLOSではメソッドが属すジェネリック関数が、普通の関数と同じ書式で呼び出せる ということに利点を感じて、(gf1 (gf2 obj0) (gf3 obj1))なんて感じの表記に したのでしょう。 それが主流から外れているというのなら、ふ〜んというしかないけど。 全般的に劣った表記体系かといえば、そうは思わないという話。
だらだら書く場合は、前に戻って関数挿入するのが面倒。 んで、その関数の引数について、こんどは右端までいかないと書けない。 これが主流のオブジェクト指向に向いてないという根拠の1つ。 数アクションぐらい余計に負担が掛かる。
そっ、それは…、エディタがなんとかするということで、妥協できませんか。 すまん、もうねるぽ。
>>292 そんな表面的な部分だけ取り上げて得意気になられてもなあ
どこが表面的なんだか。 根幹に関わる。
そのうちカッコを入力するのも面倒になり、 キーボードを打つのも面倒になるのだろうな。
それこそCでオブジェクト指向できると言い張るぐらい滑稽。
機械語でオブジェクト指向ってできないの?
やりたかったらやりなさいよ。 でもつまらないよ。
>>295 Lisp にとって、構文の問題は「表面的」なんだよ。
macro 書けば解決するから。
ごめん、へんなこと書いた。忘れて。
「o君、mしてね」というのだけが、オブジェクト指向じゃなかろうに、 「mしてね、o君」というのでも、オブジェクト指向なんじゃないの、 S式は、後者に適しているというだけなんじゃないの。
オブジェクト指向にするとどんな利点があるのか分からない。
>>302 o君、m1してね p1とp2で その後 m2してね p3とp4で
後でm2してね、最初にm1してね、o君、 p1とp2で ところでm2の件だけどp3とp4使ってね
わかりますか?
つまり 前者が object method1(p1, p2) method2(p3, p4) 後者が (method2 (method1 object p1 p2) p3 p4) なわけです。 後者は文章にするのも大変だということがわかりますか?
オブジェクト指向は幻想
後者の場合、methodが続くと大変なことになります。 最後にmnするんだけど、そのまえにmn-1してね、・・・ 最初にm1してね、o君、 m1の件はp1とp2で。 m2の件ではp3とp4、・・・ mnの件は・・・なんだっけ? 一般人の短期記憶スタックは6〜8ネストぐらいが限界だとどこかで読んだ事がありますが、 口頭で言われた場合、理解できるでしょうか。
>>306 当然ながらフロントエンドについては考えてるよ。
(define-syntax chain (syntax-rules () ((_ obj) obj) ((_ obj (m . args) . more) (chain (m obj . args) . more)))) (chain obj (method1 p1 p2) (method2 p3 p4))) -> (method2 (method1 obj p1 p2) p3 p4)
>>308 そんなにダラダラ書いたらどんな記法であろうと分かりにくくなるのは当然だろ
なんのためのインデント、なんのための一時変数、なんのための括弧、なんのt(ry
要はあんたが前置記法では分かりにくいってだけでしょ
あんたに理解しづらいからといって他の人もそうであるとは限らない
ネストが深くなるとインデントがつがつ入って 横長になっちゃって見辛い、てのはあるかなあ。 適当に切り分ければいいだけの話だけど。 でも、たとえばこんな感じの関数書けば、 (define cascade (lambda (x . fs) (fold (lambda (f knil) (f knil)) x fs))) こんな感じに書けるけれど、 (cascade (iota 10) (filter$ even?) (fold$ + 0)) => 20 ちょっとややこしいのになるとあんまり書きやすいと感じなかったなあ。 上記の、インデントの関係で読みやすくはあったけど。 どうしてかな、て考えてみると、自分の場合はまず、結局最後は何やるの? ていうのを考えて、それに渡す値はどうするの? 更にそれに渡す値は……みたいな感じの思考パターンで考えることが多いみたい。 元の値から結論に向って値を下げ渡していく感じじゃなくて、 最初に結論ありきでそれに向って差し戻していくイメージっていうか。上手く言えないけど。 実際のところ、最終的に何をしたいのかていうのは、 その途中の経路よりははっきりしていることが多いと思うので、 それをまず書いちゃって、それに渡す値を作るところは適当に副関数に切り分けておいて、 後からそれを別立てで書いたほうが思考の流れに沿って作業できないかなあ。 一方で充分にライブラリが揃っていて、後はそれを糊付けしていけばいい、 てところまで状態が整っているならば、obj->metha->methb->... みたいな書き方のほうが楽かもしれない。 結局のところ、問題の質や切り分け方で、 それに適った思考過程、対応するような記法は変わってくるだろうから、 どういう記法が優れているか、ていう単純な話ではなくて、 それぞれの記法はどのように問題を切り分けるのに向いているか、てことじゃないかなあ。
だらだら書いている間に話が進んでた。
>>304-305 後者について、generic function model で第一引数を
特別扱いするのがそもそも間違っている気がする。
(……なんか最近似たようなことを書いた記憶があるな)
message passing model に基づいて事象をモデル化したら、
message passing model に基づいた記法で書いたほうが素直になるのは当然でしょう。
そこで後者が文章にするのも大変て言われても、それはそうでしょうな、としか言えない。
無理にオブジェクトを人として扱うなら、
「o 君、p1 と p2 で」じゃなくて、「o1 君と o2 君と o3 君で」と考えた方がいい。
もっとも、それだと三人が一人になったり、
逆に(多値を返すような場合)一人が三人になったりして不気味だけど。
そういう意味じゃ、(例えば)オブジェクトを人としてモデル化したいような場合には
generic function model は確かに向いてないかもしれない。
でも、モデルなんて結局のところ問題把握のための道具でしかないんだから。
通用する範囲で便利に使えればいいし、無理があるような場合には脇に置いといたり、
場合によってはあっさり捨ててしまってもいいんじゃないかな。
どっちのモデルであれ、あるいはそれ以外のどのモデルであっても、固執するのは馬鹿らしいと思う。
ていうか、ひとつの完全なモデルがみつかってなら、
何でこれほどたくさんの「オブジェクト指向」言語が作られているのか、て話になる。
で、lisp のいいところっていうのは、
記法をそこそこ柔軟にモデルに合わせて作り変えられるってとこでしょ?
散々言われてきたことだけど。
例えばあるオブジェクトについて、手続きを順々に追っかけさせる、みたいなことをしたいなら、
自分が上に書いたのや
>>311 さんが書いたようなやり方で簡単に出来るわけで、
そうした方が問題をすっきり記述できると判断するなら書きゃいいじゃんてことではあるけれど、
でもそれがどの問題についても妥当であるというなら、それは了見が狭いといいたい。
前置記法がわかりずらいってケチつけてるだけだろ lisp 族がメジャーになることはないんだから、わざわざ粘着するなよ
連鎖適用って、そんなに嬉しいかな。 何か他の値を返すようなメソッドには使えないけど。 返り値がいらないようなメソッドを続けて使うのって、表示周りとかかな…
連鎖適用って途中で切るオペレータが欲しいんだよな。 NULLやnilのような無効値だったらそれ以上進まないようなやつ。 リスト処理だけなら空リストで済むから問題ないんだけどね。
(macroexpand '(-> obj (f0) (f1 arg1))) => (let ((obj1 (f0 obj))) (if obj1 (let ((obj2 (f1 obj1 arg1))) obj2) obj)) というマクロ->を定義するのは簡単だよね。nilになる一歩手前のオブジェクトを 返してくれる。
(define-syntax chain (syntax-rules () ((_ obj n) obj) ((_ obj n (m . args) . more) (let ((c (m obj . args))) (if (eq? c n) n (chain c n . more)))))) letの変数ってこれで大丈夫なのかな?
後置記法のLispを作ればいいんじゃないの。 データについて考えてみても、cons してから reverse (nreverse) ってのをよくやる(見る)けど、あれ無駄な気がしてならない。
>>319 consセルの先頭に突っ込むのとケツに突っ込むコストが同じだというのか。キミは。
dequeが欲しけりゃリストの先頭と末尾を指すconsを一個持てば作れるけどな。 破壊的操作が必要になるのであまり嬉しくないけど、 計算量的にそれが必要ならやればいいだけの話。
>>321 いやそういうことではなくて…。後置記法Lispの場合、consで先頭に
突っこんでいくと逆さまになるのも気にならなくなるのでは、
ということです。
そんなあなたにDylanを いえ、すんません。巣に帰りまつ(;´Д`)
アホすぎ。reverseかけるのは気になるならないの問題じゃないんだが。
(define (copy-list1 l) (let loop ((l l) (r '())) (if (null? l) (reverse r) (loop (cdr l) (cons (car l) r))))) (define (copy-list2 l) (let loop ((l l) (c (lambda (x) x))) (if (null? l) (c l) (loop (cdr l) (lambda (x) (c (cons (car l) x))))))) (define (copy-list3 l) (if (null? l) '() (cons (car l) (copy-list3 (cdr l))))) (define (copy-list4 l) (let ((n '(()))) (let loop ((l l) (r n) (end n)) (if (null? l) (cdr r) (begin (set-cdr! end (cons (car l) '())) (loop (cdr l) r (cdr end))))))) 速度は copy-list1 > copy-list4 >>> copy-list2 >>>>>> copy-list3 くらいでした。copy-list4 はなんで遅いんだろ。
>>326 リストの長さや処理系によっても随分違うものになるだろうから
それらを特定しない比較には意味が無いような
copy-list4はrが冗長なパラメータだろう。それはそれとして、 リストの長さを変えても傾向は変わらなかったのか?
(define (copy-list5 l) (apply list l))
>>328 ほんとですね。とりあえず、
(define (fact f n)
(if (= n 1) f (lambda (x) ((fact f (- n 1)) (f x)))))
(define (num-list n)
(let loop ((n n) (r '()))
(if (zero? n) r (loop (- n 1) (cons n r)))))
として
((fact copy-list1 X) (num-list Y))
みたいな感じで計ってみました。
Yを大きくすると copy-list4が速くなると思ったんですが、
copy-list1の方が速かったです。処理系は Gaucheです。
他の処理系でも試してみます。
cons,cdr,set-cdr!が同じ時間で実行できるとして copy-list1,copy-list4がそれぞれどれくらいの時間でできるか計算してごらん。 copy-list1はgcの時間をのぞいたら変わらないと思うよ。
(define (my-reverse l) (let loop ((l l) (r '())) (if (null? l) r (loop (cdr l) (cons (car l) r))))) (define (copy-list6 l) (my-reverse (my-reverse l))) としたら copy-list4 > copy-list6 でした。 つまり copy-list1は組み込みのreverseを使っているから速いってことでしょうか。 リストの長さをNとすると copy-list1は 6N、copy-list4 は 5Nくらいの計算量に なるんですかね。
guileでも同じ様な結果でした。 ちなみに Gauche組み込み対決では list-copy と (lambda (l) (reverse! (reverse l))) が互格でした。 こういうリスト全体の処理では組み込みの reverseを使った方がいいってことですね。 あとからリストの後ろに破壊的に要素を足していきたい場合は deque方式と。
>つまり copy-list1は組み込みのreverseを使っているから速いってことでしょうか。 そうです。 copy-list1は2回cdrをたどってるから2N、copy-list4はNで reverseがどんなに速くても、copy-list1はNより速くならないと考えるかもしれないけど、 copy-list1は6N、copy-list4は5Nになる。 copy-list1の内reverseにかかる部分が3Nで、コンパイルしたら2倍から10倍で実行できるとすると 4.5Nから3.6Nで実行できるわけです。 実際にどれくらいの速度差で実行してるか調べてみたら?
3.6N -> 3.3N
(define (copy-list l) (append l '()))
そんなに速度気にするんならコンパイルできる処理系で コンパイルした方がいくない?
自作のScheme処理系のためのコンパイラを書いてるんですが、named let は 次のような感じで変換すればオーケーでしょうか? letrecをまだ用意していないもので。 (let loop ((a foo) (b bar) (c baz)) body) => (let ((loop #f) (a foo) (b bar) (c baz)) (set! loop (lambda (a b c) body)) (loop a b c))
(((lambda (f x) (lambda y (apply (x (f f x)) y))) (lambda (f x) (lambda y (apply (x (f f x)) y))) (lambda (loop) (lambda (a b c) body))) foo bar baz)
>>339 foo, bar, bazのスコープにloopが入ったらまずいんでない?
>>341 入るのでしょうか? 入らないように思えるのですが。
gosh> (define loop '|(゚∀゚)アヒャ|)
loop
gosh> (let ((loop #f) (a loop) (c (lambda () loop))) (list a (c)))
(|(゚∀゚)アヒャ| |(゚∀゚)アヒャ|)
>>340 一見しただけでは何が何やらですが、理解に努めてみました。
> (lambda (f x) (lambda y (apply (x (f f x)) y)))
これをF
> (lambda (loop) (lambda (a b c) body)))
これをL
とおくと
((F F L) foo bar baz)
になって、少し展開すると
((let (loop (F F L))
(lambda (a b c) body))
foo bar baz)
みたいになりますね。
このbodyの中でloopを呼ぶと((F F L) a b c) のに戻って繰り返すわけですね。
面白い。こういうのをストリームというんでしょうか。
>>211 ホントですか?
Cygwin 1.5.12-1
と
Gauche0.8.3 と Gauche-gtk-0.4.1
だと
gauche-glib.cのmakeでエラーがでてしまいます。
どーやったらコンパイルできるようになるのでしょうか?
345 :
339 :04/12/27 14:13:10
コンパイラが初期化用手続きを吐けるようになりましたので記念上げ。 # いまんとこコンパイラを動かすにはGaucheが必要だったりするんですが ところで自由変数を参照しない手続きを呼ぶ用語に困っているのですが、 何か適当な用語はあるでしょうか。 環境を持たないクロージャなんですが、組み込みの手続き(コンパイラが即値で 書き込む)を利用するので副作用があって関数とも呼びにくいのです。 ちなみに大域環境はありません。
完成おめ。 これからブートストラップしてくんだね。 ところで環境を持たないクロージャとは、単純にトップレベルで 作成するような関数のことかね? すなわちその関数内部の変数参照がローカル内で完結している関数 という解釈でいいのかな。 それとも、環境を持たないクロージャというのを、 限定構文を使うなりで明示的に宣言して作成するということかね。 副作用がSchemeからは見えず、処理系の内部的な話なのであれば、 特に区別する必要もない気がするが。 明示的なものであれば、例えばCにトランスレートするのが前提の関数なら cfuncとかcdefineとか機能や意図に基づいた名前を付けるぐらいしか 思いつかないが。 あとは既存の処理系の名前を漁ってみるしかないんじゃないかな。
>>346 どうもです。
> ところで環境を持たないクロージャとは、単純にトップレベルで
> 作成するような関数のことかね?
そうです。レキシカル変数(引数か、内部で積む環境フレーム上の変数)だけ
使うもののつもりでした。
consとかcarとかつかわないの?
過去スレ以外は別ページにすべきだよ。
まとめサイトがありゃいいけど
おれにはそんなの作る気力がない
まあ当面は
>>2 以降にだらだらでいいやね
>>344 Gauche 側の gauche.h の SCM_EXTERN から __declspec(dllimport) を削って
Gauche-gtk 側は libgauche-uvector をリンクするよう追加するだけ。
最近の ld と gcc なら dllimport は無くてもよしなにやってくれるから。
冬休み暇なやつがまとめページ作ります
>>352 http://ocw.mit.edu/OcwWeb/index.htm にMITの講義録やシラバスがあるが、ビデオは数えるほどしかない。 将来的には
もっとビデオを増やすらしい。
ここはLispスレだし、その方面のバイブルがタダで手に入って、かつ、講義まで全部見れるんだから
世の中便利になったと思います。
個人的にはSICPは冗長な気がする(特に、1〜3章)けど、4,5章は真面目に読む価値があると
思う。 実際に自分で手を動かして、Schemeのインタプリタやランタイム&コンパイラをJavaや
C++で実装するとホントに理解が深まる。 CSを勉強するときには実際に手を動かした時に学んだ
ノウハウが大きな財産になるから、暇な人はトライしてみる価値がある。
CSって何?
東経110度でスカパーとかやってるやつ。
無線とかで最初にいうやつ。
シャア専用の略
マジレスするとComputer Scienceの略。 コンピュータ・サイエンス専攻なら英語で I'm a CS major at ** university. で通じるよ。
Computer Systemかと思った。
>>345 > ところで自由変数を参照しない手続きを呼ぶ用語に困っているのですが、
> 何か適当な用語はあるでしょうか。
「自由変数を参照しない手続き」といえばコンビネータだけど
ちょっとニュアンスが違うような気もしないでもない?
「副作用があるから関数とは呼びにくい」って書いてなかったか…? コンビネータは、普通はあまり副作用のないイメージが。 「閉じた式」(=自由変数のない式)の類推で、「閉じた手続き」じゃ駄目?
関数じゃないならSubとかProcedureでいいじゃん
凄く初歩的なことのような気がするのですが質問良いでしょうか… (define aaa "hello, world") (define (bbb) 'aaa) (ccc (bbb)) => "hello, world" になるような手続きcccってあるんでしょうか。 evalしかないですか?
あとはマクロぐらいじゃない?
quoteをつけることによって、evalしないわけだから、この場合明示的にevalしなきゃ いけないんじゃない? sicpの4章を読みましょう。
そうですか。ありがとうございます。 とりあえずSICPも読んでみます。
束縛をつかうからダメなだけで、シンボルと値の対応表を別に作ってassqすればいいんでないかい?
>>353 遅くなりましたが、教えていただきありがとうございます。
これから試してみます。
関数で、結果が環境に依存せず引数だけで決まり、また、 副作用ももたないものを形容する言葉はありますか? +や-などがその仲間だとおもいます。よろしくお願いします。
明けましておめでとうございます。
返事がおくれてすみません。
>>363 ,364
さすがにコンビネータはちょっとそぐわない気がいたします。
閉じた手続きはいいかも知れません。closed-procedureでしょうか?
>>348 そういうのは組込みの手続きを用意していてそれをコンパイラが埋め込みます。
初期化段階ではLisp/Scheme的な大域環境が(シンボルも)存在しないので。
>>372 それを関数(function)と呼ぶのではないでしょうか。
副作用があったり環境に依存するものを含めた総称がprocedureではないかと思います。
>>373 > それを関数(function)と呼ぶのではないでしょうか。
> 副作用があったり環境に依存するものを含めた総称がprocedureではないかと思います。
すみません、書き忘れました。Common Lispに限定しますと、規格書やコミュニティー内でも、
そのような区別はされていないようです。
(functionpなんてpredicateはそういう区別をしません。)
Common Lispの場合はそうですね。 関数が手続き一般を指す場合、"pure function" というのが使われることが 多そうな気がします。元はfortran用語でしょうか。
>>373 (define (hoge x y) (cons x y))
(define (cons x y) ...)
はどう処理されるの?
>>377 いまのところ、そういうことはしない、というのが答です。
というのも、フルセットのScheme環境を用意するための「ローレベルScheme」
みたいなものが趣旨なので。シンボルも環境もこれを使って書くわけです。
# 今のところベクタも文字列もシンボルもありません
現状、大域変数はコンパイル単位で完結し、かつちょっと情けないですが1パスで
> (define (hoge x y) (cons x y))
ここでconsは組込み定数の参照("SCM_OBJ(&cons)"みたいな)に置き換えられ
> (define (cons x y) ...)
以降はconsに割り当てられた大域変数を参照します。
必要なら、lambda中の大域変数の操作をいったん擬似命令として出力する2パスで
今の条件でも(コンパイル単位で完結するのは変わりませんが)例のようなケースの
参照を普通のSchemeのようにできるとは思います。
今のところ大域変数の実体はコンパイル単位全体を包む最下段のレキシカル環境
フレームという身も蓋もない実装です。一段落ついたら、
defineされる大域シンボルのうち定義だけされるものと
変更されるものを区別して、後者のみCの変数を記憶場所に割り当て、
前者は定数化して参照を直接埋め込むようにする予定です。それが済めば
コンパイル単位間で大域変数を共有することも(必要性はともかく)できるはずです。
共通の大域環境を参照する普通のSchemeのコードをどうコンパイルするかは
そのうちシンボルや大域環境をローレベルschemeで書きながら決めます。
>>380 Schemeで著明な人達の写真が見れるね。
Guy Steeleの顔ぐらいしか知らなかった。
ドレッドヘアーの黒人は誰?
lisper が書く情報科学の wikibooks を見てみたい。
どなたかSECDR-Schemeの再ウプきぼんぬ。 小さくて速い処理系を探してまして、最も有望なBitとSECDR-Schemeのポインタが切れていたもので。
リンクは切れてたけど適当にURL推測したらあったよ>SECDR。 去年の話だけど。
型付きラムダ計算について書いてある資料で、 何かお勧めのやつあれば教えてください。 サイトでも教科書でも構いませんので…… MLのスレで聞いたほうがいいのかな?
型付きラムダ計算について書いてある資料で、 何かお勧めのやつあれば教えてください。 サイトでも教科書でも構いませんので…… MLのスレで聞いたほうがいいのかな?
387 :
デフォルトの名無しさん :05/01/10 12:40:00
>>387 その本にもあるかわかんないけど、
おれ論理式がよくわかんなかった。
でかい分数表記のやつ。
つーかあの辺理解できる気がしない。
実際どう動くかコードで示してほしかった・・・なんて無茶か。
>>387 レスどうもありがとうです.
とりあえず図書館で探して読んでみるとです.
>389 多謝。ドキュメントが詳しいのも良いっすな。
392 :
紫藤 :05/01/18 11:24:21
習作のSchemeもどきの実装を晒しても良いですか?
>>395 たらい回ししてみようか…と思ったら、比較オペレータは定義されてなかった。
まだまだテスト版だからってことでしょうか。
ちょっと見てみると、scheme_oprtクラスとか無駄してるような…。
C++で実装するというのは、C使いの自分には面白かったです。がんばってください。
これだけのコードでまがりなりにも
処理系を作れてしまうというのが、Scheme(lisp)の良さですよね。
>>396 比較オペレータなどを定義してみました。
scheme_oprtクラスは無駄してるでしょうか? よく分かんないです。
整数や真偽値や基本手続きをポインタではなく即値で埋めこむテクニックを知ったのですが
この先中間コードにコンパイルすることを考えると、今はどっちでもいいのかなあと思いました。
中間コードの話はSICP5章とドラゴンブック以外に参考になる文献はあるでしょうか?
特に継続の実装がさっぱり分からないです。
>>397 わっ、反応早い!
scheme_oprtクラスのprintメソッドは、簡単なやり方でも、
とりあえず先にprintf("#<subr ")しておいて、if文でプロシージャ名をprintfして、
最後に">"をprintfしておいた方が、無駄な文字列データが減るはずです。
aplyメソッドも、プロシージャごとに完全なコード書かずに、汎用化するとか。
色んな意味でRHG(Ruby Hacking Guide)とGHG(Gauche Hacking Guide)は
役に立つと思いますが、すでに見ているか。
>>398 printメソッドの話ですか。そこらへんは適当です。
Rubyのは少し見てましたが、Gaucheのは知りませんでした。
C++は細かいとこが直感的に分らないのでCで書きたくなってきました。
質問なんですが、手続き呼びだしの時、環境をコピーするより名前置き変えの方がいいですよね。
あと、SRFI-17の set!を実装するには全てのオブジェクトのサイズを同じにしないといけないんでしょうか?
>質問なんですが、手続き呼びだしの時、環境をコピーするより名前置き変えの方がいいですよね。 クロージャーの呼び出しでは引数を束縛して新しい環境を作るけど、これはコピーとはちょと違うし、名前の置き換えというのも何を意味しているのかちょとわからないなり。 >あと、SRFI-17の set!を実装するには全てのオブジェクトのサイズを同じにしないといけないんでしょうか? SRFI-17のほうは例えば(define x "hogehoge") (set! (string-ref x 4) 3.14)みたいなことはエラーになるべきだから考えなくていいんじゃないかな。
>>400 >クロージャーの呼び出しでは引数を束縛して新しい環境を作るけど、これはコピーとはちょと違うし、名前の置き換えというのも何を意味しているのかちょとわからないなり。
環境を壊したくないので、クロージャーを呼び出した時点での環境をコピーしてそれに引数の束縛を足して使うという意味です。
新しい環境を作るのにコピーはしないんでしょうか? 名前の置き変えは、環境は一つだけでかぶる引数の名前を全部置き変えるということです。
環境をリストで表現して先頭から新しい束縛を足して、検索するときは先頭から順番に調べるようにすれば、一つのポインタのコピーだけで済んで良いかなあと思いました。
ハッシュと違って検索に束縛の数に比例して時間がかかるのが欠点ですがどんなもんでしょうか。
>SRFI-17のほうは例えば(define x "hogehoge") (set! (string-ref x 4) 3.14)みたいなことはエラーになるべきだから考えなくていいんじゃないかな。
なんか勘違いしてました。ポインタの指す先を変更しないといけないのかと思ってました。
>すでに存在する環境に引数から作った環境をリンクする 「すでに存在する環境」はクロージャーの持っている環境のことなり。 >元のスタック上の環境は以後は使われなくなるなり これは完全にゴミになるということなり(実際デバッグ時には"0xcafecafe"とかで破壊するとよい) どうもShiroのようにはうまく説明できないのう。
secd machineでぐぐれば一発でわかると思う。
>>402 なるほど。ちょっと難しいですが、20%くらい分かった気がします。
名前を検索するときは envポインタからたどって、
一番下の環境->一個上の環境->もう一個上の環境 という風に探していくんでしょうか?
なんか効率が悪いような。環境一つ一つはハッシュなんでしょうか?
>次に、lambdaでクロージャーを作るときは環境をスタックからヒープに移動することはあるけれど、元のスタック上の環境は以後は使われなくなるなり。
なんで使われなくなるのか良く分からないです。これはスタックマシンのVMの話だからまた別の話なのかもしれませんけど。
SICP 4.1.7にあるような構文解析をしようと思ったんですが、quoteや ifに別の値が束縛されていると困ることに気づきました。 妥協案として実行時に defineや lambdaに出食わしたら、その時の環境を使ってボディを構文解析するというのを思いつきますた。 でもそれでは (define (my-if a b c) (let ((if if)) (if a b c))) は解析できても (define (my-if a b c) (if a b c)) というノーマルなやつが解析できないと思いますた。でも Gaucheでは gosh> (define (my-if a b c) (if a b c)) my-if gosh> (define if list) if gosh> (my-if #t 0 1) 0 となりました。 というか上のバージョンは実行できなかったです。scmでも実行できなくて、scheme48では定義すらできませんでした。 guileでは実行できました。 という訳で、実行時に defineや lambdaに出食わしたら rootも含めた環境でボディ部を構文解析するというのでいいのでしょうか? それとも ifを別の名前に束縛してる場合は諦めて、ifが上書きされてないか気合いでチェックして実行前に構文解析してしまうのがいいんでしょうか?
>>405 >一番下の環境->一個上の環境->もう一個上の環境 という風に探していくんでしょうか?
基本はその通り。
>なんか効率が悪いような。環境一つ一つはハッシュなんでしょうか?
間違いなく効率が悪い。だからインタープリターでも中間コードを使ったり、コンパイラはさらに気合いを入れた最適化をするなり。
>環境一つ一つはハッシュなんでしょうか?
トップレベルだけはハッシュを使う実装が多い。
>なんで使われなくなるのか良く分からないです
これは環境の複製を作って、オリジナルと複製の両方を使うということがないという意味で書いてみたんだけと、説明の書き方が悪かったかなりね。
>>404 secd machineでぐぐれば一発でわかると思う。
いいね〜SECDマシーン。
ちなみに、SECDによるScheme実装にはLispMeもあるなり。こっちは"SECD LispMe"でググルべし。
(LispMeという名前だけどSchemeだよん)
>>406 (define (my-if a b c)
(let ((if if))
(if a b c)))
--> syntax errorまたはunbound variable 'if みたいなエラー
(let ((if list))
(define (my-if a b c)
(let ((if if)) (if a b c)))
(if 1 2 3))
--> (1 2 3)
これはifに束縛値があれば変数として扱い、なければsyntax keywordとして扱っているからで、構文解析するときにはトップレベルから発生しているすべての束縛を記録しておく必要があるなり。これはよくcompile time environmentと呼ばれているなり。
ちなみにgaucheで実行できるのは、
gosh> (define (my-if a b c) (if a b c))
で中間コードに変換されるときにifがsyntaxのifとして中間コードに書き込まれていて後の
gosh> (define if list) の影響を受けないから。
gosh> (define if list) (define (my-if a b c) (if a b c)) (my-if #t 0 1)
とやれば(#t 0 1)が返されるはず。
gosh> (define (my-if a b c) (let ((if if)) (if a b c)))
はやはりエラーになるんじゃないかな?
最後に、どのmy-ifの定義もifと同等の定義にはなっていないよ。これは念のためなり。
おっと、 (let ((if list)) (define (my-if a b c) (let ((if if)) (if a b c))) (if 1 2 3)) は (let ((if list)) (define (my-if a b c) (let ((if if)) (if a b c))) (my-if 1 2 3)) のまちがいなり。4行も書くとバグがでるなりね(笑
>なり ウザイ
>>408 えっと上のやつは
(define my-if (let ((if if)) (lambda (a b c) (if a b c))))
の間違いです。アホでした。どちみちエラーなんですけど。
>これはifに束縛値があれば変数として扱い、なければsyntax keywordとして扱っているからで、構文解析するときにはトップレベルから発生しているすべての束縛を記録しておく必要があるなり。
なるほど。記録しておく、というのは束縛が発生しているかいないかくらいでいいんでしょうか。
>これはよくcompile time environmentと呼ばれているなり。
compile time environmentですか。この言葉だけで全てが分かった気になりますた。
マクロの展開の話もこれですよね。つまりSICPみたく (analyze exp)とはできず (analyze exp compiletime-environment)
でないといけないと。
>>407 >間違いなく効率が悪い。だからインタープリターでも中間コードを使ったり、コンパイラはさらに気合いを入れた最適化をするなり。
やっぱそうですか。それが嫌で、コピーするようにしたんですよね。どうせクロージャ作る時はマージするんだろうし、と思って。
でもコピーのコストが気になるのと set!に対応できないので
>>401 みたいなことを考えたんです。トップレベルだけがハッシュというのも納得できる
気がします。
>これは環境の複製を作って、オリジナルと複製の両方を使うということがないという意味で書いてみたんだけと、説明の書き方が悪かったかなりね。
単純にそういうことですか。理屈で分かっても実際にどういう風に操作をするのか想像できないので、ちょっと理解できなかったです。
たぶん、単にVMを作ったことないからだと思いますが。
おれはマクロや構文のキーワードの参照したらエラーとして 弾いちゃって良いと思うけどなあ。 混乱するだけでなんも良いことないし。 それよりSchemeは名前空間関係を整備してほしい。
>>412 ローカル変数へのset!のことを考えると、基本的に環境はコピーできない。
ただ、set!されるローカル変数は静的に解析できるので、それだけを
ヒープアロケートしたメモリに置いて間接参照し、それ以外(参照only)の
変数はコピーしてしまう、という手法はある。ディスプレイって言ったっけ?
もう記憶があやふやだが。
>>414 >>415 そういう方法も研究されてるんですね。調べてみます。
みんな物知りですね、ほんと。
>>415 また一人の男が門をくぐった…その門の名は lambda の門。
ガンガレおまいらw
俺も今schemeのインタプリタ作ってるので非常に参考になります…。
シンボルから引けるオブジェクトをスタック構造にするというのは問題あるでしょうか?
set!にも対応できるし、クロージャを作るときはトップだけをコピーすればいいし問題ないように思えるんですが
(どれをpopするか覚えとかないといけないですけど)、継続が絡むと破綻するってことはあるんでしょうか?
あと Gaucheは ifだけでなく consみたいな基本手続きも埋めこんでる様なんですが、これは時に仕様に反しないでしょうか?
(define (cons a b) (cons a b))
(cons 0 0)
は無限ループになるべきだと思うんですけど。
(define (cons a b) (cons a b))は
構文解析でcons, a, bは束縛変数だと分かるのでそれらには埋め込めないですよね
consが上書きされたら自分にアクセスされなくなるので、consに自分自身を埋めこむのはありかなと思ったんですが、
(define cons2 cons) (define cons list) とかされる可能性もあるのでやっぱ埋めこめないですね。
最適化の為に目をつぶったって感じでしょうか。
>>402 のGaucheのVMのスタック操作っていうページはかなり素晴らしいですね。
環境の扱いが検索する側にとって非効率に見えるんですけどそれでもあの速度がでるんですね。
上に書いた実装じゃ継続の実装も変わってくるだろうし、総合的に見たらどうなんですかね。
あと、実行前に構文解析するようにしても速度変わりませんでした。
lambdaとifくらいしかやってないんですけど。速くなるべきなんですかね。
lambdaの最適化について妄想ですが、 クロージャを作るときにボディを構文解析して第一引数の使われる場所に間接参照(ポインタのポインタ)を置いておく。 第二引数以下の使われる場所にもそれぞれ別の間接参照を置いておく。間接参照は評価されると参照先のものになる。 applyされるとそれぞれの間接参照がそれぞれの引数を指すようにする。set!は間接参照をいじることで実現する。 っていうのでトップレベルの変数以外のlookupが無くなる気がするんですが、どうでしょうか。 evalの扱いが微妙になるとは思うんですが。
>あと、実行前に構文解析するようにしても速度変わりませんでした。 >lambdaとifくらいしかやってないんですけど。速くなるべきなんですかね。 式のタイプによる分岐を実行前に事前にしておくのが肝なので、 他の構文や手続きの適用、シンボル等もやらないと。 速度は一割五分ぐらいよくなるかなあ。
>>421 そうですか。かなり地道な作業ですよね。コードの量が一気に増えるので微妙にためらってしまいます。
シンボルの構文解析って意味あるんですかねえ。SICPレベルだと全然意味ない気がします。
ところで()の評価は仕様で決まってないんでしょうか?
仕様を見る限り()は式では無いように思えるんですが、実際には()を返す処理系がたくさんあります。
SICPのような実装だと意味がある。 環境を辿って束縛している値を探す、正味の実行時間は変わらないけど 評価のたびごとにcondの条件判定をしている部分が省けて、 手続きの適用をするだけになって高速化するわけだから。 (condの条件判定をするよりも手続きの適用の方が速いと仮定して) 型タグの値でcase文を使って分岐してるんなら、高速化の余地は少ないと思う。
>>423 なるほど。すでに型は分かっているから多態は必要ないんですね。
C++ならファンクタでどうにかなるかもしれません。
Cなら、グローバルもしくはスタティック変数使えばできなくもないかもしれないけど、すごく難しそう。
>>419 >あと Gaucheは ifだけでなく consみたいな基本手続きも埋めこんでる様なんですが、これは時に仕様に反しないでしょうか?
>(define (cons a b) (cons a b))
>(cons 0 0)
>は無限ループになるべきだと思うんですけど
これは具体的にはトップレベルの定義をinternal definitionとみなしてletrecで束縛する処理系ならば無限ループになる。
本来ならそうあるべきなのであろうが、そうならないGaucheが仕様に反しているかは微妙だ。なぜならインタラクティブなトップレベルの規定が不明確だからで....
例えばGaucheでも
(let ()
(define (cons a b) (cons a b))
(cons 0 0))
とやれば当然無限ループとなる。
それじゃトップレベルもそれに合わせれば良さそうだが....
(define hoge 8)
(list hoge)
(define foo +)
(foo 8)
を単純に
(let ()
(define hoge 8)
(list hoge)
(define foo +)
(foo 8))
はできない。シンタックスエラーだからだ。
どうするR6RS???(笑
>>425 トップレベルの規定が不明確というのは
(define a 1)
(define (b) a)
(set! a 10)
(b)
として1が返ってきてもいいということでしょうか?
>>422 >ところで()の評価は仕様で決まってないんでしょうか?
>仕様を見る限り()は式では無いように思えるんですが、実際には()を返す処理系がたくさんあります。
()は#tや#fみたいに評価すると自分自身になるオブジェクト。括弧がついてるけどリストではない。
例えば (eq? () '()) --> #tだ
ところで、#nilとかにしないで()を使うことになってるのには何か理由があるんだろうけど...だれか知ってる?
>>427 R5RS 的には quote が必要
4.1.3 Procedure calls
Note: In many dialects of Lisp, the empty combination, (), is a
legitimate expression. In Scheme, combinations must have at least one
subexpression, so () is not a syntactically valid expression.
not valid ではあるけど、invalid とされているわけでもなく 扱いも明記されていないので、結局処理系依存?
>>427 ちょっと長くなるけど....
R5RSの5.2.2 Internal definitionsより
"Such definitions are known as internal definitions as opposed to the top level definitions described above. The variable defined by an internal definition is local to the <body>. That is, <variable> is bound rather than assigned ..."
とあるので、裏を返せばtop level definitionはassignmentsつまりset!と同じ動作だと推察できる。
これによれば、
(define a 1) (define (b) a) (set! a 10) (b)
は
(set! a 1) (set! b (lambda () a)) (set! a 10) (b)
となると考えられ、結果は10になるべきだと思う。
"本来ならそうあるべきなのであろうが"と書いたのはこれを根拠としてみた。
"不明確"と書いたのは、これだけでは次の動作の説明ができないと思ったからだ。
(define (hoge x) (if x "foo" "bar")) (hoge #t) (define if list) (hoge #t)
を先のように書き直すと、
(set! hoge (lambda (x) (if x "foo" "bar"))) (hoge #t) (set! if list) (hoge #t)
でも2つのhogeが返すのは両方とも"foo"でないといけない!
じゃあ本当のところはどうすればいいのか?
でも5.2.1 Top level definitionsにはほとんど何も書いてないし.....
いずれにしても1を返すのはまずいとは思う。
>>428 そのまんま書いてありましたね、すいません。近くまでは見てたんですが。
R5RSで invalidなものを validとして扱えてもR5RS互換といえるから大丈夫なんでしょうね。
これを validにするメリットがあるなら知りたいですが。
>>419 の一段落目と
>>420 についてはどうでしょうか?
>>428 ほんとだ、しかも(list? '()) -> #t だし。
マリアナ海溝より深く反省します m(_ _)m
>>430 >(set! hoge (lambda (x) (if x "foo" "bar"))) (hoge #t) (set! if list) (hoge #t)
>でも2つのhogeが返すのは両方とも"foo"でないといけない!
いけないっていうのは良く分かりませんが、とりあえず ifは構文なので無理矢理納得するとしても
cons でも埋めこまれてるから納得できなかったんです。
(define (hoge x y) (cons x y)) (hoge 3 4) (define cons list) (hoge 3 4)
の結果は処理系によってまちまちです。
>>433 ちょっと説明を整理してみた。
>(set! hoge (lambda (x) (if x "foo" "bar"))) (hoge #t) (set! if list) (hoge #t)
>いけないっていうのは良く分かりませんが
最初に、トップレベルでは(set! if list)はできない。
これはトップレベルのifが変数でないことを意味する。
次に、(define if list) (if 1 2 3) -> (1 2 3)
これは新しい変数ifを作りlistを束縛して呼び出し、結果の(1 2 3)を得ている。
では(define if list)の前に使われたifをどうするか?
そこではifは変数ではないので値を書き換える事はできない。
これが
(define (hoge x) (if x "foo" "bar")) (hoge #t) (define if list) (hoge #t)
でhogeが両方"foo"を返さなければならない理由。
>(define (hoge x y) (cons x y)) (hoge 3 4) (define cons list) (hoge 3 4)
>の結果は処理系によってまちまちです。
これは主なトップレベルの実装方法に2種類あるためで、明確な規定が無い為どっちが正しいとも間違いとも決められない現状ではしかたのないことではなかろうか。
ちなみに最初の方法は、
*すべてのシンボルが<undefined>という特別な状態に束縛されているとする。
*defineをset!として解釈する。
これは5.2.1 Top level definitionsに"Some implementations ..."と書いてある方法だ。
これによれば、次の様に解釈する
(set! hoge (lambda (x y) (cons x y))) (hoge 3 4) (set! cons list) (hoge 3 4)
結果は (3 . 4)と(3 4)
もう一つの方法は、トップレベルの式をbeginのシーケンスの様に解釈する。つまり
(begin (define (hoge x y) (cons x y)) (begin (hoge 3 4) (begin (define cons list) (begin (hoge 3 4)))))
みたいに扱う。
(注:実際のトップレベルでは(begin ...)の最初の式を評価した結果をディスプレイなりに出力する特別なbeginにする)
結果は(3 4)と(3 4)となる。
どっちにするかは好みだが、5.2.2との絡みから個人的には最初の方法に一票入れたい。
>>434 (3 4)と(3 4)を返す処理系ってあるんでしょうか?
guile gosh scm scheme48 csi(checkin) biglooでは guileと goshが (3 . 4) (3 . 4)を返します。他は(3 . 4) (3 4)です。
(define kons cons) (define (hoge x y) (kons x y)) (hoge 3 4) (define kons list) (hoge 3 4)
にすると goshだけになります。
トップレベルの実装方法の違いというより最適化の問題の気がします。
goshは上の例でも(3 . 4)を返しますし、(set! cons 1)とできるからです(ifでもできます)。
ちなみに上の中で(set! cons 1)ができないのは scheme48だけです。
ごめんなさい。最初のやつの結果が(3 . 4)(3 . 4)次のやつの結果が(3 . 4)(3 4)でした(滝汗 ちなみに (begin (define (hoge x y) (cons x y)) (begin (hoge 3 4) (begin (define cons list) (begin (hoge 3 4))))) をそのまま評価すると(3 4) (3 4)となるけど、これは処理系がdefineをletrecに変換してしまうからで。 それで勘違いしてたです。中身をflattenしないbeginと思って読んでくださいませ。
>>435 > (define kons cons) (define (hoge x y) (kons x y)) (hoge 3 4) (define kons list) (hoge 3 4) にすると goshだけになります。
ふむ。 たしかにその振る舞いは最適化に問題がありそうですね。
>goshは上の例でも(3 . 4)を返しますし、(set! cons 1)とできるからです(ifでもできます)。
goshで(set! if ...)ができてしまうとは.....意外だ。
>>434 ああ、また間違えてる。最初が(3 . 4) (3 4)、次が(3 . 4)(3 . 4)。まったく俺って情けない(涙
構文やマクロキーワードは処理系開発側からするといじらんでほしい。 最低でも警告出すか、エラーにしてしまってもいいとさえ思える。
ちょっと思ったんですが、型タグを使うよりも直接関数ポインタをメンバに持てばswitchを省けますよね。 オブジェクトのサイズが大きくなるから現実的ではないかもしれませんが。 構文解析後のオブジェクトはSICP風にやるなら環境を引数にとるメソッド一つがあれば十分なので、 それを関数ポインタメンバとして持つ、という感じでいいんでしょうか。
Gaucheでsyntax-caseは使えるのでしょうか? slibを使おうとしたらslib:eval-loadが未定義だったので まずslib.scmを修正してコメントアウトされていたslib:eval-loadを有効にし、 (use slib) (require 'syntax-case) しました。 しかしdefine-syntaxでsyntax-caseを使おうとすると *** ERROR: define-syntax needs a syntax-rules form, but got (lambda(x)(syntax-case (以下略 というエラーが出て、どうもsyntax-rulesしか使えないような気がします。 UNIXでsyntax-caseを問題なく使える処理系があれば教えてください。 目的はsyntax-caseの練習です。
お騒がせしてしまってすみませんが、標準手続きへの割り当ての問題は R5RSの Chapter6の最初
に思いっきり書いてありました。ただ
>>435 の例のも OKなのかは良く分かりませんが。
>A program may use a top-level definition to bind any variable. It may subsequently alter
>any such binding by an assignment (see 4.1.6). These operations do not modify the behavior
>of Scheme's built-in procedures. Altering any top-level binding that has not been introduced
>by a definition has an unspecified effect on the behavior of the built-in procedures.
>>441 良く知らないけど Chikenというので使えるらしいです。
>>441 slibのマクロ実装って、repl(もしくはload)を乗っ取らないといけない
んじゃなかったっけ。もし対話的に実行してるなら、goshのプロンプト直接
じゃなく、slibのreplを起動する必要があるはず。
そうしてるのにエラーが出たなら、gaucheのslibサポートが不完全なんだろう。
>>444 それは確かに道理なので、Petite Chez Schemeを入れてみました。
おお、syntax-caseが使える! 日本語使えないけど(Windows版)
しばらく遊んでみます。
うーん、これがどの処理系でも使えるようになればいいんだけど、
R6RSでは使えるようにしてくれたりはしないのかしら。
ところでsyntax-caseってidentifierとかのコンテクスト周りが
ややこしそうなんですよね。皆さん使いこなせるんでしょうか。
syntax-caseで使うfree-identifier=?とかbound-identifier=?とかがいまひとつ よくわからないような、ちょっとわかったような。 (syntax-object->datum obj) "datum"を返すらしいが、ようするにシンボルとかquoteされたS式 (テンプレートに入ってる式の字面)が入っていると考えればいいんだろうか。 (free-identifier=? obj1 obj2) 変数として束縛されていない場合のみマッチさせたい場合は free-identifier=?を使うということでいいのかしら。 (bound-identifier=? obj1 obj2) bound-identifier=? ってのは同じ束縛を参照してるってことなんかなあ。 これが一番よくわからない。
Gaucheで (ref (sys-localtime (sys-time)) 'mon) => 1 になるのは私だけでしょうか?
≫450 マニュアルをきちんと読まない私が馬鹿でした。 お騒がせしました。
>>451 よい経験をなさいましたな。
小生、テスターに届いたときには既に時限爆弾で期限切れとなっていたというベータ版を知っております。仕様の勘違いから1ヶ月計算がずれたわけですな。
今では懐かしい想いで..... はあと。
schemeで末尾再帰でない再帰関数を書くことがあると思うんですが、 Cのスタックをそのまま使って evalと applyの相互再帰で実装すると わりと簡単にスタックオーバーフローで segmantation faultになって しまいませんか? やっぱスタック(もしくはCPS?)から自作しないといけないんですかねえ。
減らしたほうがいいのは確かだが、 規格上は末尾再帰でなかったらスタックをバカ食いしてもOKだと思う。
>>455 メモリ使用量の話ではなく、スタックオーバーフローの話です。
ヒープに自作スタックを置けばメモリの許す限り使えるし、
連続した領域じゃなくてもいいかもしれないから、良いことが多いん
じゃないかと。継続も実装しやすいでしょうし。
デメリットとしてスタック積むのが遅くなったりするのかも知れませんが
どの程度か良くわからないです。
schemeでたかが5000回程度の再帰で溢れてしまうので問題かなあと思ったんですが
guileはもっと浅くても溢れてしまうので OKなんでしょうか。
SECDR(これは当たり前?)や minischemeでさえ溢れないのに。
じゃあそうすればいいじゃん
どういう目的で使うかによるが、個人的にはスタック溢れで 落ちる処理系はとても使いにくい。テストデータで通って、 いざ本番を流してみたら入力データの特異点 (たまたまひとつだけ 再帰が非常に深くなるようなもの) で落ちてくれると、髪を かきむしりたくなる。
Schemeはcontinuationがあるからマシンスタックをそのまま使って実装することは あまりないと思うんだけどそうでもないのかな?
>>459 そうなのかもしれませんね。継続のことを考えないで作り始めたので、
途中で困ったんですが guileのソース見て真似して作りました。
マシンスタックをそのまま使っているので激しく環境依存だと思われます。
マシンスタックそのまま使う方法だと自動的に、作るときと実行するとき
両方でスタックをコピーすることになるので、とても効率が悪いと思います。
他の方法に比べると実装がとても楽なのが良い点だと思います。
まあいろんな意味でスタックもしくは継続を自作した方がいいってことですかね。
マシンスタック使う方が速いってことはあるんでしょうか?
SCMはマシンスタック使ってるのに、スタックが溢れない気がするので
そこらへん調べてみます。
SCMはマシンスタックだねえ。そのかわり環境は全部ヒープに作る。でも環境キャッシュがあるので早いけど。 ただしcall/ccと継続の起動は遅い。マシンスタックを全部セーブするから。 スタックオーバーフロウで止まらないのは、スタックを継続としてヒープにセーブしてスペースを空けてるから。 call/ccと継続の起動が無ければやっぱマシンスタックの方が早いね。 ところで最近「lambda の門」が賑わってるね、ラムダ饅頭でも作って仲見世で売ってみるかな(笑
>>461 >SCMはマシンスタックだねえ。そのかわり環境は全部ヒープに作る。でも環境キャッシュがあるので早いけど。
素朴な疑問なんですがヒープよりスタックの方がアクセスが速いんでしょうか?
>スタックオーバーフロウで止まらないのは、スタックを継続としてヒープにセーブしてスペースを空けてるから。
なるほど継続として扱ってスタックを退避させてるんですね。Gaucheと一緒ですね。
>call/ccと継続の起動が無ければやっぱマシンスタックの方が早いね。
やっぱりそうですか。マシンスタック使うのは Cでないと無理だし環境依存だし美しくないので
どうにかしたいものですが。
ベクタってなんで評価できないんでしょうか? 単なるデータだから自分自身を返してもいい気がするんですけど。
評価できないオブジェクトって束縛されてないシンボル、不正なリスト、ベクタの3種類だけですよね。
>>462 > ベクタってなんで評価できないんでしょうか?
SCM:
> #(1 2 3)
#(1 2 3)
ってことじゃなくて?
(eval (lambda (x) x))
>>463 クォート付けないといけないって仕様に書いてあるんで。
実行前の構文解析をして実行時の条件分岐や仮想関数呼び出しを無くしたんですが
逆に遅くなりました。型タグでの分岐や仮想関数呼び出しは大したネックにはならない
んですかね。速くする方法が分からないんですが、VM化すれば3,4倍くらい速くなるんでしょうか?
最低限、数字と文字列は自己評価してくれってことでしょ。
>>465 どういう風にしたんですか?
実行時の条件分岐や仮想関数呼び出しよりも高速な形式にしなきゃ速くならないでしょう。
>>467 構文解析済みオブジェクトに関数ポインタメンバを持たせて evalする時は
それを呼びだすという感じです。
struct analyzed_obj {
func_ptr ev;
scheme_obj value;
scheme_obj car;
scheme_obj cdr;
};
scheme_obj const_obj(analyzed_obj obj, enviroment e){
return obj.value;
}
struct analyzed_obj *analyze(scheme_obj obj){
if(numberp(obj) || boolp(obj) || charp(obj) || stringp(obj)){
struct analyzed_obj *a = new_analyzed_obj();
a->ev = &const_obj;
a->value = obj;
}
...
}
scheme_obj eval(analyzed_obj obj, enviroment e){
return obj->ev(obj, e);
}
よく分からないけど、 evには構造体をポインタで渡してるの?
上のコードいろいろ間違ってました。 carとか cdr の型は analyzed_objで
analyzeの中もヒープに確保したりとかは擬似コード的には余計でした。
evalの中も->じゃなくて.ですね。
>>469 実際には全てのオブジェクトをヒープに確保してて、全部ポインタ渡しです。
副作用起こせないだろ、とかそういうことですか?
アーキテクチャにもよるけど、関数ポインタのcallって重いよ
いや、コピーして渡してたら、そこが足を引っ張ってるのかなと思ったので。 これだったら仮想関数呼び出しと大差ないと思うんだけど、何で遅くなるんだろうね。
>>471 そうですか。仮想関数呼び出しが無くなる変わりに関数呼び出しが一つ増えてるんですよね。
型タグで分岐せずに直接関数ポインタを使うっていうのもなんか不毛な感じがしますし。
こまごまとしたエラーチェックを実行時にしなくていいっていうのはありますが、
>>423 が言うような高速化は気にしなくてもいいんですかね?
まあ、423も高速化の余地は少ないと言ってますし。
>>462 > 素朴な疑問なんですがヒープよりスタックの方がアクセスが速いんでしょうか?
アクセス速度の方はほとんど変わらない。局所性が上がる分だけ微妙に良い程度だと思う。
環境をスタック上に作るのはヒープの消費を押さえるためで、一般的にはこれが速度に貢献することを期待している。
ただしクロージャーを作るときにはヒープへのコピーが発生するわけで、コンパイラの性能やプログラムによっては逆効果になることもある。
そのへんは確かorbitの論文に詳しかったように思う。
>>473 >471が既に言ってるけど、関数ポインターの使用は最近のCPUでは遅い。理由は
1. 飛び先の分岐予測が外れやすい(ぼぼ100%外すやつもあり)のでハザードが多い。
2. 飛び先の分岐予測が外れるのを嫌ってコードのアッチコッチから飛ばしていると、今度はリターンの予測が外れて(ぼぼ100%外すやつもあり)ハザードになる。
んじゃどうするか?そこでFORTHですよ!騙されたと思ってthreaded codeでググってみよ!
FORTHマニアは友達にはなれそうも無いけど、やつらはVMには気合いが入っている。勉強になることが多い。
あ、FORTHでSCHEME書くのを勧めてるわけじゃないからね(笑
>>462 > 素朴な疑問なんですがヒープよりスタックの方がアクセスが速いんでしょうか?
ハード依存。
スタック領域とヒープ領域が別々のメモリになっていたら、多くの場合スタックの
方が早くなるように作られている。
でも大抵のPCは同じメモリ上にスタックもヒープもあるからアクセス速度はほとんど
同じだと考えて問題ないと思う。
ハードが特殊な場合は気を付けて。
>>474 なるほど。ラベルをデータとして扱えたらなーと思ってたんですが、GCCならできるらしいですね。
これは threaded codeと関係あるのかなあ。まだ threaded codeのことは全然分かんないですが、
Scheme関連でいうと QSchemeというのが使ってるらしいですね。
VMのことは全然分からないヘタレなのでとりあえずドラゴンブック読みます。
あと
>>395 のコードをいろいろ改良しました。いろんな構文や型を足して、
set!や継続を実装しました。すぐに スタックオーバーフローになるのと
継続が環境依存かつ遅いのが弱点で、SECDR-Schemeと同じ程度の速さです。
477 :
デフォルトの名無しさん :05/02/08 11:56:14
PC-98で使えるメモリ制限なし(EMSを使用してくれる)のschemeないですか
一万数千円くらいする処理系があったような
フリーではないですかね
niftyとか行けばいくらでもありそうだが
EMSなんて使うのあるかね? djgcc+DOSエクステンダなものならありそうとも思うが。
将来的に見てもパソコンに搭載されるメモリは 640キロバイトもあれば十分ですよ by ビル・ゲイツ
GaucheのMD5は (use rfc.md5) (open-input-file "Q:/000 SF/backup/(readme)/readme.txt") (md5-digest) で良いでしょうか? (md5-digest-string "test")は応答がありますが (md5-digest)は応答がありません。
マニュアル読め。 といいつつ、ワシも読んでないが、多分 (use rfc.md5) (with-input-from-file "Q:/000 SF/backup/(readme)/readme.txt" md5-digest) Gauche だと foo-string があるとき、foo は (current-input-port) から読んで (current-output-port) に書き出すプロシージャになってることが多い。
485 :
483 :05/02/14 21:55:25
>484 ありがとうございました
486 :
デフォルトの名無しさん :05/02/16 17:30:55
入門SchemeってHTML版ないの? PDF死ぬほど読みにくい・・・ リンクもないしさー
487 :
デフォルトの名無しさん :05/02/16 23:16:12
>486 書き方が変だから読みにくいんだよ。用語も少しおかしいし、眠くなるし。 プログラミング言語Schemeの方がいいよ。原書はただで読めるし。 そういえば何時の間にか3rd editionになってますね。
Schemeなんて最初はとりあえず普通のLISP(CommonLisp系)と、 その違いを知っておけばいいぐらいじゃない? ネットに転がってるSICPやら入門サイトでも流し読みすればいい。 結局R5RSとかの規格書しか読まなくなる。 あと理解を深めるには処理系依存度が高い言語だから、 どれか1つの処理系に詳しくなるか、自作でもした方がいいね。
普通のLispを知らなかったらどうするんだ
開発の滞っていない、フリーなCommonLisp処理系ってどんなのがありますか?
CLispでいいやん
CMUCL disassembleして眺めるのが好き。
Lisp入門はホフスタッターのが面白い
あれを入門としていいのか
たしかに漏れがLISPを初めて知ったのは「メタマジック・ゲーム」だったが
497 :
デフォルトの名無しさん :05/02/18 10:37:18
schemeの継続が理解できません クロージャないのトップレベルで(call-with-current-continuation (c) c)して継続を 得た場合この継続は何を指してるんですか?
その式から戻るという継続
ということはこの継続を例えば(define cc (call-...)しといて後で(cc 0)とすると この次の関数に処理の流れが戻るということですか
それは誰にもわからない。 誰にもわからないなんて凄すぎる。 いや、実はトップレベル継続の呼び出しは処理系依存。 トップレベルにも戻るというだけは保障されてるが、 次が何なのかは決まってない。
なるほどありがとうございます このスレのひとはなんかかっこいい
>>493 むしろあれはLISP信者への入信本かな
あの本には不思議な魅力があるよね
>(define cont #f) >(list 1 2 3 (call/cc (lambda (c) (set! cont c) 'foo)) 4 5 6) 1 2 3 foo 4 5 6 >(cont 'hoge) 1 2 3 hoge 4 5 6 でなんとなく想像つくかな?
> (define cc (call-with-current-continuation (lambda (c) c))) > (cc 80) > cc 80 これならどうだ?
ついでに > (define cont #f) >((call-with-current-continuation (lambda (c) (set! cont c) cdr)) '(1 2)) (2) > (cont car) 1 でもって、 >(call-with-current-continuation (lambda (c) (set! cont c) 'bye)) bye >(cont 'hello) hello ということになる。
わけわかんねえよ
こういうのは初心者スレに隔離しようぜ
あいにくSchemeの初心者スレはないのだ 別にどこでもいいじゃん
立てるべきは下らないメタ議論専用スレだ
shiroさんが Scheme 本を書く予定とかってないのですか?
Part7 の833辺りからがとても参考になるんですが、ちょっと分からないところ があります。引数をスタック上に作ると (lambda (a) a) みたいに引数が返り値に 使われるときに困らないでしょうか。返り値がスタックにあるかチェックしてヒープ にコピーしたりするんでしょうか。 頭の中がまとまってないので変なこと言ってたらすいません。
スタックから返り値用のレジスタにコピーするだけでしょ。
>>513 コピーはネックにならないんでしょうか?
GCいらない代わりにコピーが必要なのとコピーがいらない代わりにGCが必要なのは
どちらがいいか微妙じゃないですか?
メリット、デメリットを考えてそうしてるんでしょ。
そういうことですか。納得しますた。
(((((;゚Д゚)))ガクガクブルブル)
(define (´∀`) 'マターリ)
xyzzy で ChezScheme を書いている人は,私のほかにいませんか? 私は今のところ,lisp-mode で書いて,Petite Chez Scheme のコンソールに コピペしています.もっと良いやり方は無いものでしょうか? Emacs の *scratch* バッファがうらやましい.
xyzzyもwin上のchezも知らないんだけど、サブプロセスとして走らせられないの?
>>523 それはできるのですが,いくつか問題があって,
・プログラムの戻り値は表示されるが,ユーザの入力値は消えてしまう.
・サブプロセスの起動は,非力なマシンだと重い.
などの理由があって,今のところ Petite Chez Scheme を単独で動かしています.
やっぱり,スレ違いだったかな.xyzzy のスレに行ってみます.
Schemeのマクロが全然判らないんですが 良さそうな情報源ないでしょうか
google
>>529 批判があるのはよく分かるが,ほかに日本語で読める,R5RS のマクロの文献は
私はほかに知らない.あとはR5RS そのものになってしまう.
この本のマクロの部分は,R5RS そのものよりはまだ読みやすいよ.
言語間のコストをどうみるかは人それぞれだけど、 英語でもTSPLの説明の方が簡潔かつわかりやすいと思うな。 どうせR5RS分だけならすごく短いし。 chezのsyntax-caseの説明もあって長いけどそっちは興味ないなら全く見なきゃいいし。 すげー短いから、ここだけ和訳を立ち読みしてもいいんじゃない。 サンプルとかはwebにある英語と変わらないんだから必要なら参照できるし。
実例を伴う資料が少なすぎるんじゃボケェェェェ! と太陽に吠えてみる
Schemeのsyntax-ruleってそんなにわかりにくいか??? ほとんどlambdaと一緒だろ。
分かる奴が分からない奴のことなんて分かるわけがないだろう
成長すれば分かるようになる
中年男がテレビに出るらしい
ライブドアの社長役か?
『ハッカーと画家』のブックレビュー集がありました.
http://www.linux.or.jp/bookreview/BR85.html 驚くほど,評価が低い.誉めているのは最後の評者ぐらい.おまいらはこの本を,
どこまで理解してレビューしているのか,小一時間問い詰めたい.とにかく,
この本の内容の熱気が,評者らには全然伝わってない感じなんである.
と言うか,なんか考えさせられました.普通の人の反応って,こんなものです
よね.みんなが面白がるはずはない.それを改めて実感させられました.
>>539 Lispを知らない人(つまりほとんどの人)にとっては「なんのこっちゃ」って部分があるのは
確かだろうね。前半は割と万人に勧められると思うけど。
でも、こういう本をきかっけに Lisp に興味を持ってくれる人も多いのではないかと個人的
には期待してるよ。
そういう人たちの次のステップとなるためにも「Lispで作るWebアプリ」みたいな本が出ると
いいよね。
萌えLispきぼんぬ。
括弧たん(;´Д`)ハァハァ
Lisp用超セクシーな括弧の書体きぼん。
乳首がついてるとか?
} 右向いた oppai ) 右向いた oppai (陥没乳首)
すまん、くだらなかった
(おっぱい! :cup 'f) _ ∩ ( ゚∀゚)彡 ⊂彡
sexp
>>540 >「Lispで作るWebアプリ」みたいな本が出るといいよね。
このスレで議論して、本をだしてはどうだろう?
「電車男」に続いて。
煽りではない、マジレス
>>539 「日本語がこ難しい」という評はちょっと理解できん。
おれは良い訳だと思うし、最後の人の評がぴったりくるな。
まぁマンセー評ばっかりだと逆に嫌だけどw
>>549 多分 CGI よりも(勿論サーブレットよりも)
圧倒的に動きが分かりやすいから、良いと思う。
関数が呼ばれて文字列を返す、それをマクロで囲むだけ。
さてどこから議論するかだな。
とりあえず portable aserv と clsql 位の導入から始める?
ただし、圧倒的に高度な事をしないと Lisper は満足しないだろうし、
そうすると素人にはチンプンカンプン、という難しさはあるw
Webアプリで、Lispのパワーが生かせる場面があるか、じゃないかなあ 今はJavaにあわせてやれることを決めてるって感じだし
>>550 確かにふつーのWebアプリ作るだけなら「PHPでいいじゃん」って言われそうだよね。
CMSっぽいのを1から作るとかやれば面白いかな。
>>551 >>552 本物の(汎用的って意味ね)プログラミング言語である Lisp じゃなきゃ
できない事ってのを見せつけなきゃな…
すぐには出ないけど皆で考えたらなんかあるんじゃない?
FireFox ががんばってWebブラウザを再定義しようとしているように。
>>549 Lispを世に広めるためになら、敷居を低くすべきだろうな。
でないと、Lisperしか注目しないし、それでは意味がない。
面倒なんで、入門・初級・中級・上級とレベル別に議論すべきか?
そうすると、UNIX・Linux環境だけでなくWindowsも視野に入れねば
ならないか?
今のWebサービス系のPGやSEにアピールするためにはいきなり高度な
ことをせずに「とりあえず触ってみるか」と思ってもらえるように
しないといけない。となると、やっぱりWindowsなのかなぁ。。。
敷居っても色々あるよな。 まずは最初の壁を下げるために、Lisp/SchemeスペシャルなKNOPPIX CDが要るな。 ブータブルなKNOPPIX CD入れたらいきなりLispが動かせて、 必要なライブラリも揃ってるような奴。 できたらログインシェルを emacs にしといてやれw
追加。WindowManager は当然sawfishだ。
>>555 そういうの存在するはず。なんか一通りLispの処理系のエディタが入ってるやつ。
名前なんだっけ。
継続やらなんやらを駆使して、データベースとのやりとりやセッション管理を意識せずにWebプログラムが作れるようにするとLispっぽいかも。
>>550 | 「日本語がこ難しい」という評はちょっと理解できん。
評価した人の日本語理解力が訳者の意図したレベルに到達してなかったものと思われる。
幼稚園児に小学生の教科書を読ませたみたいな感じかな。
ただ幼稚園児は批評することなくわからないと言うのに対し、ある程度年をくってくると
自分が理解できない文章は書いた奴が悪いと文句を言うようになる。よくあることさ。
>>556 時々でいいですから GWM のことも思い出してやってください
>>556 sawfishはクソな気がするんですが
Squeakみたいなのが欲しい。 仮想VM環境入るとLISPづくしって感じの。
んで、どっかの学校で子供達がそのLISP環境で遊んでる写真も欲しいね。 子供を使った宣伝だね。 括弧だいすき!とか適当なフォーラムでっちあげて、 いかにも低年齢からでもLISP使えますよ?って誤解^H^H理解を広める。
いや、実際LISPさわるのは低年齢の方が良いと思うんだ。 Smalltalkと同じ様な理由で。
やっぱ環境か・・・。 Lisperの標準的な環境ってなんだろうね? やっぱemacsなんですかね? 個人的に、フランツがACLの日本語のドキュメントを 本にすりゃいいのに、と思う次第。 (あいつら日本でLisp広める気あんのか?)
日本法人なんて入る奴は基本的に他人の褌で相撲をとることしか考えないやつだから そんなの望むべくもなさそうな。
>>559 Common Lisp なら Uncommon Web.
次のリリースでは CLSQL と連携もできるらしい。
問題は、多少手を入れないと日本語が通らないこと。
>>565 LISP使いって聞くと、どうしても髭もじゃのキモオタ(=RMS)ってイメージが付きまとうから
そういった固定概念の除去という意味でも子供を使ったアピールってのは有効だと思う。
身寄りのない子供を預かってLISPの英才教育するネバーランドでも設営するとか。
もしFranzの誰かにメールで、 「日本語ドキュメントとかないとACL導入しにくいな〜」 とか言ったら、ドキュ用意してくれるかな? 無理かw
572 :
Scheme初心者 :05/03/14 15:10:28
(define (disp-list-of-lists a) (cond ((null? a)) (else (display (car a)) (display "\n") (disp-list-of-lists (cdr a))))) ((1 2 3)(2 3 4)(3 4 5))というようなリストの入れ子を (1 2 3) (2 3 4) (3 4 5) と表示したく、上のコードを書いたのです。このコードの添削お願い。 これみたいに帰結節が複数の式を含む場合、ifは使えないかな?
beginね. (define (disp-list-of-lists a) (if (not (null? a)) (begin (display (car a)) (newline) (disp-list-of-lists (cdr a)))))
574 :
デフォルトの名無しさん :05/03/14 16:00:04
Schemeの健全なマクロと伝統的なマクロではどう違うのか。 伝統的なマクロではどういうときに不都合が起こるのか教えてプリーズミー
>>574 伝統的なマクロでも不都合は防ぐことはできる。
そういった対策を自動でやってくれるのが健全マクロ。
何が不都合なのかというと
(define-macro (hage test . body)
`(let ((var ,(test))) (var ,@body) (var ,@body)))
こんなマクロを作った場合にvarという名前が既に環境に入ってたら意味が違ってくる。
これを以下の様に直すと不都合がなくなる。
(define-macro (hage test . body)
(let ((var (gensym)))
`(let ((,var ,(test))) (,var ,@body) (,var ,@body))))
こういう事を自動でやるのが健全なマクロ。
でも健全マクロは冗長で独自の構文を覚えなきゃならない意味で個人的に嫌い。
>>575 varだけじゃなく、hageが使われる文脈でletが束縛されていると
(普通は)困ったことになる。これはgensymじゃ防げない。
Schemeはそのへんに妙なこだわりがある。
CLは「letを束縛するような奴はいねえよ」で済ませるんだが。
>>577 CLはパッケージがあるし、変数と関数の定義空間が違うから、基本的にはその手の
トラブルは起きにくいと言えるね。
>>577 そうかあ。
まあそれってSchemeのキモイとこの1つだよね。
そういう心配してる割にパッケージとかの名前空間周りの改善が一向に見られないし。
Javaのパクリでもなんでもいいから適当なモデルを決めて欲しい。
Schemeってそのまま人間が使うより、 その上に適当に使いやすい人間様用のレイヤを被せて使うべきなんだよ。 MIT Scheme+とか。
>572 (define (disp-list-of-lists a) (for-each (lambda (x) (display x) (newline)) a))
Schemeキモイか?
あれは妥協することなくDo the right thing.を徹底して貫く姿勢を維持してる
結果じゃないの? 適当なモデルとかで決めちゃうんじゃなくて全員が納得しない限り
規格には採用しない、っていうのは何でも取り込んで言語仕様がカオスになるよりは
いいと思うけど。処理系毎に色んな実験を試みるのも推奨してるみたいだし。
あと
>>571 日本語ドキュメント用意した見返りに何ライセンス購入する? 向こうもビジネスなんだぜ。
ACLって1ライセンスいくらよ?
>>567 | 個人的に、フランツがACLの日本語のドキュメントを
| 本にすりゃいいのに、と思う次第。
詳細きぼんぬ。買うと日本語のドキュメントついて来るの? 内容いい感じ?
ポールの本とは違うの?
日本語ドキュメントって別に要らない気がするけど… そもそもFranzって日本法人なんて無いんじゃなかった? まぁもし日本語ドキュメントが必要なら、 日本語ドキュメントを簡単に整備するための Lisp ベースのシステムを作る、 ってのはどう?
で、日本語ドキュメントを整備するためのシステムが出来た時点で満足すると。 なんか火事になったときの数学者と科学者とエンジニア(だっけ?)の小話みたいな…
Gaucheを皆で盛り上げよう!
まず隗より始めよ。
Allegro Common Lispのマニュアルとか、aserverのマニュアルとか の日本語版があればな〜。
Gaucheなんだが、不完全文字列というものは必要? 文字の列の文字列とバイト列(u8vector)との区別だけで十分。 APIも、あるところではu8vector、別のところでは不完全文字列と いうように統一感に欠けるような。
>>592 だいぶ昔にMLで話題になってたような気がする。不完全文字列は無くす方向とか。
わろた
素朴な疑問なんだが、日本語のドキュメントがあると何か状況が変わる? そんなに日本語日本語いう理由を列挙してみて欲しい。 Franz Inc.の人もココ見てるから何か反応あるかもよ。
Franz Incの人見てるの? ふざけた値段設定やめて。
>>598 ワロタ。
ほんじゃいくらだったら妥当な価格だと思うかとか議論する?
初心者スレでやった方がいいような気もするけど。
あとACLが商用Common Lisp処理系の頂点に君臨しているみたいな
暗黙の了解があるみたいだけど、LispWorksユーザとか、Scieneerユーザとかの
意見も聞きたい。取っ付き易い環境とか日本語がとか言うならゲイツOSの上で
Cormanを日本語化するとかどうよ。あれ200ドルくらいでソースコード付いてるよね?
つか技術者で英語が苦手です、って正直どうかと思うぞ。
英語ドキュメントしかないからその技術には手をださない、なんて奴は
日本語ドキュメントがあっても手を出しゃしないよ。
価格の話もスレ違いだろ。
>>588 詳細キボン
601 :
572 :05/03/15 23:42:26
>>573 >>582 ありがとです。define,lambdaの直下のとき以外でも、beginで複数の式を連続して書けるのね。
for-eachってのもあるのね。
>>599 某とかゲイシの所の開発環境くらいの値段だろうな。
日本語でドキュメントと統合開発環境が揃って、2〜3万円とかいうパッケージを出せば それなりに市場性はあるんじゃないかとは思うよ。裾野を広げるのも大事だと思うな。
数十万円が妥当
>>599 LispWorks、以前開発中のプログラムでベンチマークしたときは ACL の倍くらい
速かったよ。(どちらも無料版での計測だけど)
結構良い印象を持っている。(でも cmucl のほうがさらに速かったけど)
ちなみに同じ計測でインタプリタ最速は CLISP だったと思う。
無制限の配布ライセンス付きで20万くらい。
いつ撤退するか教えてくれますか。
小俣さんガンガレ
>>600 一PGに限ればそのとおりだと思うよ。
でも導入のために上司説得したりする時に日本語ドキュメントないと
結構辛いんだわ。協力会社・派遣・外注にLisperの募集かけてすぐに
頭数揃うと思う?JAVAerでも揃わないのに。
だとするとLispの教育ってコストをかけなきゃいけない。
そのときに英語という余計なコストがかかる、と聞いて上司がいい顔
するわけないだろ?
趣味と仕事を一緒にするなってw
頭数が必要ならJavaにしとけ。 言語を何とか教えたところで、経験ない連中と一緒だと、高階関数×、マクロ× みたいな条件で書く羽目になるぞ。
確かにLispは趣味的に惚れこんでる奴多そうだな。 だけどLispで何人も使うような仕事ってあるのか? どうせ少人数でやるんだから、 英語なんかに抵抗なく、新しい言語を覚えるのにも抵抗のない、 優秀な奴集めようぜ。 頭数がいるような仕事はJava、ってのは禿しく同意。 Lispは逆。
Lispが流行るということは、LispがJavaやVBのように使われるということであります。
615 :
デフォルトの名無しさん :05/03/16 09:53:32
>611 じゃあRubyにしとけや(プゲラ
おいおい、仕事にLisp使うってネタだろ??? Lispは素晴らしいとは思うが、使える奴が少なすぎる。
ま、おのおの立場があるようで・・・。
とりあえず
>>593 を訳すよ。
できたら
>>611 にもあげるから。
>>611 Lisperとjava技術者だったらjava技術者の方が集めやすくない?
なんでLispなわけ?
初心者スレのほうで会社にACL導入しようとしていた人がいたけど、
同一人物?
>>618 それはレベルの高い海外で、その中でも偶然PGがレベル高かった
から成り立った事例だよ。
所詮島国。 日本では仕事で使われる言語や処理系の定番というものがほぼ固定化してる。 それにテンプレートやOOに振り回されて他の概念にまで手が回らないんだろう。 総人口で考えても向こうは仕事する人数ぐらいは集まりそうだが、 日本ではLisperを見つける事自体が難しい。 Lispで仕事したかったら海外に飛んだ方が早い。
(((())))系を天下のMITが教育に取り入れてるからってのもあるかもな。ないか。
海外でもあんま変わんないよ。 Lispで仕事したかったら自分で事業を起こせ。組織に頼っちゃ駄目だ。
618も、まあそういう話でつね。 yahooに買収されてから、lisp技術者がいないからって理由で 他の言語に書き換えられたらしいし。当然その頃にはPaul Grahamの手は離れてたらしいけど。 どこの国も同じ。
あうあうあー
LISPはともかくMLはもうちょとメジャーになって欲しい。 OCamlで開発してー
ぼた?
>>623 がーん。lisp から書き直されたのか…。
その言語と、情報ソース分かれば知りたいっす。
糞言語コンビですなあ。
て、よくよく思い出すと、これ、618の原文かなにかで
読んだんだった。
http://www.paulgraham.com/avg.html から
In January 2003, Yahoo released a new version of the editor written in
C++ and Perl. It's hard to say whether the program is no longer
written in Lisp, though, because to translate this program into C++
they literally had to write a Lisp interpreter: the source files of
all the page-generating templates are still, as far as I know, Lisp
code.
628でも↑でも、S式解釈してるからLispインタープリタを相変わらずもって
るんだって主張してるけど、そのS式の部分、どれくらいLisp的なんだろうなあ。
かなり宣言的というかデータに近いもののような気もしなくもない。
雑談だとスレが伸びるなぁ。初心者スレとか質問スレとか分けた意味ないじゃん(w
>>631 ここでこういう話は特に問題ないのでは?
何が気になんの?
>>617 自ら動こうとしているおまいは立派だぜ。
おれは正直日本語じゃなくても良いけど、何かあったら手伝わせてくれ。
ただ翻訳はWikiとか使っても精度が上がらないから、
出来上がりを読んで何か言うくらいしかできないけど…
>>620 , 622
おれはLispがしたいんじゃなくて、良い仕事をしたい。
そのための良い道具がLisp、と思う。
別にlispに関係無い話というわけでもなし 他に話題があるなら積極的にふれば?
Practical Common Lispってあるじゃん。あれくらい実用に重点を置いた ドキュメントの日本語版を作る、ってのならある程度意義はあると思うんだけど。 Peter Seibelに勝手に訳して適当にウェブで晒していいか?って質問したら Apressのしかるべき担当を見付けて連絡するからちっと待て、と言われてもう10日以上・・・
ちょっと期待
>>633 訳精度はあんま期待しないでね。
というわけでAllegro Webactionsを10%程度翻訳中。
ドキュメントうんぬんより、実績かなぁ。見せて欲しいの。 Lisp/Schemeだとこんなことができるんだぜ!!っていうの、ないの? 言語間の機能比較どうねんこうねんより、実際に無料で試せる処理系の上で動く アプリケーションでLispで書かれているスゴイもの、って何? (X)Emacs/xyzzyは便利に使わせていただいてますが、それだけじゃ説得力ない希ガス。
641 :
デフォルトの名無しさん :05/03/18 03:06:30
(define (apply-multi-proc a p) (define (iter a p) (if (not (null? a)) (begin ((car p) (car a)) (iter (cdr a) (cdr p))))) (if (= (length a) (length p)) (iter a p) (error "Error: apply-multi-proc"))) (define main (apply-multi-proc '(1 2 3) '(a b c))) (define (a x) (display x)) (define (b x) (display (* x 2))) (define (c x) (display (* x 3))) このコードが動かないわけを教えてください。 (a 1)がInvalid Applicationと言われてしまいます。
main の記述がおかしいから。
643 :
デフォルトの名無しさん :05/03/18 03:26:05
どうおかしいのでしょうか?
おまいの目は節穴か
645 :
デフォルトの名無しさん :05/03/18 03:39:30
初心者ッス。あと、mainは、今ここに載せるために書いたので、 実際には別のprocedureから呼び出してます
外の a と中の a とかぶってね?
647 :
デフォルトの名無しさん :05/03/18 03:51:16
そうですね。それもエラーの原因になるかもしれないですが、 載せる前の元のプログラムはちゃんと違う名前でした。
((car p) (car a)) が ( 'a 1 ) になるんじゃない?
>>641 とりあえず main の '(a b c) -> (list a b c)。
必要なのは a,b,c ていうシンボルではなく a,b,c の値である関数だから、
a,b,c を評価した結果をリストにする必要があります。
ていうか、(map (lambda (x y) (y x)) '(1 2 3) (list a b c)) でいい気がします。
>>641 引数と関数が同じ数だと保障されてるなら、
(define (apply-multi-proc a p) (for-each (lambda(x y) (x y)) p a))
エラー付け足すなら
(define (apply-multi-proc a p)
(if (not (= (length a) (length p))) (error ...))
(for-each (lambda(x y) (x y)) p a))
(define (a x) ...)
(define (b x) ...)
(define (c x) ...)
(apply-multi-proc '(1 2 3) (list a b c))
quoteをうまく使えてないだけだと思う。
>>649 副作用を起こすのが目的みたいだからmapじゃなくてfor-eachかと。
まあ知らんけど。
652 :
デフォルトの名無しさん :05/03/18 13:55:09
MIT Schemeがいつのまにか MIT/GNU Schemeに化けとる……。
>>653 知らんかった?
木村巌さんのサイト全然更新してくんない (´・ω・`)
URL変更あったヤツとかだいぶ前にメールしてあるんだけど...
655 :
641 :05/03/18 21:46:36
ありがとです。うまく動きました。いまいちquoteの意味は理解できませんが。
> いまいちquoteの意味は理解できませんが。 それじゃだめだろ。
657 :
デフォルトの名無しさん :05/03/18 22:54:05
Allegro CL 3.0.2 を手にいれたんだけど、 これって、最近の Allegro CL と比べて使える範囲内に入る?
まえにLisp処理系を組み込んだFTPクライアントとか見かけた覚えがあるが、知らないか?
>>659 SIODっていうEXEも作れるScheme処理系のサンプルにftpクライアントがあるけど。
でもperlみたいにライブラリの整備がされてないから処理系固有になって
使いづらいと思う。
この辺ネットワークモジュールインターフェースみたいなの考えて
各処理系で使い回しできる様にならないかな。
FFIで繋ぐだけで各処理系からftp使えるようにするとか。
BSDsocketっていやらしい部分があるけど。
661 :
デフォルトの名無しさん :05/03/20 17:17:16
昨年、ある脳生理学者が、Lispハッカーがハッキングに没頭している時の脳波を計測した。 すると「人間らしさ」を司る前頭前野において、α波が優位になりβ波が低下したという。 α波はリラックスしている時に見られる脳波と言われる。 「たくさんの開き括弧と閉じ括弧が、寄せては返す波のリズムのように作用し、脳に影響 をあたえているのではないか」と研究を行ったエム博士は述べている。 エム博士はインタビューでさらに衝撃的な理論を明らかにした。 「この波形は痴呆症の患者のものとよく似ている」 というのだ。 「Lispは専門家の間ではとても危険な言語として知られています。 JavaやC++といった正統的な言語では、プログラマはよく考えてから プログラムを書かないと、実行する以前にコンパイルエラーになってしまいます。 しかし、Lispにはそのような規律が全くありません。 でたらめなコードでも実行できてしまい、エラーが起きてもそこで適当に 数値を書き換えて実行を続けることができてしまうのです。 こんな言語を使っているプログラマはものを考えなくなり、 適当に式を打ち込んで、動けば良いという習慣がついてしまいます。」
662 :
デフォルトの名無しさん :05/03/20 17:18:05
エム博士は続けた。 「考えることを止めたルーズなLispプログラマは、やがてコンピュータに合わせて プログラムを書くのではなく、あたかも自分がコンピュータを操っているかのような 全能感に囚われます。自分が一番であるというこの全能感のために、Lispプログラマ は他の言語を使うプログラマを馬鹿にし始めるのです。」 博士はそのようなプログラマの脳は「Lisp脳」になっているのだと言う。 「この感覚は麻薬のようなものです。一度溺れてしまうと、 そこから抜け出すのは容易ではありません。」 Lisp脳の症状としては、「他の言語を馬鹿にする」の他にも、 「定められた勤務時間を無視する」、「見積りを出す前にプログラムを書き上げてしまう」、 「会議でじっと上司の話を聞いていることができない」、等があるという。 Lispの一種であるSchemeというプログラミング言語は、プログラミングの入門教育 で使われることがある。そのことにインタビュアーが触れると博士は激昂した。 「それは殺人教育です。アメリカでは軍事予算でLispの研究をやっている。 日本でも最近はゆとり教育だの何だのと言って子供に好きなようにやらせている。 もともと日本には、芸事はまず形から入るという文化があった。 師匠の真似をして、一通り形ができるようになって、それから心がわかるのです。 まずは紙の上で、誤りが一切無いプログラムを書けるようになるまで修行すべきです。 私が学生の頃は皆そうやっていた。」
663 :
デフォルトの名無しさん :05/03/20 17:23:23
また最近の研究では、Lispプログラマの能力と、高機能自閉症の一種であるアスペルガー症候群 との間に関連が見られるという。「Lispで自閉症になるんです」エム博士はこう断言する。 「コンピュータを自由自在に操れる全能感に溺れ、自分の殻の中に閉じこもるのです。」 博士は一枚の紙を取り出した。「典型的なLispプログラムの見かけはこのようなものです。」 ((((;゚Д゚))) 「ほら、冷汗をかいて震えている人間のように見えませんか。これはLispプログラマの対人恐怖 という潜在意識がプログラムコードの上に滲み出ているからなのです。」
664 :
デフォルトの名無しさん :05/03/20 17:24:56
((((;゚Д゚))) ↑ LISP脳のおまいらw
667 :
デフォルトの名無しさん :05/03/20 20:14:44
訳文の公開許可をフランツに問い合わせたのに、 全然メールが来ない・・・ 許可されたと思っていいのだろうか?
いいわきゃないだろ
だよな しかし、このままでは徹夜の労が無駄になるな
その労を別のものに使え。
671 :
デフォルトの名無しさん :05/03/20 21:46:07
GaucheをWin2kのcygwinで使ってますが、 (use srfi-4) で単一型ベクタのモジュールを使おうと思ったのですが、 failed to link "libgauche-uvector" dynamically: dlopen, Win32 error 193 ってエラーが出てきてうまくいきません。どうしたらいいのでしょうか? Winの対応は完全ではないようですがそのせいでしょうか。 (use srfi-1)はできました。
193 ってことは ERROR_BAD_EXE_FORMAT ? ファイル壊れてるんじゃね?インストールし直してみたら
673 :
デフォルトの名無しさん :05/03/20 22:44:57
どうもuvectorだけuseできないみたいっす。 とりあえず普通のvectorで書いて、ひまを見てインストール(コンパイル) しなおしてみます。
674 :
デフォルトの名無しさん :05/03/20 23:30:45
Gaucheでもうひとつ質問っす。 byteのlistから作ったvectorから、マルチバイト文字列に変換する方法を教えてください。 (list->string (map integer->char v))) だと日本語は文字化けしちゃいました。
あんま処理系固有の話はMLかなんかで聞いた方が早いかと。
MLって書くと紛らわしい。
MastersLeague
推論してくださいよ
MoeLisp
>>674 「文字」と「バイト(オクテット)」は別物と思った方がいい。
低レベルでふたつを変換するにはu8vector->stringとかがあるけど、
srfi-4が使えないってことなら、output-string-portを作って
write-byteしてからget-output-stringしたらどう?
682 :
デフォルトの名無しさん :2005/03/21(月) 20:46:48
syntaxについて教えてください。 R5RS英語版p.14にある例が理解できません。 whenがあるmacroとして定義されているとき、 (let ((if #t)) (when if (set! if 'now)) if) => now となるのですが、評価の過程でどのような順に 「if」が置き換えられていくのでしょうか? whenのマクロ定義の内部で使われている「if」が 置き換えられないことはわかります。
683 :
デフォルトの名無しさん :2005/03/21(月) 20:53:29
682です。 もう少し具体的に言い換えますと、ソースコード中に現れる最後の3個のifが なぜ#tに置き換えられてしまわないか、という質問です。
684 :
デフォルトの名無しさん :2005/03/21(月) 20:56:35
683です。訂正します。 誤「最後の3個の」 正「最後の2個の」
TSPL読め。
686 :
デフォルトの名無しさん :2005/03/21(月) 21:35:26
>>685 ありがとうございます。
TSPL読んでもよくわからなかったので質問させてもらったのですが…
マクロ展開と引数の評価の順番が理解できていないのかもしれません。
先にマクロ展開、そのあと引数の評価、という順番で評価が進むと考えて
よいのでしょうか?
そのとき、展開後のコードに含まれるシンボルは、通常のスコープとは異なる
スコープをもつということなのでしょうか?混乱してます。
687 :
デフォルトの名無しさん :2005/03/21(月) 22:08:32
688 :
デフォルトの名無しさん :2005/03/22(火) 00:13:01
LISPを学ぶとCなどのプログラミングの勉強になるといいます。 確かに、LISPで学んだアルゴリズムやリストの使い方をCでアプリケーションを 組んだときに活かすことができれば、美しいプログラミングができそうです。 そこで、LISPでのリストの処理をする関数などがCから利用できるライブラリのような ものはないものでしょうか? また、みなさんはもし、CやJAVAなどでLISPで学んだことをどのように活かしておりますでしょうか?
>>683 (let ((if #t))
(when if (set! if 'now))
if))
はマクロ展開されると、だいたい
(let ((#:if1 #t))
(if #:if1 (begin (set! #:if1 'now)))
#:if1)
な感じになる。というわけで結果はnowとなる。
こんなんでいいのかな?
690 :
本田 :2005/03/22(火) 20:35:55
>>689 マクロ展開した結果じゃなくて、
工程を聞いてるんだと思うけど。
そういってもなあ。解釈時の展開と実行時の束縛を混同しているように思える。
693 :
デフォルトの名無しさん :2005/03/22(火) 22:14:32
>>689 >>691 682-684です。早速ありがとうございます。
689さんの展開結果の疑似コードはマクロ展開の行程を
推測するのに参考になります。
マクロシンボルは通常のスコープにあるシンボルと
かち合わないような名前に変更されて置換される、
と理解しました。
686の最後に書いた「展開後のコードに含まれるシンボルは、
通常のスコープとは異なるスコープをもつ」というのは
だいたいこのようなことを想像していて、それを書いた
つもりでした。
ただし、この例の場合はさらに複雑で、letのスコープも
絡んできますよね。
689さんの説明では、letブロックの中のシンボルも
置換されてしまっていますが、マクロシンボルの置換の
対象になるのは飽くまでも(when ....)のブロックの内部
だけに限られますよね。
(689さんが説明のためにすべてのシンボルを置換されたのは
理解していますが、厳密にいうと、です。)
結局、まず(独自のマクロシンボルのスコープを用いて)マクロ
展開が行われ、その後、展開式の評価が通常のメカニズムで行われる、
と理解できかけているような気がします。
まだ完全にはわかっていない感がありますので、もう少し考えてみます。
どうもありがとう!
694 :
デフォルトの名無しさん :2005/03/22(火) 22:16:59
>>692 693です。まさにそういうことみたいですね。
あれで納得したならいいけど。
696 :
デフォルトの名無しさん :2005/03/22(火) 22:23:28
694ですが、 「そういうこと」=「解釈時の展開と実行時の束縛を混同している」 という意味でした。
697 :
本田 :2005/03/22(火) 22:30:34
WindowsXPでclispを起動したら↓こんなエラーメッセージが出てしまいました。 *** - invalid byte #x83 in CHARSET:ASCII conversion clispはcygwinのインストーラでインストールしました。 エラーが出たからといって動作に不都合はないみたいなんですが、気持ち悪いので できればなんとかしたいです。解決方法知ってたら教えてもらえませんか。
R5RSでScheme勉強中なんですが、以下の"implicit forcing"を備えた実 装ってどれぐらいあるんでしょうか。ちょっとググった限りでは見つけ られませんでした。 + Some implementations may implement "implicit forcing," where the value of a promise is forced by primitive procedures like `cdr' and `+': (+ (delay (* 3 7)) 13) ==> 34
>>698 export LANG=
してから実行するとエラー消えたりしない?
701 :
698 :2005/03/25(金) 00:46:48
>>700 アドバイスありがとう。でも残念ながらダメでした。
特に特殊な環境や設定で動かしているわけじゃないのになんでなんだろ。
703 :
698 :2005/03/26(土) 02:08:43
なんかpython 3000ではlambdaだけでなくmapやreduceも捨てるといってるそうだが、 リスト内包表現って構文であって、 その操作自体をfirst class objectとして扱えないよね? つまり持ち運ぼうと思ったら関数を定義して名前を与えざるを得ないよね。 その場合のための統制語彙があるに越したことはないのに、 「俺様が理解に詰まるものは捨て捨て」 だそうだ。何考えてるんだ。もったいない。
別に理解に詰まってるわけじゃないだろ。 しかし、なんで捨てるんだろうな。 俺が知ってるのは、Lispが他の言語より優れてるというgrahmaの意見に対する Python側の反論で、lambdaはPythonコミュニティでは失敗とみなされてる ってのがあったんだけど、なぜだかは知らない。 もしかしたらlispの方が優れてると言わせたくない思惑があるのかも?
pythonで匿名関数を扱うにはどうすれば良いですか
名前欄を空にする。
>>705 >Python側の反論で、lambdaはPythonコミュニティでは失敗とみなされてる
>ってのがあったんだけど、なぜだかは知らない。
素人にはお勧めできないから。
lambdaかっこいいのに・・
まぁ所詮 Python は Lisp ではなかったってことだな。
711 :
デフォルトの名無しさん :2005/03/26(土) 17:03:45
Lisp ってすごいよね、ほんと。 最後まで生き残るんじゃないかな。
細々とな(w
>>705 > grahma
grandmaに見えた。Lisperおばあちゃんw
Lispばあさん。誰か物語書いてー
ぼくの おばあちゃんは 明治生まれのLisper 再帰 高階関数 なんでもどんとこいさ λにmapcar クロージャをapply マクロでDSL オブジェクトも楽々 CLOSでさくさく 得意の総称関数
うは。「コンピュータおばあちゃん」を知らない世代?
知らない世代ならば逆に喜ばしいことじゃないか
ハッスルばあちゃんなら知ってるが。
実写版いじわるばあさんなら知ってる。 あれは世界観が最高だった。
コンピュータおばあちゃん世代だらけとは加齢臭漂うスレだな
俺は真っ暗森世代だよ
724 :
:2005/03/26(土) 23:04:22
サーバサイドのプログラムなのですが、 lisp で書き溜めたいつくかの処理があってこれをCから使いたい のですが、こういう処理って fork→exec してパイプでつないで結果を得る、 みたいな方法になるんでしょうか? clispとCが連携しているケースのソースなんか あったら参考にしたいのですが、参考になるプロジェクトとか サイトとかありませんか?
Lispはpythonよりも最先端の言語だよ。
Common Lisp やばい。。。 今勉強してるんですが、まじ感動してます。 ほら、そこのリスパー! 俺に質問してみれ
>>727 car板とcdr板があるのにcons板がないのはなぜですか
729 :
デフォルトの名無しさん :2005/03/27(日) 09:27:20
Emacs Lisp でファイルをプログラムに入力して、その内容により midi 作るってことできるのかい? いや、できるのはわかっている。 でも、それを簡単にする Auxiliary パッケージはあるかい?
>>728 Vacuous.
car板とcdr板なんてないじゃん。
cons は List (ってかツリー) をCONStruct するんだYO.
(cons (cons (cons ... ) ... ) ... )
の一番外側の cons をツリーのルートと見てもよい。
わかったか。 > リスパー
731 :
デフォルトの名無しさん :2005/03/27(日) 09:31:54
昔、スコーンというおかしがあった。 てか今もある。 cons は スコーン => scon => sconsconscon => cons cons cons という見方もあるのである。
732 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/03/27(日) 09:34:35
isomorphism が大切。 例えば、上の例の `sconsconscon' の先頭 `s' と 一番最後のキャラクター `n' をくっつけてみると、一つの輪ができる。 この時、この輪は consconscons とも sconsconscon とも 解釈することができるのであるYO. わかったか >lisper
735 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/03/27(日) 10:03:19
俺はまだリスパーではない。 ヽ(`Д´)ノヽ(`Д´)ノヽ(`Д´)ノ
お前つまらないからもうカエレ
例えば、上の例の `こちんこちんこちん' の先頭 `こ' と 一番最後のキャラクター `ん' をくっつけてみると、一つの輪ができる。 この時、この輪は ちんこちんこちんこ とも こちんこちんこちん とも 解釈することができるのであるYO. (・∀・)
738 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/03/27(日) 10:17:52
Re:>736 お前が帰れ。 Re:>737 Topology でも学べ。
>>726 ついにDrSchemeも日本語使えるようになったのか。
やっと使える処理系になったな。
>>726 おお,よく知らせてくれた.
ここに書いてもらわなかったら,絶対視界に入らなかった.
カァ クダァ ((・∀・) . (・∀・))
ス コーン ((・∀・) . (・∀・)) car + cdr == whole list + オペレーションは CONS つまり、スコーン!
743 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/03/27(日) 12:50:25
まちがってサゲちまった
↑ 新種のスクリプトですか?
なんで荒らされてんの?(w
746 :
:2005/03/27(日) 13:07:45
むずかしいことには誰も答えられないんだね
なぜcons板がないかっていうこと?(w
(nth 1) (nth 2)
>>726 日本語がぁ!感激です。・゚・(ノД`)・゚・。
750 :
デフォルトの名無しさん :2005/03/27(日) 13:58:12
>>726 MrEd でも日本語使えるようになってる?
なってる
752 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/03/27(日) 14:38:05
Re:>749 やったじゃん
>>752 ぱんつって何かおもしれ〜www
何気に変なこと知ってるし
(・∀・)
Re:の後にレス番を続ける形式を何回か見たことあるが、全てトリップ付きのかなりな厨だった
なんかキチガイが暴れてるな
呼びましたか
拡張子がpltなファイルがあったんだけど、 どうやって解凍すんの?
Windows2000/XPでDrSchemeをインストールして、*.scmファイルをダブルクリック起動すると、 *.scmファイル中の日本語が化ける。 Definitions Window内で日本語入力した場合は、化けずにちゃんとSJISで保存できるのに。
Definitions Window から保存すると UTF-8 になってるはずだよ。 他のエディタで書いたものを読ませたいなら、UTF-8 にすれば問題なし。
762 :
760 :2005/03/30(水) 09:34:32
ほんとだ。Definitions Windowからのは、秀丸が自動的にUTF-8で読んでた。
いつの間にか SBCL と SLIME の組み合わせでも UNICODE が使えるようになってた。 CL-USER> (length "ほげ") 2 CL-USER> (aref "ほげほげ" 3) #\げ CL-USER> (char-code #\λ) 955
764 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/03/30(水) 17:52:33
Re:>ALL みんな、最近どうだ? Re:>754 やあ。 Re:>757 吾と寝ろ。 >大原ゆき
数学板のうんこコテじゃないよな
766 :
デフォルトの名無しさん :2005/03/31(木) 08:27:02
S式とXMLの相互変換というのをやりたいのですが、 それっぽいライブラリがもうあったりしますか?
>>768 うひょ、リーダでそのままXML読めるのか。面白いな。
>>770 う〜ん もう一つひねりが欲しかったな。座布団は出ないかも。
>>771 ひねり?ハァ?
そのまんまだろ。
何か問題でもあるのか?
ふと思ったんだが、v3.00からしてネタだったり....まさかそんなことないか(笑
774 :
デフォルトの名無しさん :2005/04/04(月) 06:51:31
cygwinでGauche-0.8.3使ってます。 windows形式でのパス(C:\cygwinとか)を元にファイル操作をするには どうすれば良いでしょうか? string-trの使い方を分かってないみたいです。
cygpath
776 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 10:37:00
お ね め \ \ ん ら だ つ Y ま O ん
777 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 15:59:31
吾はプログラマーではない; 論理学者であるぞ 貴様等とは格が違う
779 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 16:06:43
>>778 主に数学論理である
それとモダン論理システムにも手を出している
相手にするなよ
ボロが出ないうちに去った方がよいぞよ
783 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 16:11:43
Modal 論理、Conditional 論理、 Relevant 論理などである
785 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 16:12:34
貴様等とは格が違う ふぁふぁふぁふぁ
787 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 16:15:39
ところでこのスレッドに Lambda Calculus を完全に修得した者はおるか?
789 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 16:20:05
なあ、コテハン変えてもいい? なんか発言といまいちマッチしないねん
790 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 16:23:58
(´・ω・`)ショボーン
>>787 このスレにいるならラムダくらい使うだろ。
「完全」ってのがどの程度かは知らんが。
>>789 このオレが名付け親になってやろう。
貴様は「フルーツジョッキー」だ。
792 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/05(火) 16:31:04
君は Lambda 関数と Lambda Calculus を一緒にしていないか? >このオレが名付け親になってやろう。 調子にのんなばか。
いちおう初歩的な数理論理学とアルゴリズム論ぐらいなら知ってる。
「完全に修得」って秘伝の武術みたいだな。w
一子相伝だったりして
ぱんつマニアアアアアよ、説明せよ。
フルーツジョッキー(formerly known as ぱんつマニアアアアア)ってばタイミングよく入るCMみたいだな。 でも番組が再開したら消えろよ。
(´Д`) フルーツジョッキーてなんずらと思てぐぐってみたけんど、なんもヒットしん。。。
>789 うんこイータアアアアアア でじゅうぶんだろ
800 :
800 :2005/04/05(火) 20:23:47
最近LISPとForth作ったんだけどよ Forth意味不明だった Forthはワード定義と制御構造が無茶苦茶汚くなる やっぱ一貫性のあるLISPだよな まあGCイラネって意味ではRPNも良いんだけどよ
802 :
800 :2005/04/05(火) 21:43:02
ForthはRPNだとか言いながらワード定義や制御構文は それに全然従ってねえってことよ
803 :
800 :2005/04/05(火) 21:44:02
LISPは(アクション 引数〜)で一貫環てるじゃねーか 括弧のネストがウザイけどな
括弧は見易い!
Python みたいにインデントで構造を表すLispとかあったら面白いとおもわんか? 面白いだけだが。
ML系の方が見やすいわ。
>>805 二次元構文って何がいいの?メリットがよくわからんのだけど。
>>807 他人のプログラム読むときに変なインデントになってる心配がない。w
Python 書いてると、明示的に閉じないせいか、ズボンのチャックを 空けっぱなしのような不安感がつきまとう。
あるある。結構無理して;を書かないようにしてる。 あんまりPythonやってるとCで書いてる時に閉じ忘れたり。
811 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/06(水) 11:28:13
Re:>805 つまらん
812 :
デフォルトの名無しさん :2005/04/06(水) 20:28:46
コールド・ジン みたいでかっこいいな。
814 :
デフォルトの名無しさん :2005/04/06(水) 22:22:18
情報システム板で古典パンにやられてる屑コテハンが、 こんなところで暴れてるのな。悲惨
815 :
デフォルトの名無しさん :2005/04/06(水) 22:26:15
しかも、Lispが最高だとか未だに勘違いしてる馬鹿っぷり。 うんこだな
判りやすい馬鹿はスルーでよろしく
817 :
デフォルトの名無しさん :2005/04/07(木) 00:39:55
馬鹿とはスレをあげてる奴の事ですか?
818 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/07(木) 14:20:26
Reply-to:
>>814 > 情報システム板で古典パンにやられてる屑コテハンが、
> こんなところで暴れてるのな。悲惨
吾はそんな板に出没したことはないぞ。
____________
"Self" is that which is in the process of becoming... --Zeno
Today's Lucky Number: 348
内容が無い言い訳をいちいちする辺り、奴とそっくり
ぱんつ以下略って2chぶらうざで書いてないのか?
821 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/07(木) 20:43:32
Reply-to:
>>820 > ぱんつ以下略って2chぶらうざで書いてないのか?
いや、navichだな。
Reply-to:
>>819 > 内容が無い言い訳をいちいちする辺り、奴とそっくり
その「奴」ってのは誰だ?
____________
If T is consistent, T !|- G_T.
ぱんつ以下略ってもしかして就職活動中? この業界にLISPの仕事はないよ。
823 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/07(木) 20:52:08
Reply-to:
>>822 いや、今のところ違うが。
____________
If T is consistent, T !|- G_T.
if T is ω-consistent, T !|- ¬G_T.
教職狙え。
825 :
デフォルトの名無しさん :2005/04/07(木) 21:05:42
いやきっと、汚いパンツくんは、Frantz Lispに入るんだろうw
あっそ言えば、情緒不安定でとみに著名な某氏の会社もあったなw
パンツの中身は、ここ数年就業経験のない無職粘着中年
828 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/07(木) 21:10:14
Reply-to:
>>824 恐らくそれが一番楽であろう。
Reply-to:
>>825 吾は Lisper ではないから Franz にはいかないであろう。
Computer Science でいくのであれば AI 系の会社に入るだろうね
なににしてもつまらん仕事はしたくない。
____________
If T is consistent, T !|- G_T.
If T is ω-consistent, T !|- ¬G_T.
汚れパンツくん、 一週間に一度くらいはパンツ履き替えろよ あと、signature風のその見苦しい虚栄心をなんとか白w
830 :
デフォルトの名無しさん :2005/04/07(木) 21:18:37
>>829 キチガイ中年の今度のタ〜ゲットは、AIか。悲惨だなキチガイ粘着=パンツ
この子は小さい時から粘着力だけは凄かったんです。 頑張って、この粘着世界一位を目指して欲しいんです。 他は全然駄目だけど、馬鹿な子ほど可愛いって言うじゃないですか(涙
>>818 なんてsignatureもどきを Zeno ◆5nZQbNmQPs のときのまま変え忘れてるしw
834 :
658 :2005/04/08(金) 23:30:00
Schemeで自作ゲームのマップ自動生成ツールを作成中。 って、道のりは遠いが。 Lispは S式で何かデータを記述 → S式のデータを元に別のデータを出力 だと異様に生産性が高いね。 Paul Graham氏のViawebはそんな感じか?
>>834 だよね。XMLの代わりにS式が流行ってたら俺たちの天下だったのにな。w
まぁちょちょいのちょいで変換できるからいいけどさ。
macro & sexp マンセー。 `(,foo ,@bar ,(baz ))
>>834 別にS式だから生産性が高いというわけではなくて、関数型の一般的な性質。
Lispは副作用もかけるけど。
>>835 SGMLのスタイルシートの記述言語 は、Schemeだたーよ。
でも流行らなかった罠。
>>837 例によって例のごとく、ズレまくった発言して、
フレーム議論でも始める準備ですか(呆
>>839 ずれまくるのは仕様です。
なぜなら、最後の3レスぐらいしか読まないから。
何の仕様?
>>841 俺の仕様。3レスぐらいしか読まないっていう仕様。
それは仕様じゃなくてバグじゃないのか?
>>843 そやないよー。
コンピュータでの数値計算だって1/1+1/2+1/3+…の計算をするとき、実際には有限回の計算しかしないよね?
レスだって有限とは言えたくさんあるのでPart1から全て読むなんてことなんてしないもん。
俺は読む量がちょっと少ないだけ。
せめて fixnum レス分くらい嫁
kusosure
korosuke
>>846 普通は10ビットか20ビットくらいあるはず
>>842 氏のfixnumは2ビット(-2〜+1)でつ
う〜ん、違うなぁ。3レスぐらいっていうからには4レスという可能性もあるわけだ。 たぶん平均3の正規分布になるだろうね。
> 4レスという可能性もあるわけだ。 そーゆーときはbignumで対処しまつ
LISPの一部のコードに型推論を実装することってできるよね。 誰かやってよ。 最強に生まれ変わるよ。
既にLISPは最強ですがなにか?
855 :
ぱんつマニアアアアア ◆6Vxxv8cFbA :2005/04/09(土) 18:40:37
「何かが最強」であると考慮する時、それが何を相対として、 何について最強であるかが述べられていない場合、 その行為は全くもって無意味である。 ____________ If T is consistent, T !|- G_T. If T is ω-consistent, T !|- ¬G_T.
>>853 多くのCommon Lispコンパイラは既にやっている。
もちろんdeclareがあればそっちを優先するけど。
多くのって・・ 具体手にには何? clispはやってますか?
>>857 cmuclはやってるね。clispは中間言語コンパイラだからやってないかも。
cmuclだけ? 他には?
もしかして最適化レベルのこと言ってんの?
860は何いってんの?
>多くのCommon Lispコンパイラは既にやっている 今は「既にやっている」「多くのCommon Lispコンパイラ」を列挙する場面でつ
>>858 今ソース読んでるけどcmuclのどの辺に型推論やってるとこある?
俺はソース読んでないけどcmuclのドキュメントにはやってるって書いてあった希ガス
common lispの仕様外でしょ?
そんなこと関係ないが
で、「多くの」はどこに掛かってるわけ?
結局cmucl以外やってないということでいいですね。
cmucl自体やってるか疑わしい、と。
>>856 がさっさと列挙してくれれば一番良いのですが。
アレグロもやってる と、思う
>多くのCommon Lispコンパイラは既にやっている と思う。
「多くの」に粘着するのを見てても面白くないんで、
むしろ
>>853 の「最強」が気になる。
現存の全ての処理系に勝るには何をどのようにやればいいのかな?
認知されてない時点でやってないも同じ
はやく列挙しろよ
別にLispに型なんていらねーな。 型推論とかあっても邪魔。
型推論いるよ派 型推論やると最強だよ派 多くのCommon Lispコンパイラは既にやっているよ派 cmuclはやっているよ派 cmuclのソース見てもやっているかわからないよ派 ドキュメントにはやってるって書いたあった希ガス派 はやく列挙しろよ派 多くのCommon Lispコンパイラは既にやっていると思うよ派 アレグロもやってると、思うよ派 認知されてない時点でやってないも同じだよ派 型推論いらないよ派 型推論は邪魔だよ派
((型推論いるよ派 (型推論やると最強だよ派 (はやく列挙しろよ派) (cmuclのソース見てもやっているかわからないよ派) (認知されてない時点でやってないも同じだよ派)) (多くのCommon Lispコンパイラは既にやっているよ派 (cmuclはやっているよ派 (ドキュメントにはやってるって書いたあった希ガス派))) (多くのCommon Lispコンパイラは既にやっていると思うよ派 (アレグロもやってると、思うよ派))) (型推論いらないよ派 (Lispに型はいらないよ派 (型推論があっても邪魔だよ派))))
↑のリストに (型推論いらないよ派 (既にLISPは最強ですが抜けてますよ派)) を追加するプログラムを作れよ派
おれはむしろLISPにも静的型が書けたらいいよ派 declareとかtheとかキショイよ派
scheme派
schemeにも型推論が必要だよ派
Schemeの方がシンプルでいい。
schemeに足りないのはdeclareみたいな型指定子とパッケージみたいな名前空間だけ
↑末尾に派を付けない派
CommonLispは名前が長いよ派
schemeに型推論は蛇足だよ派
>>882 Gaucheとかはモジュール化機構があるよ派
だから何?派
Scheme は方言が多いよね派 Scheme に飽きた Guy Steele が作ったのが Common Lisp だよね派 でもそのあと Guy Steele は Java にも加担しちゃったんだよね派
SchemeはもともとLispの方言だよね派
SchemeがLISP方言なわけだが。 あとは処理系の実装の違い。
方言の使い方間違ってないか? CommonLispは言わば標準語。
標準語⊂方言 のように「方言」という単語を定義すれば矛盾しない。 Common Lisp, Scheme ∈ {Lispの様々な方言}
>CommonLispは言わば標準語 そう言い切られるとISO ISLISPが可哀想派
そもそもLispに標準を求めるのが間違いだよ派。 っていうか自分で作ろうぜ派。
どれでも受けつける処理系をきぼんぬ派
Common Lisp ↓ CommonLisp+-(Scheme) ↓ Common Lisp # ↓ ?←これ何て呼ぶんだろう
Dommon Lisp
>>899 Dommonってなんだよw
そういうのはGガンダムで勘弁な。
SchemeにCommonLispの型やパッケージが入れば、 CommonLisp不要になるんだよね。 結局わざわざCommonLisp使う理由ってパフォーマンス以外にないから。 Biglooみたいなやつから発展しないかなあ。
>>901 Gacuheの次期バージョンではコンパイラ(っていうかCへのトランスレータ)
が実装される予定だからパフォーマンス的には期待できるかも。
declare みたいなのがないと高速なコードに静的にコンパイルするのは難しいでしょ。 それよりも、最近の流行としては HotSpot みたいに実行時のプロファイルを使った 動的コンパイル&動的最適化かも。誰か挑戦しない?
An Infrastructure for Profile-Driven Dynamic Recompilation (1998) Robert G. Burger and R. Kent Dybvig International Conference on Computer Languages
905 :
デフォルトの名無しさん :2005/04/10(日) 20:49:04
>>853 あぁ〜、これだから初心者は・・・。
最初に「型変数」を実装した実装系は、
CommonLispコンパイラ。
当然、型推論も一部行っている。
>>903 Gaucheの次期バージョンで限定的に実装されるCへのトランスレータは、
VMコードをCのベクタに落とすだけなので、性能には寄与しないでしょ。
コンパイルが省略できるぶん少し早くなるだろうけど。
907 :
デフォルトの名無しさん :2005/04/15(金) 01:18:37
フジ「恋におちたら」出演おめ
908 :
デフォルトの名無しさん :2005/04/15(金) 01:26:38
ああ、中年男の日は昨日だったのか。さっくり忘れてた。
>>909 ちゃんとエンドロールに名前も出ていた。
セリフもあった。
その話題とこのスレの関係は何?
>>911 Gaucheの作者であるかわいさんが出演してたのです。
>>912 へぇ〜。つか、そういう面白いことは放送前に教えてくれよ。
しばらく前からwilikiに書いてあったよ
ドラマの件はさ〜っぱり忘れてた。誰かビデオでも撮ってないかな。 Common Lisp HyperSpecは変更点がよくわかんないけどダウンロードしとこ。 関係ないけどLispWorks 4.4のPersonal Editionまだ来ないね。 ILC2005行けばEnterprise Editionの評価版貰えるかも知れないけどウェブサイト 見る限りじゃちゃんと準備が進んでいるのかあやしげな悪寒。業務で行くのは無理か。
918 :
デフォルトの名無しさん :2005/04/20(水) 22:01:48
文字コードをeuc-jpからutf-8に変換するライブラリで lispの方言(librep)でも使えるものってありませんか?
そういう事にLISP使うのは間違ってる気がする 本来そういった文字セットとかを超越した所にS式は存在するべきなんだよ
921 :
デフォルトの名無しさん :2005/04/22(金) 01:28:15
Scheme初心者です。FAQだったらごめんなさい。 syntax-rulesで作成したマクロは通常define-syntaxで シンボルにバインドしているようですが、なぜdefineでは いけないのでしょうか?試してないけどそれもアリ? ひょっとしてマクロとそれ以外のオブジェクトとで 異なるScopeを持たせたいってことでしょうか?
922 :
デフォルトの名無しさん :2005/04/22(金) 01:41:50
921です。 試してみましたが、やはりdefineではエラーになります。 defineを使ってマクロをシンボルにバインドするような実装も 可能だと思うのですが。 そうした場合、どういう不都合がありますか?
>>922 define はあくまで変数を定義してそれに値を与える(たまたま値がラムダ式であれば
関数を定義したことになる)だけです。マクロは文法上、変数ではないので define で
定義するのは一貫性を欠くことになります。また define-syntax はトップレベルでしか
使えないなど、制約事項も異なります。
924 :
デフォルトの名無しさん :2005/04/22(金) 04:00:48
>>922 あと、コンパイルと実行が別々になっている場合、マクロはコンパイル時に
展開するのが普通だから、マクロ定義と通常の束縛とが区別できる形に
なってないと困る、ってのもある。
925 :
デフォルトの名無しさん :2005/04/22(金) 21:34:00
お前等逝けよ。 >ALL 逝けってば。 早く逝けっつってんの。
926 :
デフォルトの名無しさん :2005/04/22(金) 21:45:25
最近LISPでない言語でプログラム書いたら、 LISPの偉大さ心に染みた。
処理系実装して解るLispの(_|_)さ。
どういうところがどうだと言いたいのかさっぱりわからん。
>>927 (_|_)
↑この顔文字?の意味がわからん。
ウルトラ・・・かな
931 :
デフォルトの名無しさん :2005/04/23(土) 08:55:29
>>923 ,924
921です。ありがとうございます。
コンパイラの場合、話はわかりやすいですね。
インタプリタの場合はどうでしょうか?
(実装依存、という話ではなく、どのようにあるべきか、です)
たとえば
(define-syntax some-operation (syntax-rules ...) ;;マクロ
(define some-operation (lambda ...) ;;手続き
とした場合、
(some-operation ...)
という呼び出しは、やはりマクロ定義のほうを優先するのが順当なのでしょうか。
ただし、呼び出し時の字面は全く同じだと仮定します。
あるべき姿としては、コンパイルしてもインタプリタで実行しても 同じように実行できるのがいちばんいいんじゃないの。もっともこれは Lispが随分苦労してきた問題で、いまだにすっきりした解決は無いと 思うけど。(comp.lang.schemeあたりで、マクロと分割コンパイルの 話題を探すと色々出てくると思う) マクロと手続き、両方定義したらどうなるかっていう話は、綺麗な仕様は 無いような気がする。ナイーブに上から実行してくインタプリタなら 後から出てきた方が上書きしちゃうだろうけど、例えば別ファイルで some-operationにset!されたらどうなるかとか。921は何かアイディアがあるのか?
933 :
デフォルトの名無しさん :2005/04/23(土) 09:59:05
>>932 >921は何かアイディアがあるのか?
何もありません。ただ、R5RSをみても、define-syntaxの説明があまりにも
簡略でdefineとの関係がよくわからなかったのでおたずねしました。
Scheme勉強中なのでできるだけ実装系に依存しない理想的な挙動をイメージ
しておきたかったのですが、
[1]コンパイラなら話は簡単(924のように)
[2]インタプリタでもコンパイラと同じ挙動が期待される(932のように)
[3]ナイーブに上から実行してくインタプリタなら後から出てきた方が上書き(932のように)
ということですね。
931に挙げた例だと[2]と[3]とは矛盾することになりますが、
[2]は人間様にとって実装によらず常に同じ結果を返すようにするように期待したもので、
本来の「自然な」Schemeの振る舞いは[3]のほうである、と理解しました。
しかし、もし[3]の立場をとるとすると、define-syntaxとdefineとは同じscopeを
共有することになり、define-syntaxの存在意義がよくわかりません。
>>923 さんは「マクロは文法上、変数ではない」と書かれましたが、
マクロを変数に「バインドする」ことならやってもよいのでは?(初心者です)
define-syntaxでなければできないことって、何かありますか?
具体的な例をいただければ理解できると思います。
初心者です・・・ 人間様にはR5RS schemeのdefine-syntaxは理解できません・・・ 初心者です・・・
初心者です・・・ 具体的な例をいただけないと理解できんとです・・・ 初心者です・・・
936 :
デフォルトの名無しさん :2005/04/23(土) 10:16:56
921です。自省 コンパイラの存在なしで話をしようとしていたのが誤りだったのかも。 結局Schemeといえども単なる言語処理系であって、形而上学的な理想像を 追い求めてはいけない、ということでしょうか。
>>936 私も初心者だけど、defineとdefine-syntaxは概念として全然違うものだと思うので、
なんでそんなにしつこく同一視できると思うのかよくわからない。
ただ、うまく説明できるほどには習熟してないのでもどかしい。
あえて説明を試みるならdefineは実行環境が持っている保存領域になんかいれるもので、
define-syntaxはコンパイラ(インタプリタ)に覚えさせる指示ってカンジ?
Cでいうならステートメントや式とコンパイラディレクティブの差みたいなもの。
変なこと言ってたらスマソ。
>>933 変数値として「マクロ」を認めてしまうと、当然実行時の動的な値に従うべきということに
なるので、実際問題としてコンパイラを作るのが非常に難しくなってしまうよね。
文法上「マクロ」は通常の Scheme の実行環境の「外側」にあると考えられるわけ。
マクロ展開時の「実行時環境」を考えたくないので、手続き的な方法ではなく宣言的な
方法での定義を強制させているのだろうね。
でも、個人的には危険が危ないがなんでもできる Common Lisp 風のマクロのほうが
好きだったりするのだが。w
939 :
デフォルトの名無しさん :2005/04/23(土) 12:29:09
921です。
>>937 >Cでいうならステートメントや式とコンパイラディレクティブの差みたいなもの。
>>938 >文法上「マクロ」は通常の Scheme の実行環境の「外側」にあると考えられるわけ。
なるほどね。
個人的には、SchemeのマクロはCのプリプロセッサ的なものと理解しました。
かなり納得。
940 :
デフォルトの名無しさん :2005/04/23(土) 12:36:10
921です。939の続き。 となると、やはり933の[3]的な考えは正しくなく、どのような場合でも、 まずマクロ展開が行われてから、通常の評価が行われる、ということになりますね。 ふむふむ、納得。 間違っていたらご指摘ください。
>>940 むしろ、仮に [3] のような処理系であっても結果がなるべく同じになるように考えて
define と define-syntax を分離していると考えることもできる(ような気がする)。
943 :
デフォルトの名無しさん :2005/04/23(土) 22:49:26
jythonのようにjavaソースやclassファイルに落とせるlispの処理系って 何かありますか? javaでは面倒な処理をLispで書けが生産性があがる気がするのですが。
単発QAは荒しのサイン
>>921 schemeでシンボルといったら'nameで表されるようなオブジェクト、または
それらの型を言う場合が多い。あなたが言っているものは名前とか識別子と
呼ぶのが適当だ。もし混同していたのなら、これを機に復習してくれ。
識別子には種類が二つあって、それは(defineやlambda式で導入される)変数名
と(define-syntaxやlet-syntaxで導入される)構文キーワード名だ。
これらは同じ名前空間で管理される(別の言い方では同じスコープ規則に
従う)が、扱いは別。
(932が言っているのは、ソースファイルとかモジュールというような概念が
定義されてないschemeにおいて、それらをどう扱うかという話。)
>>933 [1], [2], [3]はなんというか視点がずれてる。
コンパイラ、インタープリタ問わず処理系は (some-operation ...) を処理
するときには二つのsome-operationのバインドのうちどちらかしか見えない
ので、その式を処理する方法は常に一つしか存在しない。
つまり、some-operationを変数名だとみなしたら手続き呼び出しだし、
構文キーワード名だとみなしたらマクロ展開だ。
そういった訳で、940でのあなたの理解は大まかには正しいということに
なる。マクロ展開が先に行なわれるというよりは、マクロ呼び出しだったら
展開するしか処理方法がないということね。
ちなみに通常は、トップレベルで二重に定義された名前は後から定義した方
が以前の定義を(概念的に)上書きするので、 (some-operation ...) は
マクロ呼び出しとして処理することになる(この辺はschemeの仕様書で探して
みたが明確な記述はなかった)。
948 :
946 :2005/04/24(日) 01:10:26
訂正。 > (some-operation ...) はマクロ呼び出しとして処理することになる ...は手続き呼び出しとして... 読み返してみると日本語ムチャクチャだな...
jil.faslが存在しない〜〜〜なんだよ・・・
JiL? 6のトライアル版でも使ってんの?
>951 faslは見つけたんだが、require出来ん。 Trialでは無理なのかな? これでjavaコード全部書いてやろうと思ってたんだが。
トライアル版持ってないから力になれない。Franz Inc.に直接問い合わせてみれば?
954 :
デフォルトの名無しさん :2005/04/26(火) 00:54:26
921です
>>946 >もし混同していたのなら、これを機に復習してくれ。
なるほど。ご指摘ありがとうございます。
>some-operationを変数名だとみなしたら手続き呼び出しだし、
> 構文キーワード名だとみなしたらマクロ展開だ。
結局、手続きとマクロ展開とはつくられたときから全く別の
ものであり、参照のためにそれぞれ変数名や構文キーワードに
関係づける際に、それぞれdefineとdefine-syntaxを使う、と
理解しました。
ただし、
>「これらは同じ名前空間で管理される(別の言い方では同じ
>スコープ規則に従う)
わけですね。
そうすると、マクロと手続きとは並列的な関係にあるオブジェクトであって、
>>946 さんは婉曲に
>そういった訳で、940でのあなたの理解は大まかには正しいということに
>なる。
なんて書いてくださいましたが、私が
>>939-940 で納得していた
「Cプリプロセッサ的解釈」はちょっと違いますね。
compiler(およびそれと整合的なシステム)は、実行時に
マクロ展開を選択的に優先して実行するようなシステムだと
思えばいい、ということで、今度こそ納得できた気がします。
955 :
デフォルトの名無しさん :2005/04/26(火) 01:03:46
921です。補足 ちなみにcompilerそのものの場合には コンパイル時にマクロ展開するので、 最後のくだりの中で >実行時に が不要であることはわかってます。
956 :
デフォルトの名無しさん :2005/04/26(火) 01:08:10
>>954-955 キミの理解はあってると思うけど、
キミの文章は色々不要な事を言い出しちゃってて、
コミュニケーションに難がある、と思う。
このような文章を書くあなたは学生さんだと思うが。
テストの回答で、余計な事書くと減点されるって知ってるよね?
今の君のコミュニケーションは、正にそれ。くどい。
957 :
デフォルトの名無しさん :2005/04/26(火) 01:10:05
くどい=回りくどい あるいは、 正解わからずに、解答欄に三つも四つも解を書いて、 数撃ちゃ当たるだろう、という傲慢な態度が見え隠れしている。
958 :
デフォルトの名無しさん :2005/04/26(火) 01:15:54
959 :
946 :2005/04/26(火) 11:40:51
>>954 それでOKかと。
923とその背景を説明してる924はよく出来てると思うので、迷ったら読み
返すといいかもしれない。
960 :
デフォルトの名無しさん :2005/04/26(火) 23:12:08
961 :
デフォルトの名無しさん :2005/04/27(水) 23:44:00
CPSにコンパイルする処理系ないですか もつろんSchemeでさ
rhizome/pi "完全なCPSによる実装である"らしい。