【入門】CommonLisp【 ..
[2ch|▼Menu]
577:デフォルトの名無しさん
05/09/26 12:17:57
>>576
おまえスレタイ読めるのか?
スキームの宣伝は他でやれよ。

578:デフォルトの名無しさん
05/09/26 12:20:35
ちなみにちゃんとしたSchemeでも継続はあんま使わないよ
別に無くてもなんとかなるレベルでしょ
ただし末尾再帰は無いとコーティングスタイルにまで影響する
最適化の余地があるCommonLispならともかく、
独自LISPにはもう期待できる事が何も無い

579:デフォルトの名無しさん
05/09/26 12:23:36
>>577
スキームの宣伝て何?
おまえこそちゃんとレス読めよダボが

580:デフォルトの名無しさん
05/09/26 12:28:57
>>578
はぁ?
> 最適化の余地があるCommonLispならともかく、
> 独自LISPにはもう期待できる事が何も無い

何か言ってる意味わかんねよ。
Common Lisp系の独自LISPとかイメージできないの?

581:デフォルトの名無しさん
05/09/26 14:26:44
>Common Lisp系の独自LISP
イミフメ

582:デフォルトの名無しさん
05/09/26 21:57:00
見事に話が噛み合ってないな(w
ちなみに漏れは580の言ってることは理解できる派ね。まぁただでさえマイナーな言語に
関わってる者同士マターリと行こうや。

583:デフォルトの名無しさん
05/09/27 01:25:11
末尾再帰の最適化をするのは Scheme だけじゃないしね。
俺も継続は無くても良いけど、末尾再帰の最適化は欲しいなぁ。

584:デフォルトの名無しさん
05/09/27 01:36:27
>>583
以前話題になった気がするけど、Common Lispにおける末尾再帰の最適化は、
・インタプリタはほとんどの処理系がやらない
・コンパイラはほとんどの処理系がやる
という結果だったと思う。Common Lisp的思想からすれば順当なところだろうね。

585:デフォルトの名無しさん
05/09/27 02:42:55
Scheme 勉強したてで毒されてるな.
末尾再帰の最適化はメリットばかりじゃねーんだぜ?
インタプリタ上では *常に* 最適化されちゃったらデバッグしにくいだろ?
Common Lisp 的思想なら,コンパイル時の最適化オプションで
制御できるほうが嬉しい.

末尾再帰の最適化を示すオプションが欲しいって話もあるけどな.事実上,
speed 3 とか debug 0 にしとけばほとんどのコンパイラがやってくれっからねぇ.


586:デフォルトの名無しさん
05/09/27 11:44:41
>>585
> インタプリタ上では *常に* 最適化されちゃったらデバッグしにくいだろ?

これはスタックトレースが取れないとかそういう意味?

587:デフォルトの名無しさん
05/09/28 02:18:03
常に最適化されちゃって選択できねーとかははやすぎる最適化の部類に感じる時がある.
CL 派としては c.l.l で出てた宣言的アプローチで解決してほしいなー.

「可能な限り最適化する」「自己呼び出しとローカル関数のみ最適化」「自己呼び出しのみ」「最適化なし」

とかが宣言できるみたいな.まぁ,現状はコンパイラのマニュアルを見る必要
があるわけだけど,それで不都合あるのかっつーはなし.Common Lisp におけ
る末尾再帰の最適化はだってほぼ標準だしね.


588:デフォルトの名無しさん
05/09/28 02:22:10
>>587
結局Common Lispの仕様の問題になるわけだよな。20年間にわたって仕様が安定
している(ANSIでわずかに変更されたところもあるが)のは利点でもあるわけだが、
そろそろ次期規格の話が出てきても良いように思う。

589:デフォルトの名無しさん
05/09/28 09:10:11
元々の話が>>573なわけで・・

590:デフォルトの名無しさん
05/09/28 14:17:11
Schemeばかり書いてると、関数呼び出しが関数呼び出しに
見えなくなるというか、全部継続へのジャンプに見えて来るんだよな。
それに関数とブロック(let)が頭の中でブレンドされて区別されなくなる。
そうすると自己末尾呼び出しだけ特別扱いしたりするのがとても不自然に
感じる。

まあ、Common Lispの空気に合わないってのはわかる。CLで書くときは
スタイルが変わるからな。


591:デフォルトの名無しさん
05/09/29 01:15:48
このスレこんなに人がいたのか(^_^ゝ)


592:デフォルトの名無しさん
05/09/29 03:42:33
>>588
仕様の問題ねぇ.改善の余地(個人的希望は >>587 な)があるとは思うが,
Scheme が The Right Thing だとは思わない.なぜなら,俺には区別したい
時があるからだ.最適化する,しないは選択したい.まぁ,その選択肢が
存在するのが不自然だと言われりゃしょうがねーけどなぁ.

ま,CL にも末尾再帰の最適化は実装依存だが,「ある」という事を言って
おきたかったわけ.

593:デフォルトの名無しさん
05/09/30 19:03:53
lispファイル用の良いアイコン知りませんか?

594:デフォルトの名無しさん
05/09/30 23:27:09
>>593
自作すれば。
↓雛型
(())

595:デフォルトの名無しさん
05/09/30 23:31:51
Planet Lisp のサイトアイコンは () だね

596:デフォルトの名無しさん
05/09/30 23:36:49
>>593
λ

597:デフォルトの名無しさん
05/10/01 00:34:23
(car cdr)
なんてどうだ

598:デフォルトの名無しさん
05/10/01 01:19:05
>>592
CommonLispで以下の相互再帰がループになる保障があるってわけじゃないでしょ?
こういうとこで根本的にコーティンングスタイルに関わってくるわけ。

(defun f(a) (g a))
(defun g(a) (h a))
(defun h(a) (f a))

(f f)

Schemeでトレースしたけりゃ末尾再帰の最後に適当な置石すりゃいいだけだし。
既存の処理系にも普通にバックトレースぐらい存在してるでしょ。

599:デフォルトの名無しさん
05/10/01 01:28:56
>>598
言いたいことはわかるけど、だからCommon Lispは駄目、Schemeが良い
という話をしたいのであればスレ違い。そもそもここはCommon Lispのスレ
なので、もうちょっと建設的に考えてほしい。

例えばCommon Lispで末尾再帰を強制するようなdeclareを提案するとか。

あと、念のために言っておくと相互再帰をループ化する最適化はさほど
難しくはないので多くの処理系がやっているはず。

600:デフォルトの名無しさん
05/10/01 01:51:26
>>599
あのな、CommonLispをどうこうしようってんじゃなくて、>>573の回答として
独自LISP勉強して作るぐらいならScheme作っとけって話。
CommonLispがどこまで最適化できるとか云々は別に興味ない。

601:デフォルトの名無しさん
05/10/01 01:55:45
>>598
そりゃ環境を問わずあらゆるCL処理系で動く必要のあるコードとかいうなら
仕方がないけど。元々の方向性が違うんだから仕様の問題というよりは
そういうスタイルでCLを選択する方が間違ってるんでは。

ちゃんと末尾再帰を最適化する処理系を使えばいい話でしょ?
相互再帰だろうが末尾再帰だろうが基本的に違いはないよ。
cmuclでも、declareも何もせずにreplからそのままdefunして直ぐにdisassemble
しても、ちゃんとジャンプになってるよ。


602:デフォルトの名無しさん
05/10/01 02:10:36
>>600
別に>>573氏はおまえが使う処理系を作ろうというんじゃないと思うぞ。w
おまえの好むScheme的スタイルをCommon LispスレでLISPの処理系でも
作ってみようかという奴にしつこく言う必要はあるまい。

603:デフォルトの名無しさん
05/10/01 11:21:07
>>598
すると,あなたは R5RS にないものは使わないのですか?
事実上標準だと主張しているのだが.メインストリームの商用
コンパイラで末尾再帰の最適化機能を持たないコンパイラがある
のかと.Scheme ではコンパイルについての規格がないから,
安心してコンパイルできない!! というくらいの心配症の人なら
まぁ,止めないけどね.

> Schemeでトレースしたけりゃ末尾再帰の最後に適当な置石すりゃいいだけだし。
残念な結末ですね.大規模なプログラムでそれが簡単な事だお思いますか?
末尾再帰の最適化を OFF にしたら Scheme じゃないんでしょ?
Scheme の処理系依存機能はよくて,CL の処理系依存機能はだめなんですか.

そんな事言うなら,CLOS 相当の機能がなく,したがって安全にオブジェクトの
定義を更新できないほうが嫌だ.

再帰というトンカチを手にすると他の全てが再帰に見えてくる.ループは
再帰の特殊系だけど,本来並列動作とかもあるから
(map fn lst)
を見て,再帰的な実装がまず第一に頭に浮ぶならもう一度良く考えたほう
がいい.


604:デフォルトの名無しさん
05/10/01 11:36:24
つうか,>>600 からしておかしい。

俺なんか既存の概念をくつがえすようなトンデモない
処理系を期待しちまうけどな。がんばって勉強しろーよ。
最初はショボくても独自 Lisp 上等。Lisp の進化の歴史を
学ぶもの一興。

まず自分で作ってみれば?ショボショボインタプリタとかでいいから。
つうか 573 を応援してやりたいが,情報がないな。
Lisp/Scheme の腕前と C の腕前はどーなんだろう。


605:デフォルトの名無しさん
05/10/01 12:02:37
馬鹿だなおめーらは

606:教えて厨
05/10/01 16:54:07
質問。
(-1 3 2 5 3 -3 -4)
というようなリストがあるとしますよね。
これを
((-1 -3 -4) (3 2 5 3))というように負数と正数で別々のリストに分類したい。
これ、負数だけとりだす関数と正数だけ取り出す関数を作って、
それをlistすれば簡単にできるけど、
再帰関数ひとつだけで作る方法もあるんだよね??
それってどうやるの?
letやlet*なんかでnilとかに初期化した変数って、再帰で呼び出すと
再帰呼び出し先でもまたnilとかになるの?
再帰呼び出し先で再帰呼び出し元での変数の値が引き継がれるような方法
があればうまくやれそうなんだけどなあ。
みなさんなら、どうやって再帰関数一つだけで、上のような処理を実装できますか

607:デフォルトの名無しさん
05/10/01 17:31:36
LOOPマクロ
(defun plus-minus (list)
(loop for x in list
if (>= x 0) collect x into plus
else collect x into minus
finally (return (list minus plus))))

再帰
(defun plus-minus (list)
(labels ((iter (l plus minus)
(if (null l)
(list (nreverse minus) (nreverse plus))
(let ((x (car l)))
(if (>= x 0)
(iter (cdr l) (cons x plus) minus)
(iter (cdr l) plus (cons x minus)))))))
(iter list '() '())))

608:デフォルトの名無しさん
05/10/01 19:49:26
質問させてください。
(setq a t)
とした変数aの真偽を連想リストに入れてやりたいのですがうまくいきません。
(setq b '((res . a) (res2 . ....)))
みたいにすると(cdr (assoc 'res b))はtではなくaを返すし
(setq b '((res . (eval a)) (res2 . ....)))などとしても同様です。
環境はxyzzyです。どうかお願いします。

609:デフォルトの名無しさん
05/10/01 20:16:30
(cdr (assoc 'res `((res . ,a))))


610:デフォルトの名無しさん
05/10/01 20:29:24
そんな説明なしで得意げに書かれてもな・・

611:& ◆6g4XpN.URU
05/10/01 20:35:27
>607

どうもありがとう。
ちなみにiterって初めてみるんだけど、どういう関数なの?

612:608
05/10/01 20:53:15
>>609
ありがとうございます。backquoteを使ってなんとかするということですね。
確かにまだよくわからないですが勉強します。

613:デフォルトの名無しさん
05/10/01 20:57:32
>>611
labelsの行をじっと見つめてみろ。

614:デフォルトの名無しさん
05/10/01 23:13:06
>>612
quoteしたら評価されないって言うことです。
quoteしないようにこんな感じで書けばOK

(setq a t)
(cdr (assoc 'res (list (cons 'res a))))

いちいちこう書くのは面倒だからbackquote構文が用意されてる
って感じかな。

615:デフォルトの名無しさん
05/10/01 23:15:33
言っとくけど、backquoteもマクロなんだぜ?
マクロって偉大だよなあ・・・

616:デフォルトの名無しさん
05/10/02 04:39:29
>>606
宿題だとすると labels の内部関数はつかっちゃだめかも?ということで
親切にも別解だっ.

;; 再帰関数一つ
(defun plus-minus (lst &optional plus minus &aux (x (car lst)) (xs (cdr lst)))
(cond ((null x)
(values plus minus))
((>= x 0)
(plus-minus xs (cons x plus) minus))
(t
(plus-minus xs plus (cons x minus)))))

;; メソッド一つ
(defmethod plus-minus-2 ((lst null) &optional plus minus)
(values plus minus))
(defmethod plus-minus-2 ((lst cons) &optional plus minus)
(if (>= (car lst) 0)
(plus-minus-2 (cdr lst) (cons (car lst) plus) minus)
(plus-minus-2 (cdr lst) plus (cons (car lst) minus))))


617:デフォルトの名無しさん
05/10/02 09:38:28
(defun partition (test lis)
(labels ((recur (lis in out)
(cond ((null lis) (values (nreverse in) (nreverse out)))
((funcall test (car lis))
(recur (cdr lis) (cons (car lis) in) out))
(t
(recur (cdr lis) in (cons (car lis) out))))))
(recur lis '() '())))

CL-USER> (partition #'(lambda (x) (>= x 0)) (list 1 -3 0 -2 9 -8))
(1 0 9)
(-3 -2 -8)


618:デフォルトの名無しさん
05/10/02 10:59:40
(defun partition (test list)
(let ((in (cons nil nil)) (out (cons nil nil)))
(let ((i-tail in) (o-tail out))
(dolist (x list (values (cdr in) (cdr out)))
(if (funcall test x)
(setf i-tail (setf (cdr i-tail) (cons x nil)))
(setf o-tail (setf (cdr o-tail) (cons x nil))))))))

619:デフォルトの名無しさん
05/10/02 11:40:15
(defun partition (pred lis)
(do ((lis lis (cdr lis))
(in '())
(out '()))
((null lis) (values (nreverse in) (nreverse out)))
(if (funcall pred (car lis))
(push (car lis) in)
(push (car lis) out))))


620:おしえて厨
05/10/02 23:47:39
clispをwinで使ってるんだけど、lispでウィンドウやダイアログボックスを
だすようなGUI作ることってできないの?できるとしたら
そういう情報はどこにある?

621:デフォルトの名無しさん
05/10/03 00:01:59
>>620
例えば URLリンク(www.wxcl-project.org)

622:デフォルトの名無しさん
05/10/03 01:27:27
できるよ.(621 は試したことないの別のネタで)
自分で Windows の API を呼べばいい.

A) FFI で必要な API をラップする (URLリンク(hocwp.free.fr) とか)
B) Lisp 向けの API を実装したライブラリを作る

ただし,どっちもある程度 C の知識がないと難しいかもね.

Corman Lisp とか AllegroCL や LispWorks といった処理系を使う手もある.
AllegroCL や LispWorks はどっちも GUI ライブラリを持ってるよ.

623:デフォルトの名無しさん
05/10/03 16:43:37
CommonLispにはpartitionがなかったのか…

624:デフォルトの名無しさん
05/10/03 17:56:31
R5RS には remove-if すらないけどね

625:デフォルトの名無しさん
05/10/05 15:05:45
質問です。
(my-reverse '(1 (2 3) (4 (5 6))))
を与えたら(((6 5) 4) (3 2) 1) と、
中身が全て反転するような関数my-reverseを定義するやり方を教えてください。
お願いします。

626:デフォルトの名無しさん
05/10/05 15:14:34
>>625
>>513-525

627:デフォルトの名無しさん
05/10/05 17:33:39
>>626
すいません。>>513-525を読んでもわかりませんでした。。

628:デフォルトの名無しさん
05/10/05 18:07:07
(defun my-reverse (list)
(let ((result '()))
(dolist (x list result)
(if (consp x)
(push (my-reverse x) result)
(push x result)))))

629:デフォルトの名無しさん
05/10/05 19:14:32
>>628
ありがとうございます!!

630:デフォルトの名無しさん
05/10/05 19:43:33
>>525

631:デフォルトの名無しさん
05/10/05 20:30:40
相変わらずレベル低いよな
おまえら普段何してんの?

632:デフォルトの名無しさん
05/10/05 20:35:49
みんな処理系は何使ってんの?

633:デフォルトの名無しさん
05/10/05 23:10:51
Gaucheでネットワークプログラミング

634:デフォルトの名無しさん
05/10/06 01:30:05
CLISP - 日常的な小物スクリプト書き
SBCL - CLISP では力不足な計算用とかスレッド使いたいときとか
CMUCL - 最近使ってない…互換性検証用か


635:631
05/10/06 01:34:37
おまえらレベル低すぎ
俺の使っている処理系を教えてやるから勉強汁
Ruby 1.8.3
ユーザビリティの低いもの使ってんなよ


636:デフォルトの名無しさん
05/10/06 01:51:04
>>634
SBCLってCMUCLよりデバッグやりにくくない?

637:デフォルトの名無しさん
05/10/06 02:14:31
スレッドまわり以外は特にそんな事おもわないけど?
どのへんがやりにくいとおもう?

638:デフォルトの名無しさん
05/10/07 10:11:25
Windowsのアプリに組み込めるLisp、Schemeでいいの無いですかね?

639:デフォルトの名無しさん
05/10/07 14:34:43
ないから俺は自作したが。

640:初心者
05/10/09 00:25:24
(defun plus-minus (lst &optional plus minus &aux (x (first lst)) (xs (rest lst)))
(cond ((null x)
(values plus minus))
((>= x 0)
(print xs)
(plus-minus xs (cons x plus) minus))
(t
(plus-minus xs plus (cons x minus)))))


このコードのxやxsって再帰のたびに更新されていくけど、a


(defun test (lis &aux (a (first lis)) (b (rest lis)))
(if (not (null (first lis)))
(print b)(test b)))

これのaやbは再帰しても更新されないよね・・・違いはなんなの?
再帰後にもずっと同じ値がはいったままだったり、再帰後には再帰後の
更新された値が入ったりするその違いって?

641:デフォルトの名無しさん
05/10/09 01:25:18
(lambda (x y &aux (a form1) (b form2)) ...) は
(lambda (x y) (let* ((a form1) (b form2)) ...)) と同じ。
後半で更新されてないように見えるとしたら、それはちゃんと再帰
してないから。

642:デフォルトの名無しさん
05/10/09 08:45:59
>>640
↓こんな動きになってるのは理解できてるの?
CL-USER> (PLUS-MINUS '(1 -3 2))
0: (PLUS-MINUS (1 -3 2))
x: 1 xs: (-3 2)
1: (PLUS-MINUS (-3 2) (1) NIL)
x: -3 xs: (2)
2: (PLUS-MINUS (2) (1) (-3))
x: 2 xs: ()
3: (PLUS-MINUS NIL (2 1) (-3))
x: () xs: ()
3: PLUS-MINUS returned (2 1) (-3)
2: PLUS-MINUS returned (2 1) (-3)
1: PLUS-MINUS returned (2 1) (-3)
0: PLUS-MINUS returned (2 1) (-3)

CL-USER> (TEST '(NIL NIL 2))
0: (TEST (NIL NIL 2))
a: NIL b: (NIL 2)
1: (TEST (NIL 2))
a: NIL b: (2)
2: (TEST (2))
a: 2 b: ()
NIL
2: TEST returned NIL
1: TEST returned NIL
0: TEST returned NIL


643:& ◆RdmUjfVKqQ
05/10/09 10:34:53
>641, 642

そういう動きになっててほしいけど、
printから出てくる値をみてる感じだと、
2番目のコードだと再帰前のリストのrestとったものがでてるようにみえるんだよ〜

644:デフォルトの名無しさん
05/10/09 10:54:00
間違いなくコードが変だからどういう動作を意図してるのか言ってみ。

645:デフォルトの名無しさん
05/10/09 12:53:13
642 は SBCL でのトレース結果だよ.CLISP でも同じだた.
意図したように動いているみたいなんで,
640 が動作させた本当のコードと入力値を述べたまえ.


646:デフォルトの名無しさん
05/10/09 14:08:21
>>640が何を訊きたいのか判らんが、こう書きたかったんじゃないのか?

(defun test (lis &aux (a (first lis)) (b (rest lis)))
(if (not (null (first lis)))
(progn (print b)(test b))))

647:デフォルトの名無しさん
05/10/09 14:40:00
>>646 それでも条件が逆になるけど再帰時にちゃんと lis はあたらしくなるぞ?
思うに,if の条件が意図したやつと逆になっているので期待どうりしていなかっ
たとかそんな事じゃないかな.どーゆう条件でどう動いてほしかったのかを日本語
で説明してもらうのがはやいと思う.


648:おすえて
05/10/09 20:21:16
(defun test (lis &aux (a (first lis)) (b (rest lis)))
(if (not (null (first lis)))
(print b)(test b)))

これが、(test '(1 2 3 4 5))とやったときに
例えば
(2 3 4 5)
(3 4 5)
(4 5)
(5)
みたいにならないのは、なぜ?

649:デフォルトの名無しさん
05/10/09 20:29:11
>>648
なぜそうなると思った?

650:& ◆eDpN.64OYw
05/10/09 20:48:49
(defun plus-minus (lst &optional plus minus &aux (x (first lst)) (xs (rest lst)))
(cond ((null x)
(values plus minus))
((>= x 0)
(print xs)
(plus-minus xs (cons x plus) minus))
(t
(plus-minus xs plus (cons x minus)))))


↑これだと再帰のたびにxsが変わっていくから、468でもそうだろうと
思ったんだけど

651:デフォルトの名無しさん
05/10/09 21:00:36
君のやりたいことは、
(defun test (lis &aux (a (first lis)) (b (rest lis)))
 (cond ((not (null b))
    (print b)
    (test b))))
ってな感じかな。if の定義を再勉強!

652:デフォルトの名無しさん
05/10/09 21:04:56
やっぱりな.再帰とか &aux 以前に 2 つ間違いをおかしている.
1. if の構文を間違えている (おそらく)
2. 条件の中身も間違えている
それって,「条件を満しているなら print で b を表示したあと再帰する」って
処理が希望のようだが,書いたコードが,「もしリストの先頭要素が nil 以外なら表示する.そうでないなら再帰する」
なので,表示は一回しかされない.
(defun test (lst &aux (a (first lst)) (b (rest lst)))
(if a
(progn
(print b)
(test b))))
もしくは
(defun test (lst &aux (a (first lst)) (b (rest lst)))
(when a
(print b)
(test b)))
だな.手元の参考書を if の説明をちゃんと読みなおしたほうがいい.

653:& ◆QWv3R1XL8M
05/10/09 21:14:39
>書いたコードが,「もしリストの先頭要素が nil 以外なら表示する.そうでないなら再帰する」
なので,表示は一回しかされない.

なんで??
再帰二回目だとrestとった値がなんでnilになる???2とか3じゃないの??
ifがどうとか言う以前によくわからんのですが

654:デフォルトの名無しさん
05/10/09 21:23:19
再帰しないんだから二回目もクソもないんだよ。
if の説明を確認しろっていわれてんだから素直にそうしな。

655:& ◆QWv3R1XL8M
05/10/09 21:31:58
なるほど、わかりました。ありがとうございました。
で、

(defun test (lis &aux (a (first lis)) (b (rest lis)))
 (cond ((not (null b))
    (print b)
    (test b))))

↑これ実行できないんですけどこれは何故?

656:デフォルトの名無しさん
05/10/09 21:39:12
全角空白までコピペしちゃっているからだろう.
大した手間でもないだろうから手で入力したまえ.

657:おしえて厨
05/10/10 19:51:08
lispのsort関数を使わないで、
オリジナルの数字リストの昇順または降順ソートプログラムを
書いてみてください。
できれば初心者でもアルゴリズムが分かりやすいような書き方でおながい

658:デフォルトの名無しさん
05/10/10 20:35:14
>>657
やだ

659:デフォルトの名無しさん
05/10/10 20:50:39
xのy乗を求める問題なんだけど、どこか変なところある?
include <stdio.h>
#include <math.h>


main()
{
double x,y,z;

printf("x =");
scanf("%lf",&x);
printf("y =");
scanf("%lf",&y);

z = pow(x ,y);
printf("x\ty = %lf", z);
}


660:デフォルトの名無しさん
05/10/10 20:52:12
頭が変かもしれんな

661:デフォルトの名無しさん
05/10/10 21:05:09
書き込むスレの選択が変

662:デフォルトの名無しさん
05/10/11 04:45:21
>>620
面白い物見つけた。

URLリンク(www.geocities.jp)

Socket 経由で GUI を作ってるっぽいけど、Windows Native でも
似た様なのがあるんじゃないかな。Mac だとこういうのがある。

URLリンク(www.bluem.net)

663:おしえて厨
05/10/11 08:49:23
(defun small (lis)
(cond ((null (rest lis))
lis)
((< (first lis) (first (rest lis)))
(remove (first lis) lis)
(remove (first (rest lis)))
(cons (first lis) lis)
(cons (first (rest lis) lis))
(small lis)
(t (small (rest lis))))))

↑バブルソートしたくて書いてみた。駄目だった。どこが駄目?

664:デフォルトの名無しさん
05/10/11 09:41:52
バブルソートを使うところが駄目。

665:デフォルトの名無しさん
05/10/11 10:13:57
(defun merge-sort (lst)
(let ((len (length lst)))
(cond ((< len 2) lst)
((= len 2)
(let ((x (car lst))
(y (cadr lst)))
(if (< x y) (list x y) (list y x))))
(t
(do ((x (merge-sort (butlast lst (ash len -1))))
(y (merge-sort (last lst (ash len -1))))
(r '()))
((or (null x) (null y))
(nconc (nreverse r) x y))
(push (if (< (car x) (car y)) (pop x) (pop y)) r))))))

666:おしえて厨
05/10/11 17:25:50
(remove 'a 'a)みたいに一文字だとremoveできないじゃん。
どうやって一文字しかないのを消すの?
あと、(a b c (a ((b))))みたいになってるときのbだけを消して、
(a b c (a (( ))))みたいにする方法って、あるの?

667:デフォルトの名無しさん
05/10/11 18:03:53
((lambda (x y)
((lambda (f) (funcall f f y))
(lambda (f y) (typecase y
(list (remove x (mapcar (lambda (y) (funcall f f y)) y)))
(t y)))))
'b '(a b c (a ((b)))))
=> (A C (A (NIL)))

668:おしえて厨
05/10/11 19:06:51
関数が定義されていません: typecase

669:デフォルトの名無しさん
05/10/11 19:36:09
そりゃ Common Lisp じゃないな。スレ違いだからもうこのスレに来ないように。

670:デフォルトの名無しさん
05/10/11 19:37:20
>>668
処理系がまがい物だな

671:デフォルトの名無しさん
05/10/11 20:10:17
xyzzy だな

672:おしえて厨
05/10/11 20:43:06
xyzzyなんだけど、typecaseつかわずにできないの???

673:デフォルトの名無しさん
05/10/11 21:12:30
>>672
xyzzy使いのよしみで回答しておくけど、
CommonLisp を勉強するのに xyzzy を処理系として使っちゃダメ。
xyzzy でマクロを書くための勉強ならここで質問するのは間違い。

((lambda (x y)
((lambda (f) (funcall f f y))
(lambda (f y) (if (listp y)
(remove x (mapcar (lambda (y) (funcall f f y)) y))
y))))
'b '(a b c (a ((b)))))
=>(a c (a (nil)))

674:おしえて厨
05/10/11 21:57:05
(defun del-atom (n lis)
(cond ((null lis)
nil)
((atom (first lis))
(cond ((eql n (first lis))
(del-atom n (rest lis)))
(t (cons (first lis) (del-atom n (rest lis))))))
((listp (first lis))
(cond ((listp (first (first (first lis))))
(cond ((eql n (first (first (first lis)))))
(del-atom n (rest lis)))
(t (cons (first lis) (del-atom n (rest lis))))))
(cond ((listp n (first (first lis)))
(cond ((eql n (first (first lis)))
(del-atom n (rest lis))))
(t (cons (first lis) (del-atom n (rest lis)))))))))



↑自分でもやってみようとしたら、こんなんなっちゃったよ〜〜〜〜
どこが駄目???

675:デフォルトの名無しさん
05/10/12 00:50:11
((listp (first lis))
(cons (del-atom n (first lis)) (del-atom n (rest lis))))

676:デフォルトの名無しさん
05/10/12 00:51:18
first とか rest って使われてるんだなぁとそちらのほうに感動してたりする俺。

677:デフォルトの名無しさん
05/10/12 17:12:58
>>676
それはね、「xyzzy Lisp Programming」のページで、first と rest を推奨す
る、と書かれているからだよ。
URLリンク(www.geocities.jp)


678:デフォルトの名無しさん
05/10/12 17:23:12
>>677
「first と rest を使うことが推奨されています」なんて書いてるが、「誰が」推奨
しているのか不明だな。少なくとも CLtL2 にも ANSI にもそんな記述は見あた
らないが。(もし見落としてたら教えてくれ)

679:おしえて厨
05/10/12 17:33:11
P.H.ウィンストンという人が書いた緑の本に推奨されていた。
まあそれはさておき675さんの指摘がよくわかりません。
どこを直せばいいの??

680:デフォルトの名無しさん
05/10/12 18:08:58
>>679
> どこを直せばいいの??
頭の中身。
お前さんは九九も覚えてないのに数学の問題を見てわからないとわめいてるの
と同じなので、677 が紹介してるサイトの Common Lisp 入門を全部読んで
理解してからもう一度いらっしゃい。

681:デフォルトの名無しさん
05/10/14 03:51:47
ウィンストンって培風館の奴か?

car,cdrの方が好き
ハード寄りで

682:デフォルトの名無しさん
05/10/14 11:14:21
>>681
いつの時代の方ですか?

683:デフォルトの名無しさん
05/10/14 12:23:03
平成17年

684:デフォルトの名無しさん
05/10/14 12:27:20
漏れも car cdr のほうが好きだが、さすがに IBM 7090 (だっけか)は使ったことない。

685:デフォルトの名無しさん
05/10/14 14:01:44
8月からLisp触り始めた超初心者だけど
car、cdrのほうが好きだな。

686:デフォルトの名無しさん
05/10/14 17:17:44
>>679,681
俺もその本持ってる。そのせいか first、rest 派。
自分では使わないから、car や cdr ならともかく caddr ぐらいでもわけわからん。

687:デフォルトの名無しさん
05/10/14 17:23:31
>>686
caddr と third とどっちがわかりやすいかだわな。
個人的には視覚的にわかる caddr のほうが好き。

688:デフォルトの名無しさん
05/10/14 22:48:16
nthは邪道ですか、そうですか

いや、俺も使わないけど

689:デフォルトの名無しさん
05/10/15 14:56:32
(nth 3 L) ≡ (fourth L) なのがなんとも

690:デフォルトの名無しさん
05/10/15 15:05:25
>>689
nth は aref とともに elt の特別版ということだな。
むしろ、この3つの中で nth だけ引数順が違うのが気になる。

691:デフォルトの名無しさん
05/10/16 18:18:47
ルプラカ ルプラクドゥ
パンプルピンプルパムポップン
カッドゥルゥァー
クックドゥー

692:デフォルトの名無しさん
05/10/18 22:37:29
オブラディ オブラダ
(・∀・)スンスンスーン

693:デフォルトの名無しさん
05/10/19 19:16:22
;;ある基点となるフォルダより下のフォルダのフルパスを全て取得するには再帰でどう書けばいいですか?

694:デフォルトの名無しさん
05/10/19 20:40:03
実装依存

695:デフォルトの名無しさん
05/10/19 20:42:51
xyzzyでは??

696:デフォルトの名無しさん
05/10/19 20:45:20
板違い

697:デフォルトの名無しさん
05/10/19 20:55:26
(directory PATHNAME) あたりで調べると良いかも。

698:デフォルトの名無しさん
05/10/21 00:53:04
ECL使って実現されているプロジェクトでそこそこの規模のやつって誰か知りません?
C/C++とCommon Lispを混ぜた開発したいんだけども、実際の使われ方を見て勉強した方が
理解が早いかなと思って。
それともUFFI使うのが定説ですかね。

699:デフォルトの名無しさん
05/10/21 01:37:09
どうなんだろう.最近は CFFI とかも出てきてるしねぇ.
まず Lisp 側のインターフェースを決めて,それが十分に抽象化できていれば
その下は UFFI だろうが処理系の FFI だろうがたぶん問題ない.

ECL はあんまり触ったことないので本題には答えられない.スマソ.
キーワードハイライトつきのエディタ作ったとか Planet Lisp に出てたような.

700:698
05/10/21 01:58:32
>> 699
ありがと。Planet Lisp行ってきます。
スレ違いって怒られるかも知れないけど、Gaucheとかだと結構事情が違ったりする?
確か開発目標に他の言語と仲良くするってのがあったような。でも最終的には
ネイティブコードで走らせたいんだよなぁ・・・

701:デフォルトの名無しさん
05/10/21 02:08:50
ネイティブコードってことは性能が欲しいの?
それでフリーなのがいいならCMUCLやSBCLがいいんじゃないかな。
Cの呼び出しやCからのコールバックもそれほど面倒じゃないし。

702:698
05/10/21 02:45:04
Planet Lisp行ってきました。
簡単なアナウンスだけ出ててsourceforgeに誘導されてみたらスクリーンショットも
公開されてました。CVS HEADにコードが入っているみたいなのでこれから調査します。

いまはプロトタイピングの段階なので実現可能性の検証が主体です。アルゴリズムの設計と
検証はLispであ〜でもないこ〜でもないやりながら考えた方がお手軽なのですが
プロジェクトの他のメンバがC/C++でコード書いてるので現状は

・Lispでアルゴリズム練る → C++で等価なコードを書いてリポジトリにチェックイン

してます。二度手間でアホらしいんですが最初からC++であれこれ書けないんですよ。
C++の汚さに辟易して大分昔に標準化の動向追いかけるのやめていたこともあって。
で、どうせならLispのコードそのままC/C++に埋め込んじゃうことはできないのかな〜と
たくらんでいるところです。


スレ違いになりますが最近STLやらBoostやらLokiやら勉強してみて驚愕しました。
何であんな大変な思いをしてまでC++使うんですかね・・・不思議でたまらん。

703:デフォルトの名無しさん
05/10/21 02:54:10
>>702
ずいぶんと怪奇なことになってるよね。>C++
でも、すべてインラインに開いちゃうから確かに速い。
そのかわりコードサイズが大爆発。w

704:デフォルトの名無しさん
05/10/25 00:24:33
今ポールグラハムのlisp本でお勉強中なのですが、lispでは
soketを開くとかプロセス制御するとか低レイヤな処理をする場合
どーすんのでしょうか。処理系にそうしたライブラリがなかったりする場合は?

705:デフォルトの名無しさん
05/10/25 00:34:49
socketです。typoっす。すんません。

706:デフォルトの名無しさん
05/10/25 01:12:37
>>704
どうにもなりません。そういうライブラリが存在するか、ネイティブコードを
呼ぶなどの方法でなんとかできる処理系を選びましょう。

707:704
05/10/25 01:53:21
>>706
むぅ。そういうもんなんですか。教えて頂いて有難うございます。
そういったことは一旦置いておくとすると、学習向けに
オススメの処理系があればご教授頂けると助かります。
今のところ本読んでるだけなのですが手続き型が染み付いた頭には
関数プログラミングって難しい…。

708:デフォルトの名無しさん
05/10/25 02:04:53
>>707
WindowsならCLISP、UNIX系ならSBCLがいいんじゃないかな。
どちらもソケットなどの拡張機能は持っているよ。

709:704
05/10/25 02:12:34
>>708
どもです。SBCLっての調べてみます。。

710:デフォルトの名無しさん
05/10/28 00:10:41
潜水艦から発射するミサイルじゃないの?

711:デフォルトの名無しさん
05/10/28 00:15:22
>>710
それはSLBM

712:デフォルトの名無しさん
05/10/28 01:26:06
コンパイラ・スクリプトエンジン相談スレで言語処理系の実装にLispを使うべきだ風な
書き込みを見掛けて興味を持ったのですが、具体的にLispで記述されたコンパイラとかで
参考になりそうなものがあれば教えていただけますか?ソースを見てどんな利点があるのか
比較してみたいです。大昔GCCのソースを眺めたとき内部でS式みたいので木を表現して
いたみたいでしたが、表現形式だけじゃなくて実際に内部でLispプログラムが動いてたり
するんだろか。

713:デフォルトの名無しさん
05/10/28 03:53:37
かつては MacLisp が Fortran と張り合っていたわけだし,今でも Lisp コン
パイラはほとんど Lisp で書かれているよ.ただ,Lisp 製の ML や C コンパ
イラとかもあるけど,入門で読むのは無理だろう.

利点としてはコンパイラを書く時にモロに Lisp コンパイラの機能がつかえる!!
といっても,何の事か Lisp を知らなければまったくイメージできないかもしれない.
だからまず Lisp を学ぶ必要があるとおもうよ.基礎を一通りやったあと,

URLリンク(groups.google.com)

とか見て,それでもメリットがわからないようなら Lisp の事は忘れたほうが
いい.合う合わないがあるからね.

714:デフォルトの名無しさん
05/10/28 20:14:18
MacLispか…研究室の物置に5”FDの認知心理のプログラム群があったなぁ

715:デフォルトの名無しさん
05/10/30 01:11:05
lispと他のプログラムとの構文とかの対比表ってありませんか?

716:デフォルトの名無しさん
05/10/30 03:33:47
MacLisp か…今やプロジェクト Mac の Lisp で Macintosh とは関係ないと
言わないと通じない時代かもしれんな…

717:デフォルトの名無しさん
05/10/30 06:51:32
URLリンク(kasamatusan.sakura.ne.jp)
(竹内)

718:デフォルトの名無しさん
05/10/30 11:34:43
>>715 他のプログラム言語,と言いたいのか?具体的には何よ?


719:デフォルトの名無しさん
05/10/30 14:47:52
>>718
C,C++,java,perl,ruby,python,PHPなどのメジャーな手続き型のどれか

720:デフォルトの名無しさん
05/10/30 16:39:07
>>719
Lisp プログラマのための Python 入門
URLリンク(www.unixuser.org)
こんな感じ?

721:719
05/10/30 16:54:13
>>720
thx!

722:デフォルトの名無しさん
05/10/30 19:46:03
>>716
Windows上で動く?

723:デフォルトの名無しさん
05/10/30 19:47:42
lispとjavascriptってどっちが優れていますか?

724:デフォルトの名無しさん
05/10/30 19:50:17
>>722
PDP-10 とか DEC System 20xx のエミュがあれば。

725:デフォルトの名無しさん
05/10/30 19:57:22
>>723
javascript は lisp です

726:デフォルトの名無しさん
05/10/30 23:48:45
煽りにもマジレスしておこうか.

Web のクライアントサイドスクリプティングなら圧倒的に JavaScript が優れている.

逆にサーバーサイドでの処理なら Lisp のほうが良いな.でも君が病的に括弧
を恐れているならどこでも JavaScript のほうが優れていると感じるだろう.
基準をしめさない場合,「どちらが優れていか?」というのは主観的な問題だ
から,人に聞いてもあまり意味がないよ.

727:デフォルトの名無しさん
05/10/31 03:19:26
>lispと他のプログラムとの構文とかの


728:デフォルトの名無しさん
05/11/01 00:04:26
>>716 Maclisp と綴って欲しい

729:デフォルトの名無しさん
05/11/01 06:11:42
Win32バイナリが吐けるLispコンパイラはどこですか?

730:デフォルトの名無しさん
05/11/01 07:05:14
>>726
主観なわけねーじゃん。ばっかじゃないの

731:デフォルトの名無しさん
05/11/01 10:46:25
>>730
基準をしめさない場合、という条件でどこをどうやったら主観じゃなくなるのだ?

732:デフォルトの名無しさん
05/11/01 11:35:21
>>730の次のレスは「あまりの恥ずかしさに煽って逃げる」これ。

733:デフォルトの名無しさん
05/11/01 12:11:48
>>729
コーマンリスプなんてどうだ。
URLリンク(www.cormanlisp.com)

734:デフォルトの名無しさん
05/11/01 12:54:47
非商用なら無料なんだ。
corman はチェックしてなかったな。結構寛容なライセンスだね。

735:デフォルトの名無しさん
05/11/01 13:34:49
どうせポップアップウィンドウに


        t


とか表示させるだけだろ

736:デフォルトの名無しさん
05/11/02 00:11:24
ロジャーコーマンは腹出過ぎ。

737:デフォルトの名無しさん
05/11/02 00:30:12
Corman Lispって日本語通るようになったのかな?
要望あったら聞くよーてなメールも送ってきたくらい個人商店ぽいので
誰か日本で使い物になるなら買うから是非頼むといってやれば
なんとかしてくれるかも。


738:デフォルトの名無しさん
05/11/02 00:31:55
[CommonLisp とコンパイル - コンパイラスクリプトスレからの続き]

つまり Lisp においては「x に 2 を倍する」プログラムはデータ構造 (* x 2) と表現できるわけだ.
(もし熱烈な C/C++ & XML ファンならこの構文木をつくってよう)
さて,ここで操作する.もし「x に 2 を足す」にしたいと思ったとする.
これは Lisp では (+ x 2) と表現できる.インタプリタ上ならば

> code
(* x 2)
> (setf (car code) '+)
(+ x 2)

となる.(もし熱烈な C/C++ & XML ファンなら,同様の操作を表現してみよう )
さて,これをコンパイルしてみよう.このとき,コードは引数 x を一個とるわけなので関数で
ラップする.これは (lambda (x) (+ x 2)) と書ける.Common Lisp の compile メソッドを使うと

> (compile nil '(lambda (x) (+ x 2)))
#<compiled-function>

これでコンパイルされたコードが得られる.もしネイティブコードコンパイラ
を使っているならネイティブコードが得られる.確認したければ,すかさず

> (disassmble *)

とうてばよい.このようにコンパイラは Lisp 環境と統合されており,利用者が気軽に使える存在なのである.
(もし熱烈な C/C++ & XML ファンなら,表現した構文木をコンパイルしてからディスアセンブルしてみよう)


739:デフォルトの名無しさん
05/11/02 02:59:33
C で同じことやりたいなら cc -fpic 実行して dlopen するだけじゃない?
KCL 系だってそうやってんだし。

740:デフォルトの名無しさん
05/11/03 13:38:27
コンパイラスレのからの客人?でも KCL とかっていうことはこのスレの人かな?
まぁ,Lisp では手軽さがケタ違いです.C を直接さわったら操作するたびに,
C のソース <--> データ構造 を変換しなきゃいけないのですが,逆に S 式な
ら変換する必要はない.

まぁ,どうしてもと言うなら C っぽく入力列 (S 式風味) をパースしてコンパ
イル,実行という手順でもいい.例として forth 風味の言語を考えよう.

def double
2 *
end
def quad
double double
end
def fib
dup 1 > if
dup 1 - fib swap 2 - fib +
end
end
reset
5 quad fib print

これでフィボナッチ数列の 20 番目を表示したいとする.大袈裟に言うと,
たとえば gcc のバックエンドにこの言語のフロントエンドを作るという事になる.
これは手軽か?(まぁ,手間以外の難易度は Lisp だろうとなんだろうと簡単なんだけど…)

741:デフォルトの名無しさん
05/11/03 13:41:51
まずパッケージと,基本オペレータを準備する.まぁ,とりあえずスタックはリストで
表現し,スタックのクリア,表示,スタックトップの入れ替え,コピーという基本操作を
使う.算術演算子も lisp のやつを流用する.と,オペレータの定義はこうなる.

(defpackage :mini-forth (:use :cl) (:export #:parse #:run #:forth) (:shadow #:print #:pop #:push #:+ #:- #:* #:/ #:> #:< #:= #:>= #:<=))
(in-package :mini-forth)
(defparameter *stack* nil)
(defmacro defword (word args &body body)
(let ((binds (loop for v in args collect (list v '(cl:pop *stack*)))))
`(defun ,word () (let* ,binds ,@body))))
(defmacro default-operators (&rest operators)
`(progn
,@(loop for op in operators
collect `(defword ,op (x y) (cl:push (,(intern (symbol-name op) :common-lisp) y x) *stack*)))))
(defword print () (loop for e in *stack* for i from 0 do (format t "~&~4D: ~A~%" i e)))
(defword reset () (setf *stack* nil))
(defword swap (x y) (cl:push x *stack*) (cl:push y *stack*))
(defword dup (x) (cl:push x *stack*) (cl:push x *stack*))
(default-operators + - * / > < = >= <=)


742:デフォルトの名無しさん
05/11/03 13:43:17
あとは入力をパース(手抜き)する.

(defun parse (program &optional (ast nil) &aux (word (first program)))
(cond ((or (null program) (eq word 'end) (eq word 'else))
(values (nreverse ast) program))
((or (stringp word) (numberp word))
(parse (cdr program) (cons `(cl:push ,word *stack*) ast)))
((eq word 'if)
(multiple-value-bind (tree next)
(parse (cdr program))
(multiple-value-bind (tree2 next2)
(parse (if (eq (car next) 'else) (cdr next) next))
(parse (cdr next2) (cons `(if (cl:pop *stack*) (progn ,@tree) (progn ,@tree2)) ast)))))
((eq word 'def)
(multiple-value-bind (tree next)
(parse (cddr program))
(parse (cdr next) (cons `(defword ,(cadr program) () ,@tree) ast))))
(t (parse (cdr program) (cons `(,word) ast)))))

で,得られた S 式をコンパイル(Lisp コンパイラを流用)して実行.

(defun run (program)
(let ((tree (cons 'progn (parse program))))
(funcall (compile nil `(lambda () ,tree)))))


743:デフォルトの名無しさん
05/11/03 13:51:52
この forth もどきにさっきのプログラムを喰わせる.

MINI-FORTH> (run '( [さっきのプログラム] ))
0: 6765

計算できたッ!! ついでにこの簡易言語で定義された関数 fib とかはLisp コン
パイラでコンパイルされている.つまりネイティブコードコンパイラを使って
いればネイティブコードが得られる.

MINI-FORTH> (disassemble 'fib)
; 09AB6F66: 8BD4 MOV EDX, ESP ; no-arg-parsing entry point
; 6F68: 83EC0C SUB ESP, 12
; 6F6B: 8B05886DAB09 MOV EAX, [#x9AB6D88] ; #<FDEFINITION object for DUP>
; 6F71: 31C9 XOR ECX, ECX
; 6F73: 896AFC MOV [EDX-4], EBP
; 6F76: 8BEA MOV EBP, EDX
; 6F78: FF5005 CALL DWORD PTR [EAX+5]
; 6F7B: 8BE3 MOV ESP, EBX
[...]

…というような説明でどうかな?

744:デフォルトの名無しさん
05/11/04 01:46:00
む、つまりこれはforthのトランスレータ?
結構短く書けるもんだね。


ところで↓のスレとここはどう使い分けてるの?
スレタイ同じだから混乱するぜ。

【一日】CommonLisp【一門】
スレリンク(tech板)


745:デフォルトの名無しさん
05/11/04 02:05:48
スレタイが違うので混乱はしない。

746:デフォルトの名無しさん
05/11/04 04:54:18
>>744 宣伝乙

747:デフォルトの名無しさん
05/11/08 00:07:54
すいませんが、解の公式を使って二次方程式の解を出す関数の定義の仕方を
教えてください。どうも、±がどう表現していいか分からなくて…。
よろしくお願いします。

748:デフォルトの名無しさん
05/11/08 00:09:53
↑宿題?

749:デフォルトの名無しさん
05/11/08 00:13:37
たぶん。

>>747
> ±がどう表現していいか
思考様式の変革が必要だと思う

750:デフォルトの名無しさん
05/11/08 00:27:29
多値で返すとか、リストで返すとか好きなやり方選べばいいんでないの。

751:デフォルトの名無しさん
05/11/08 00:30:53
つうかやる気ねーんだろ?授業をちゃんと聞いてなかったみたいだし。「

いつも思うんだけどなんで〜日までの宿題ですやる気ないんで教えてください、
って素直に言えないのかね?まさか宿題である事を隠してるつもりなのか?なら
人をナメすぎだな。ほらこれを提出してごらん。俺は親切だから罠をしかけたりしないよ。

(defun solve (a b c)
"ax^2 + bx + c = 0"
(let ((A (- b))
(B (sqrt (- (* b b) (* 4 a c))))
(C (* 2 a)))
(values
(/ (+ A B) C)
(/ (- A B) C))))


752:デフォルトの名無しさん
05/11/08 00:39:19
漏れのエスパー能力によると>>747が求めているプログラムは Lispではないな。

753:デフォルトの名無しさん
05/11/08 00:41:43
>>750
±にあたるものが存在してないのが問題の山なのかも。
存在してても使いにくそうだけど。

754:デフォルトの名無しさん
05/11/08 05:01:13
そういえば複素数も扱えるんだよな
でも>>751はaが非零でないことくらいはチェックした方がいいと思う

755:747
05/11/08 22:31:36
どうもどうも。おかげさまで解決しました。
視点を変えました。>>751のプログラムもある意味参考にさせていただきました。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5384日前に更新/244 KB
担当:undef