CommonLisp Scheme Part12
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNGPart1: http://piza2.2ch.net/tech/kako/987/987169286.html
Part2: http://pc.2ch.net/tech/kako/1002/10025/1002584344.html
Part3: http://pc.2ch.net/tech/kako/1008/10082/1008220265.html
Part4: http://pc.2ch.net/tech/kako/1016/10162/1016211619.html
Part5: http://pc3.2ch.net/tech/kako/1023/10230/1023091882.html
Part6: http://pc3.2ch.net/tech/kako/1031/10315/1031560687.html
Part7: http://pc5.2ch.net/tech/kako/1042/10421/1042167213.html
Part8: http://pc5.2ch.net/tech/kako/1058/10582/1058263391.html
Part9: http://pc2.2ch.net/test/read.cgi/tech/1069594582/
Part10: http://pc5.2ch.net/test/read.cgi/tech/1075630259/
Part11: http://pc5.2ch.net/test/read.cgi/tech/1091456033/
関連リンクは>>2-10あたり
0232デフォルトの名無しさん
NGNGわかりました。しかし、Gaucheにはないようなのですが、何か、
深い理由でもあるのでしょうか?
作るならこう?
(define (atom? x)
(and (not (pair? x))(not (null? x))))
0233デフォルトの名無しさん
NGNG0234デフォルトの名無しさん
NGNGと思うんですが、define-macroみたいにメタな場合分けってできないんでしょうか。
だとしたらパワーが全然違うと思うんですけど。
0235デフォルトの名無しさん
NGNG同じ機能の not-pair? があります。
0237デフォルトの名無しさん
NGNGLW4.3との比較であればBill Clementson's Blogにベンチマーク採ったの載ってるよ。
LW4.3からLW4.4でどの程度高速化されたか早く知りたい。買わないけど。
0238デフォルトの名無しさん
NGNG世の中にはdefine-syntaxだけでquasiquoteの展開を書く人もいるわけだが....(汗
やっぱりsyntax-caseかdefine-macroがないとつらいよね。
0240デフォルトの名無しさん
NGNG0241デフォルトの名無しさん
NGNG非共有性に基づいて型を定義している以上、当然ではあるけれども。
0242デフォルトの名無しさん
NGNG研究室遊びに行って後輩捕まえて代わりに買ってもらおうかな(w
0243デフォルトの名無しさん
NGNG学生じゃなくても個人ユースならその値段で売って欲しいぞ。
0244デフォルトの名無しさん
NGNG0245デフォルトの名無しさん
NGNG同名のメソッドは引数を合わせないといけないので、
パッケージを分けたくない時は、javaとかでいう抽象クラス名みたいなものを
プレフィクスに付けたりしないと名前が被りますよね。
メッセージ伝達モデルのほうが型ごとに名前空間を分離できるし、
タイプ量も減って手軽だと思うんですけど、
普段は、そういうオブジェクトシステムを使ってるって人いないですか?
0246デフォルトの名無しさん
NGNG>>同名のメソッドは引数を合わせないといけないので、
何言ってんのあんた。
0247デフォルトの名無しさん
NGNGパラメータリストを整合的にしないといけないということです。
メッセージ伝達モデルだと、関係の無いクラスで
同名の引数の数が違うメソッドが定義されていないかなどといったことは
気にしませんから、それがわずらわしく感じないかということを言いたかったのですが。
0248デフォルトの名無しさん
NGNG言いたいことがよく判らない。
簡単なものでいいから、具体例を出して説明して頂けないか。
0249デフォルトの名無しさん
NGNG0250247
NGNG変数名 . 動詞or名詞
と普通のオブジェクト指向言語では書けるところが、
(パッケージ名:動詞 変数名)
あるいは、
(型名-動詞or名詞 変数名)
となって、タイプ量が増えて面倒だと言いたいだけです。
普通はパッケージ名は書かないのかもしれませんが、
複数のパッケージからインポートして、それぞれに整合的でないメソッドが
含まれている場合、シンボルのインポートを諦めるか、
メソッド名に基底クラス名等のプレフィクスを付けるか、
全く違う名前に変更してユニーク性を確保する羽目になります。
型の名前やパッケージ名が繰り返し書かれると、
情報の多重化になりますから、名前を変更する時も面倒です。
本当に複数の引数の型でディスパッチしたい状況というのは少なそうですから、
この負担が割りにあってるかは疑問です。
日常的に使いたくなるのはメッセージ伝達モデルの方であり、
総称関数を使いたい状況の方がむしろ特殊じゃないかと。
オブジェクトをキーワードやシンボルを引数に取るクロージャにして
(funcall 変数名 '動詞)
Schemeなら単に (変数名 '動詞)
と書けるようなオブジェクトシステムを実装するのは簡単なので
やってる人は結構いるんじゃないかと思ったのですが。
総称関数モデルとメッセージ伝達モデルのトレードオフくらい
ここの人は分かってると思ったので、単に
「メッセージ伝達モデルの奴が欲しいんだけど、いいのない?」
みたいな聞き方でも充分通じると思ったのですが。
0251デフォルトの名無しさん
NGNG0252デフォルトの名無しさん
NGNGいや、だから具体例を出してくれはしないだろうか。
何で generic function の名前に型名をつける必要があるのか理解できない。
パッケージについても、まあ名前の衝突はありうるけれども、
それがメッセージ伝達型だと何で解消できるの?
それは総称関数モデルの問題じゃなくて、
Common Lisp のパッケージシステムの問題じゃなかろうか。
取りあえず、何というか、手続きの総称化ということについて
よく判っていないのではないかという印象を受けた。
ちなみにメッセージ伝達モデルの oo については
Paul Graham の"ANSI Common LIsp" で例題として実装している。
まあ、Common Lisp でわざわざ oo 実装するやつも少ないので、
Scheme の方で探して、気に入ったのがあったら移植でもしたらいいんじゃない?
CLOS like なのしか思い浮かばないんで、紹介は出来ないけど。
0253デフォルトの名無しさん
NGNG> よく判っていないのではないかという印象を受けた。
俺も。何か気の毒だからちゃんと勉強して出直すことを期待。
0254デフォルトの名無しさん
NGNG推奨されてるのに。
0255デフォルトの名無しさん
NGNG1番目の 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)))
0256デフォルトの名無しさん
NGNGあと、それとは逆でラムダリストはたまたま合同になるけど、処理の内容が
ほとんど別のことを表しているときはどうだろう。なんとなく気持が悪くない?
パッケージで分割できればいいけど。
0257デフォルトの名無しさん
NGNGん?
今 Common Lisp の処理系が手元にないので Gauche で試したけど、
それ、ちゃんと動くよ? CLOS だと駄目だったっけ?
0258デフォルトの名無しさん
NGNGstklosとかgaucheは制限が緩い。
CLOSでだめなのは最適化かなんかの都合なの?
0259247
NGNG>>256
言いたいのはそういうことです。良い例をありがとうございます。
>>258
それは知りませんでした・・・
てっきり回避不可能に近い制限なのだろうと思ってたので。
その仕様だと、効率を除けばデメリットは無いですよね・・・
gaucheでいろいろ試してみます。
0260234
NGNGquasiquoteの展開ってこういうのじゃ駄目でしょうか?
(define-syntax qq
(syntax-rules (uq)
((_ ()) '())
((_ (uq a)) a)
((_ (a . b)) (cons (qq a) (qq b)))
((_ a) 'a)
))
理論上は define-syntaxでなんでも書けるらしいですね。
なにか面白いマクロネタありませんかね。
0261234
NGNG(define-syntax q
(syntax-rules (uq)
((_ ()) (qq ()))
((_ (uq a)) (list (qq uq) (q a)))
((_ (a . b)) (cons (q a) (q b)))
((_ a) (qq a))
))
うーん、なんか見落してる気がする。
0262234
NGNGevalじゃないだろうし、どうやったらいいか想像できないです。
unquoteがマクロ展開時に計算されるっていうのは、処理系がマクロ展開時、実行時
の2ステップに分かれていれば意味あると思うんですけど、そうでない場合
なにか意味あるんでしょうか? 計算結果は変わらないですよね。
0263sage
NGNG(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)))))))))
0264sage
NGNG見やすく書き込む方法はあるのでしょうか?
2ちゃんねる初心者です(^^;
0265デフォルトの名無しさん
NGNGなんとなくは分かるが、前半の例と後半のコードが一致しないし、typo も多いし、
正しくはどうやりたいのかがみえない。
0266デフォルトの名無しさん
NGNGとりあえず、下げたいのなら、sageはメール欄に書こうな。
0267デフォルトの名無しさん
NGNG` ' (半角スペース) を ` ' に置換する.
0268デフォルトの名無しさん
NGNG0269デフォルトの名無しさん
NGNG何がしたいのかわかんねえよヴォケ
0270デフォルトの名無しさん
NGNG説明不足でご迷惑かけました。改めて
手続き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)))))))
0271デフォルトの名無しさん
NGNG実際にやりたい処理は次です。
『'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 はいらないですね。ども。
0272デフォルトの名無しさん
NGNG下の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)))))))
0273デフォルトの名無しさん
NGNG(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))
)))
0274273
NGNG(else (iter a (car l) (lambda (b ll) (c b (cons ll (if b (rember2* a (cdr l)) (cdr l)))))))
の方が綺麗かな。
0275(define (´∀`) 'マターリ)
NGNG(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))))))))
0276デフォルトの名無しさん
NGNGLISPの思想に近いらしく、基本はすべて
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)でやろうとする場合、専用の頭が必要になる。
0277デフォルトの名無しさん
NGNG0278デフォルトの名無しさん
NGNG0279デフォルトの名無しさん
NGNGIoではifなどの構文もメソッドであるという。
メソッドというからには何かのオブジェクトに従属するはずだが、
Ioでは暗黙のrootオブジェクト(Lobby)という概念を作ってカバーしたらしい。
例えばif式だと
if(test_part, then_part, else_part)
という書き方になる。
構文要素をカンマで区切る辺りが少し不気味な気がするが、
LISPの怒濤の括弧ほどショッキングではないのかもしれない。
ここで注目したいのは、Ioの構文はメソッドであるため、
どうやらマクロの様な特殊な機構は必要ないらしい。
ただし肝心の評価順序の制御がどういう原理で行われるのか正確には不明。
(thisMessage という機構でえらい騒ぎになるらしい)
構文に対する特殊化を先送りしているだけにすぎない様な気もするが、
表向きメソッドとして統一した事に意義があるのだと思う。
ただ、構文をメソッドとして定義するということは、マクロの様に展開する機会がなく、
毎回作成した専用構文の解釈を行うということになるので、
実行効率はかなり犠牲なるはず。
マクロ的な展開機構が導入されれば解決するのかもしれないが、
その辺はかなり道のり遠そうである。
この辺を追求していくとIoの雲行きが怪しくなってくる。
ともあれ、実用性や効率に目をつむればかなり洗練された言語であることは間違いない。
0280デフォルトの名無しさん
NGNG0281デフォルトの名無しさん
NGNGLISPでもシンプルなオブジェクト指向ってできねーのかなと思って。
似た言語の筈のIoと何が違うのかなって知識の整理。
要はIoの構文はマクロの代わりにメッセージという裏技でカバーってことね。
基本概念違うから(CLOS程大きいシステムならともかく)適用してもあんま旨みがない。
0282デフォルトの名無しさん
NGNG0283デフォルトの名無しさん
NGNGおれは逆にえらい違いだと思ってるわけで。
object method1(...) method2(...)
に対して
(method2 (method1 object ...)...)
((object method1 ...) method2 ...)
やっぱ連鎖適用で括弧がネストするのは美しくないなと。
Ioでは現状おまけみたいなものだけど、
連鎖適用とメッセージを駆使すれば適当な構文が書けたりする。
if (test_part) then (then_part) else (else_part)
とか。
たぶんこれ遅いんだろうなあ。
0284デフォルトの名無しさん
NGNG0285デフォルトの名無しさん
NGNGこれはLispの表記法と一緒だよね。おれはこの部分でLispに違和感を感じたことはない。
0286デフォルトの名無しさん
NGNG0287デフォルトの名無しさん
NGNG0288デフォルトの名無しさん
NGNGないかい? 算数や数学でこの表記法に慣れているから。
0289デフォルトの名無しさん
NGNGobject methodの書式の話なわけで。
Ioの
object method1(...) method2(...)
はC++では
object->method2()->method2()
ね。
無理解を装ってるだけだろうけど。
0290デフォルトの名無しさん
NGNGobject->method1(...)->method2(...)
の間違いね。
LISPの場合これぐらいならフロントエンド書けばおしまいだけどね。
0291デフォルトの名無しさん
NGNGobject methodの書式の話だとして、
CLOSではメソッドが属すジェネリック関数が、普通の関数と同じ書式で呼び出せる
ということに利点を感じて、(gf1 (gf2 obj0) (gf3 obj1))なんて感じの表記に
したのでしょう。
それが主流から外れているというのなら、ふ〜んというしかないけど。
全般的に劣った表記体系かといえば、そうは思わないという話。
0292デフォルトの名無しさん
NGNGんで、その関数の引数について、こんどは右端までいかないと書けない。
これが主流のオブジェクト指向に向いてないという根拠の1つ。
数アクションぐらい余計に負担が掛かる。
0293デフォルトの名無しさん
NGNGすまん、もうねるぽ。
0294デフォルトの名無しさん
NGNGそんな表面的な部分だけ取り上げて得意気になられてもなあ
0295デフォルトの名無しさん
NGNG根幹に関わる。
0296デフォルトの名無しさん
NGNGキーボードを打つのも面倒になるのだろうな。
0297デフォルトの名無しさん
NGNG0298デフォルトの名無しさん
NGNG0299デフォルトの名無しさん
NGNGでもつまらないよ。
0300デフォルトの名無しさん
NGNGLisp にとって、構文の問題は「表面的」なんだよ。
macro 書けば解決するから。
0301300
NGNG0302デフォルトの名無しさん
NGNG「mしてね、o君」というのでも、オブジェクト指向なんじゃないの、
S式は、後者に適しているというだけなんじゃないの。
0303デフォルトの名無しさん
NGNG0304デフォルトの名無しさん
NGNGo君、m1してね p1とp2で その後 m2してね p3とp4で
後でm2してね、最初にm1してね、o君、 p1とp2で ところでm2の件だけどp3とp4使ってね
わかりますか?
0305デフォルトの名無しさん
NGNG前者が
object method1(p1, p2) method2(p3, p4)
後者が
(method2 (method1 object p1 p2) p3 p4)
なわけです。
後者は文章にするのも大変だということがわかりますか?
0306デフォルトの名無しさん
NGNG↓でも参考にして好きなようにすれば?
ttp://www.cliki.net/infix
ttp://lambda.s55.xrea.com/20040325.html
0307デフォルトの名無しさん
NGNG0308デフォルトの名無しさん
NGNG最後にmnするんだけど、そのまえにmn-1してね、・・・
最初にm1してね、o君、
m1の件はp1とp2で。
m2の件ではp3とp4、・・・
mnの件は・・・なんだっけ?
一般人の短期記憶スタックは6〜8ネストぐらいが限界だとどこかで読んだ事がありますが、
口頭で言われた場合、理解できるでしょうか。
0309デフォルトの名無しさん
NGNG当然ながらフロントエンドについては考えてるよ。
0310デフォルトの名無しさん
NGNG(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)
0311デフォルトの名無しさん
NGNGそんなにダラダラ書いたらどんな記法であろうと分かりにくくなるのは当然だろ
なんのためのインデント、なんのための一時変数、なんのための括弧、なんのt(ry
要はあんたが前置記法では分かりにくいってだけでしょ
あんたに理解しづらいからといって他の人もそうであるとは限らない
0312デフォルトの名無しさん
NGNG横長になっちゃって見辛い、てのはあるかなあ。
適当に切り分ければいいだけの話だけど。
でも、たとえばこんな感じの関数書けば、
(define cascade
(lambda (x . fs)
(fold (lambda (f knil) (f knil)) x fs)))
こんな感じに書けるけれど、
(cascade (iota 10) (filter$ even?) (fold$ + 0)) => 20
ちょっとややこしいのになるとあんまり書きやすいと感じなかったなあ。
上記の、インデントの関係で読みやすくはあったけど。
どうしてかな、て考えてみると、自分の場合はまず、結局最後は何やるの?
ていうのを考えて、それに渡す値はどうするの?
更にそれに渡す値は……みたいな感じの思考パターンで考えることが多いみたい。
元の値から結論に向って値を下げ渡していく感じじゃなくて、
最初に結論ありきでそれに向って差し戻していくイメージっていうか。上手く言えないけど。
実際のところ、最終的に何をしたいのかていうのは、
その途中の経路よりははっきりしていることが多いと思うので、
それをまず書いちゃって、それに渡す値を作るところは適当に副関数に切り分けておいて、
後からそれを別立てで書いたほうが思考の流れに沿って作業できないかなあ。
一方で充分にライブラリが揃っていて、後はそれを糊付けしていけばいい、
てところまで状態が整っているならば、obj->metha->methb->...
みたいな書き方のほうが楽かもしれない。
結局のところ、問題の質や切り分け方で、
それに適った思考過程、対応するような記法は変わってくるだろうから、
どういう記法が優れているか、ていう単純な話ではなくて、
それぞれの記法はどのように問題を切り分けるのに向いているか、てことじゃないかなあ。
0313デフォルトの名無しさん
NGNG>>304-305
後者について、generic function model で第一引数を
特別扱いするのがそもそも間違っている気がする。
(……なんか最近似たようなことを書いた記憶があるな)
message passing model に基づいて事象をモデル化したら、
message passing model に基づいた記法で書いたほうが素直になるのは当然でしょう。
そこで後者が文章にするのも大変て言われても、それはそうでしょうな、としか言えない。
無理にオブジェクトを人として扱うなら、
「o 君、p1 と p2 で」じゃなくて、「o1 君と o2 君と o3 君で」と考えた方がいい。
もっとも、それだと三人が一人になったり、
逆に(多値を返すような場合)一人が三人になったりして不気味だけど。
そういう意味じゃ、(例えば)オブジェクトを人としてモデル化したいような場合には
generic function model は確かに向いてないかもしれない。
でも、モデルなんて結局のところ問題把握のための道具でしかないんだから。
通用する範囲で便利に使えればいいし、無理があるような場合には脇に置いといたり、
場合によってはあっさり捨ててしまってもいいんじゃないかな。
どっちのモデルであれ、あるいはそれ以外のどのモデルであっても、固執するのは馬鹿らしいと思う。
ていうか、ひとつの完全なモデルがみつかってなら、
何でこれほどたくさんの「オブジェクト指向」言語が作られているのか、て話になる。
で、lisp のいいところっていうのは、
記法をそこそこ柔軟にモデルに合わせて作り変えられるってとこでしょ?
散々言われてきたことだけど。
例えばあるオブジェクトについて、手続きを順々に追っかけさせる、みたいなことをしたいなら、
自分が上に書いたのや >>311 さんが書いたようなやり方で簡単に出来るわけで、
そうした方が問題をすっきり記述できると判断するなら書きゃいいじゃんてことではあるけれど、
でもそれがどの問題についても妥当であるというなら、それは了見が狭いといいたい。
0314デフォルトの名無しさん
NGNGlisp 族がメジャーになることはないんだから、わざわざ粘着するなよ
0315デフォルトの名無しさん
NGNG何か他の値を返すようなメソッドには使えないけど。
返り値がいらないようなメソッドを続けて使うのって、表示周りとかかな…
0316デフォルトの名無しさん
NGNGNULLやnilのような無効値だったらそれ以上進まないようなやつ。
リスト処理だけなら空リストで済むから問題ないんだけどね。
0317デフォルトの名無しさん
NGNG=> (let ((obj1 (f0 obj)))
(if obj1 (let ((obj2 (f1 obj1 arg1))) obj2) obj))
というマクロ->を定義するのは簡単だよね。nilになる一歩手前のオブジェクトを
返してくれる。
0318デフォルトの名無しさん
NGNG(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の変数ってこれで大丈夫なのかな?
0319デフォルトの名無しさん
NGNGデータについて考えてみても、cons してから reverse (nreverse)
ってのをよくやる(見る)けど、あれ無駄な気がしてならない。
0320デフォルトの名無しさん
NGNG前半と後半の繋がりがよくわからない
0321デフォルトの名無しさん
NGNGconsセルの先頭に突っ込むのとケツに突っ込むコストが同じだというのか。キミは。
0322デフォルトの名無しさん
NGNG破壊的操作が必要になるのであまり嬉しくないけど、
計算量的にそれが必要ならやればいいだけの話。
0324デフォルトの名無しさん
NGNGいえ、すんません。巣に帰りまつ(;´Д`)
0325デフォルトの名無しさん
NGNG0326デフォルトの名無しさん
NGNG(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 はなんで遅いんだろ。
0327デフォルトの名無しさん
NGNGリストの長さや処理系によっても随分違うものになるだろうから
それらを特定しない比較には意味が無いような
0328デフォルトの名無しさん
NGNGリストの長さを変えても傾向は変わらなかったのか?
0329デフォルトの名無しさん
NGNG(apply list l))
0330デフォルトの名無しさん
NGNGほんとですね。とりあえず、
(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です。
他の処理系でも試してみます。
0331デフォルトの名無しさん
NGNGcopy-list1,copy-list4がそれぞれどれくらいの時間でできるか計算してごらん。
copy-list1はgcの時間をのぞいたら変わらないと思うよ。
■ このスレッドは過去ログ倉庫に格納されています