【入門】Common Lisp その3【質問よろず】at TECH
【入門】Common Lisp その3【質問よろず】 - 暇つぶし2ch1:デフォルトの名無しさん
07/06/10 21:41:07
lispを触ってみたい入門者のQ&A
初心者のQ&A
本スレでは恥ずかしくて聞けない人のQ&A
本スレは高度すぎて割り込めない人のQ&A
linuxでなくてwindowsでやりたいんですが・・・Q&A
lispを使用してC#やJAVAの代替にするための方法(おまけ)

ま、ゆっくりたりましょう。

「いいものの本質は、いかなる時代においても変わらない」byパワーズ

(list
(url スレリンク(tech板)l50 :part 1)
(url URLリンク(pc11.2ch.net) :part 2))


2: ◆3.JjF77I26
07/06/10 23:08:04
2get

3:デフォルトの名無しさん
07/06/10 23:51:57
(apply #'乙 (>> 1))

4:デフォルトの名無しさん
07/06/11 00:12:46
((お勧めの Common Lisp 処理系)
(SBCL: URLリンク(sbcl.sourceforge.net)
:プラットフォーム UNIX, Linux, Mac, Windows(移植中)
:開発 活発
:日本語 使える(UCS4, UTF8, EUC)
:特徴 一番お勧めのコンパイラ。)

(CLISP: URLリンク(clisp.cons.org)
:プラットフォーム UNIX, Linux, Mac, Windows
:開発 そこそこ活発
:日本語 使える
:特徴 バーチャルマシン。遅いがフットプリントが小さい。)

(CMUCL: URLリンク(www.cons.org)
:プラットフォーム UNIX, Linux, Mac
:開発 そこそこ活発
:日本語 使えない(回避法有り)
:特徴 高速コンパイラ。SBCL の元になった。)

(OpenMCL: URLリンク(openmcl.clozure.com)
:プラットフォーム PPC-Linux, Mac, x86-Linux と FreeBSD に移植中
:開発 そこそこ活発
:日本語 使えない (pre ver 1.1なら多少扱える。)
:特徴 元々商用のコンパイラ。ネイティブスレッドが使える。))

5:デフォルトの名無しさん
07/06/11 00:14:29
((その他)
(ABCL: URLリンク(armedbear-j.sourceforge.net)
:特徴 JavaVM 上で動く。JavaVM のバイトコードを生成。)

(GCL: URLリンク(www.gnu.org)
:特徴 日本発 Kyoto Common Lisp の直系。)

(ECL: URLリンク(ecls.sourceforge.net)
:特徴 Lisp->C コンパイラ。組み込み可能らしい。こちらもKCLの系譜))

6:デフォルトの名無しさん
07/06/11 00:22:38
ANSI Commn Lisp 仕様関係
URLリンク(www.lisp.org)
URLリンク(www.cs.cmu.edu)
URLリンク(lispdoc.com)

日本語のチュートリアル
URLリンク(web.sfc.keio.ac.jp)
URLリンク(www.h7.dion.ne.jp)
URLリンク(www.geocities.jp)
URLリンク(home.soka.ac.jp)
URLリンク(www.haun.org)
URLリンク(wisdom.sakura.ne.jp)
URLリンク(www-kasm.nii.ac.jp)



7:デフォルトの名無しさん
07/06/11 00:24:18
進んだ話題が欲しい人に...
(和文)
URLリンク(www.geocities.co.jp)
URLリンク(www.geocities.co.jp)
URLリンク(lispuser.net)<)
URLリンク(www.cl-user.net)<)
URLリンク(planet.lisp.org)
URLリンク(groups.google.co.jp)
URLリンク(www.cliki.net)
URLリンク(cl-cookbook.sourceforge.net)
URLリンク(www.gigamonkeys.com)
( URLリンク(www.apress.com) よりpdf版が入手可能)
URLリンク(www.psg.com)
URLリンク(www.cs.cmu.edu)

その他の情報
URLリンク(ja.wikipedia.org)

8:デフォルトの名無しさん
07/06/11 00:26:37
((おまけの処理系
(POPLOG: URLリンク(www.cs.bham.ac.uk)
Lisp, Prolog, ML のコンパイラ)
(WCL: URLリンク(wcl.kontiki.com)
Shared Library として使える Lisp)
(Movitz: URLリンク(common-lisp.net)
フルスクラッチの Lisp OS)
(CADR LispM: URLリンク(www.heeltoe.com)
MIT で使われていた LispM のソースを公開したもの))

((その他のリンク
(Meme channels: URLリンク(meme.b9.com)
Lisp の IRC Log)
(Paul Graham の ANSI Common Lisp:
URLリンク(www.pearsoned.co.jp)
Common Lisp の 参考書を探しているならこれ一択))

9:デフォルトの名無しさん
07/06/11 00:29:13
テンプレコピー終了。lispdoc.comや洋書pdf/hpをくわえた。あとは、on lisp
が和書として登場した事も記しておかないと。

10:デフォルトの名無しさん
07/06/11 00:38:53
乙。
テンプレに Allegro って入ってないのね。商用だから?


11:デフォルトの名無しさん
07/06/11 00:44:52
触った事がないからくわえ忘れた。
商用CL
URLリンク(jp.franz.com)
free downloadから登録して使えるらしい
URLリンク(www.lispworks.com)
IDEがついているらしい

12:デフォルトの名無しさん
07/06/11 01:53:11
┌──────┐
|scheme自重しろww ちょww|
|   ↑自重(ry             |
|ーかそれはないだろww    |
|                  |
|                  |
|                  |
|   リリカルは俺の嫁。   .|
└──────┘

13:デフォルトの名無しさん
07/06/13 03:41:07
すいません、明日提出の課題で完全に煮詰まってしまってもう何も浮かんできません
どなたか教えていただけないでしょうか

14:デフォルトの名無しさん
07/06/13 03:42:31
どうぞ。

15:デフォルトの名無しさん
07/06/13 03:43:21
ありがとうございます。

16:デフォルトの名無しさん
07/06/13 03:44:03
はやくしろ。

17:デフォルトの名無しさん
07/06/13 03:45:50
まだか?

18:デフォルトの名無しさん
07/06/13 03:46:37
やっぱりもう寝る。
俺のほかにも、少なくとも1人居るみたいだから任せた。

19:デフォルトの名無しさん
07/06/13 04:07:51
申し訳ありません!お待たせしました

9
(1 1 1 1 1 1 1 0 1)
(1 0 0 0 0 0 0 0 1)
(1 0 1 0 1 1 1 0 1)
(1 0 1 0 0 0 1 0 1)
(1 0 1 1 1 0 1 0 1)
(1 0 1 0 0 0 1 0 1)
(1 1 1 0 1 1 1 0 1)
(1 0 0 0 1 0 0 0 1)
(1 0 1 1 1 1 1 1 1)

上記のようなデータが入ったテキストファイルを読み込んで、迷路を解くという問題です
最初の数字が迷路のサイズを表していて、ここでは9なので9*9です
1が壁、0が道となっています



20:デフォルトの名無しさん
07/06/13 04:09:07
次の手順を追って作成するようになっています

a.迷路ストラクチャを定義せよ.迷路ストラクチャは,迷路のサイズ(整数値)と迷路の形状データ(2次元配列)を保持する

b.迷路ファイル名を引数に受け取り,それを読み込み迷路ストラクチャを返す関数 load-maze を定義せよ
>(load-maze "m9.txt")
#S(MAZE SIZE 9 DATA
#2A((1 1 1 1 1 1 1 1 1) (1 0 0 0 0 0 1 0 0) (1 0 1 1 1 1 1 0 1)
(1 0 0 0 1 0 0 0 1) (1 0 1 0 1 0 1 1 1) (1 0 1 0 0 0 1 0 1)
(1 0 1 1 1 1 1 0 1) (0 0 0 0 0 0 0 0 1)
(1 1 1 1 1 1 1 1 1)))



21:デフォルトの名無しさん
07/06/13 04:10:06
.迷路ストラクチャを引数に受け取り,迷路のデータを表示する関数 print-maze を定義せよ
>(setq m (load-maze "m9.txt"))
>(print-maze m)
■■■■■■■ ■
■       ■
■ ■ ■■■ ■
■ ■   ■ ■
■ ■■■ ■ ■
■ ■   ■ ■
■■■ ■■■ ■
■   ■   ■
■ ■■■■■■■

NIL

d.迷路データファイルを入力として受け取り,スタートからゴールまでの最短パスを出力する関数 solve-maze を作成せよ.プログラムがなるべく読みやすくなるよう作成すること
>(solve-maze "m9.txt")
■■■■■■■*■
■  *****■
■ ■*■■■ ■
■ ■***■ ■
■ ■■■*■ ■
■ ■***■ ■
■■■*■■■ ■
■***■   ■
■*■■■■■■■

Solved!
NIL

22:デフォルトの名無しさん
07/06/13 04:11:17
すいません、迷路が上手く書けませんでした

23:デフォルトの名無しさん
07/06/13 06:33:33
まずは教官に「宿題をやってなかったので提出期限を一週間延ばしてください」と
お願いにいくところから始めよう。

24:デフォルトの名無しさん
07/06/13 07:01:01
難しいな。
見た事あるけれど、たしか、プログラミングコンテストの問題だった気がする。
本があったかなぁ?

25:デフォルトの名無しさん
07/06/13 07:10:08
プロコンですか・・・解ける気が全くしないですorz

26:デフォルトの名無しさん
07/06/13 07:13:40
朝っぱらから楽しげだなw
cl-user(142): (defstruct maze size data)
maze
cl-user(143): (make-maze :size 4 :data #2a((1 0 0 0) (1 0 0 0) (1 0 0 0) (0 1 0 0)))
#S(maze :size 4 :data #2A((1 0 0 0) (1 0 0 0) (1 0 0 0) (0 1 0 0)))
経路探索はこのデータ構造じゃ面倒臭い気がするけど、
>>6 の hiroi 氏のページ見たら何とかなるんじゃね?

27:デフォルトの名無しさん
07/06/13 07:30:29
発狂hiroiさんのページを見せてもらったんですが、やっぱりダメみたいです

(1 1 1 1 1 1 1 0 1)
(1 0 0 0 0 0 0 0 1)
(1 0 1 0 1 1 1 0 1)
(1 0 1 0 0 0 1 0 1)
(1 0 1 1 1 0 1 0 1)
(1 0 1 0 0 0 1 0 1)
(1 1 1 0 1 1 1 0 1)
(1 0 0 0 1 0 0 0 1)
(1 0 1 1 1 1 1 1 1)

↑のデータをテキストから読んで、構造体の中の配列に入れることができないです・・・

28:デフォルトの名無しさん
07/06/13 07:41:47
>>27
発狂って何?
read 関数はS式単位で読み込めるので何も難しいこと無いと思うが、、
さては授業まったく聞いてないな?w

おれは仕事行くけど誰かこの駄目学生見てあげて、気が向いたらでいいw

29:デフォルトの名無しさん
07/06/13 07:47:49
授業料もったいねーなぁ。ところでスタートとゴールの定義がわからねーんだけど。
それぞれ座標固定でいいの?

(defstruct maze size data)

(defun load-maze (file)
(with-open-file (stream file :direction :input)
(let ((size (read stream)))
(make-maze :size size
:data (make-array (list size size)
:initial-contents (loop for data = (read stream nil :eof) until (eq data :eof) collect data))))))

(defun print-maze (maze &aux (size (maze-size maze)))
(loop for row below size do
(loop for col below size do
(princ (if (eq (aref (maze-data maze) row col) 1) "+" " ")))
(terpri)))

30:デフォルトの名無しさん
07/06/13 07:48:09
発狂しそうです
って書こうと思ってやめたんですけど、発狂だけ残ってましたw
お察しの通り授業全く聞いておりませんでしたorz
一行ずつ配列に追加していこうと思ったんですが、consみたいに配列に追加していく関数もないし、どうすれば良いかわからない状況です
お仕事前にありがとうございました!

31:デフォルトの名無しさん
07/06/13 07:50:44
#include <stdio.h>
int W(int x ,int y);
int a[9][9] ={
{1,1,1,1,1,1,1,0,1},
{1,0,0,0,0,0,0,0,1},
{1,0,1,0,1,1,1,0,1},
{1,0,1,0,0,0,1,0,1},
{1,0,1,1,1,0,1,0,1},
{1,0,1,0,0,0,1,0,1},
{1,1,1,0,1,1,1,0,1},
{1,0,0,0,1,0,0,0,1},
{1,0,1,1,1,1,1,1,1}
};
int main (void){
int hoge = 0;
hoge = W(1,1);
printf("%d¥n",hoge);
}
int W(int x, int y){
if(a[x][y]) return 0;
a[x][y] = 1;
return W(x,y-1)+W(x,y+1)+W(x-1,y)+W(x+1,y)+1;
}
C言語だけれど、できたじぇー。
コレをLISPに改造していけばOKなはず。
ちゃんと再帰を使ってるしね。
公立大学経済学部の力を見たカー!


32:29
07/06/13 07:52:16
ほほう、近年稀にみる素直さだな。バレバレの嘘よりは好ましい。
はやくゴールとスタートの定義おしえてよ。急いでるんだろ?

33:デフォルトの名無しさん
07/06/13 07:54:51
>>29さんも>>30さんもありがとうございます
スタートが左下、ゴールは右上となっています

34:デフォルトの名無しさん
07/06/13 07:56:17
>>30じゃなくて>>31さんです、すいません!

35:31
07/06/13 08:18:07
なんかダメダメっぽい。
一応考えを書いておくね。
もしa(x,y)が1ならば、行ける場所は0
そうでなければ、a(x,y)=1にして、周囲4近傍における合計値+1
それの再帰で行ける場所が求まるはずなんだけれど。

36:デフォルトの名無しさん
07/06/13 08:37:01
そうですか、でも>>29のところまででも凄いタメになりました!
ただ、loop for~のくだりがこちらでは使えないんですが、どういうものなのか教えてもらえませんか?

37:29
07/06/13 08:42:30
(defun solve-maze (maze &aux (start '(8 1)) (goal '(0 7)) (size (maze-size maze)) (buffer (make-array (list size size) :initial-element nil)) (path nil))
(labels ((calc-step (pos n &aux (x (first pos)) (y (second pos)))
(cond ((or (< x 0) (< y 0) (>= x size) (>= y size)) :skip)
((or (= (aref (maze-data maze) x y) 1) (aref buffer x y)) :skip)
(t
(setf (aref buffer x y) n)
(calc-step (list (1+ x) y) (1+ n)) (calc-step (list x (1+ y)) (1+ n)) (calc-step (list (1- x) y) (1+ n)) (calc-step (list x (1- y)) (1+ n)))))
(find-path (pos n &aux (x (first pos)) (y (second pos)))
(cond ((or (< x 0) (< y 0) (>= x size) (>= y size)) :skip)
((or (= (aref (maze-data maze) x y) 1) (null (aref buffer x y))) :skip)
((= (aref buffer x y) n)
(push pos path)
(find-path (list (1+ x) y) (1- n)) (find-path (list x (1+ y)) (1- n)) (find-path (list (1- x) y) (1- n)) (find-path (list x (1- y)) (1- n))))))
(calc-step goal 1)
(let ((n (aref buffer (first start) (second start))))
(cond ((null n) (error ">_<"))
(t
(find-path start n)
(loop for x below size do
(loop for y below size
for wallp = (= (aref (maze-data maze) x y) 1)
for step = (member (list x y) path :test #'equal) do
(princ (cond (wallp "+")
((null step) " ")
(t "*"))))
(terpri))
(write-line "Solved!"))))))


38:29
07/06/13 08:44:18
途中で、経路複数とか考えるの止めたのでちょっと冗長だが…って、 LOOP がエラー?
環境は何なの?今時の Common Lisp で LOOP が無い環境なんてあるの?

39:29
07/06/13 08:46:02
むしろ俺がそちらの環境を教えてくださいませんか?というキブン。

40:デフォルトの名無しさん
07/06/13 08:47:13
こんなに長いプログラム作ってくださって本当にありがとうございます
loopは大丈夫なんですけど、forのところで引っかかるみたいなんです

41:デフォルトの名無しさん
07/06/13 08:49:04
環境はGnu Common Lispというものみたいです

42:29
07/06/13 08:51:56
だーから使ってる Lisp 環境を教えろって。それが古すぎるんじゃないか?
LOOP FOR ... は 20 年以上前の ANSI Common Lisp で規格に入った機能。それ以前の
処理系には LOOP FOR はない。(ただの LOOP はある)
CLISP, GCL, SBCL, ABCL, ECL, LispWorks, ACL で LOOP FOR が使えない環境なんてないぞ。
しぬほど古いバージョンの GCL でも使ってるのか?

43:デフォルトの名無しさん
07/06/13 08:53:07
死ぬほど古いバージョンのGCLのようですorz

44:29
07/06/13 08:58:26
あれ? GCL か? -ansi オプションとかそんなんついていない?
うーむ。じゃあ do に直して使って。この書換えはなんか参考書とか教科書とか。

(loop for data = (read stream nil :eof) until (eq data :eof) collect data)

(do ((data (read stream nil :eof) (read stream nil :eof))
(lst nil (cons data lst)))
((eq data :eof)
(reverse lst)))

(loop for x below size do (princ x))

(do ((x 0 (1+ x)))
((>= x size))
(princ x))


45:デフォルトの名無しさん
07/06/13 08:58:53
といってもバージョンは(2.4.0)みたいです・・・

46:デフォルトの名無しさん
07/06/13 09:05:40
何から何までありがとうございます
今日の課題を出せば少し暇になるのでまた見直して勉強させて頂きます!

47:29
07/06/13 09:23:45
せっかく払った授業料だ。元が取れるようにガンバレよ。今からならまだ遅れも取り戻せるだろう。
歩数マップを作って解く形式だったが、本当はスタートから辿っていくほうがいいのかもしれないなぁ。
別のやり方を考えてみるのもいいと思う。あとは 37 のイケてない所をチェックして直すとかね。

48:デフォルトの名無しさん
07/06/13 09:54:53
3・4週間前までは課題も楽しくできてたんですが、少し遅れてしまったようです
他の人のプログラムの書き方を見ることができたのは本当にためになりました
ありがとうございます!

49:デフォルトの名無しさん
07/06/13 11:51:29
>>24
スタートとゴールがそれぞれ上と下にしかない &
Lispということを考えると再帰使って式書けばFizzBuzz並みに簡単だと思うがね。

50:デフォルトの名無しさん
07/06/13 12:01:09
>>31 のコードは何をしてるのか気になる

51:デフォルトの名無しさん
07/06/13 16:08:44
迷路を解く問題って非決定性のアルゴリズムを使う必要があるんじゃないの?
教官の狙いはa-bを解ければ合格でcを解いたらBランク。dを解いたらAランクの
評価を与えるのだろう。初心者が解けなくて当然だと思ってよいかもね。

授業で非決定性をやってるかどうか知らないけど、それ以外の方法も含めて
授業でやった事が大きなヒントになってるよ。スキームな人ならcall/ccを
使いそうな気がするね。clでもon lispをみればcall/ccはできる。

52:デフォルトの名無しさん
07/06/13 16:53:32
しらみつぶしで簡単に求まる問題でしょ。非決定性なんて必要ないよ。

53:デフォルトの名無しさん
07/06/13 19:33:18
>>51 は、自分の豊富な (と思ってる) 知識を披露しただけだろ。

54:デフォルトの名無しさん
07/06/13 20:04:03
fizzbuzz並みに簡単かどうか別として、再帰を利用すれば解ける問題だった。
それは一応確認した。豊富な知識(と思ってる)のかしらないけど、
いろんな事は検討してみましたがね。

52や53のような輩にレスを返しても荒れるだけだったな。2ちゃんならではの
このての人種とは関わりたく無い
では失礼。

55:デフォルトの名無しさん
07/06/13 20:05:50
日本人じゃなかったみたいだな

56:デフォルトの名無しさん
07/06/13 22:10:46
何で list じゃなくて二次元配列なんだろ。
手抜きで C の課題をそのまま lisp にしたのかな?

57:デフォルトの名無しさん
07/06/13 22:15:25
え??マップは二次元データだから二次元配列でいいじゃん。
ランダムアクセスするし。いちいちリストたぐるなんて無駄じゃん。
この例でわざわざリストを使うなんて CL としてはありえないだろう。

58:デフォルトの名無しさん
07/06/13 22:15:45
縦と横の操作の対称性を考えると配列のほうがベターじゃね?
解くときはランダムアクセスが必要だろうから配列のほうが速いし

59:デフォルトの名無しさん
07/06/13 22:35:18
>>57, 58
配列の方が早いのは勿論分かるけど、宿題レベルだと関係なくない?
>>27 なんてデータを配列に読み込むだけで挫折してるわけだし。


60:デフォルトの名無しさん
07/06/13 22:41:53
簡単にできたら宿題の意味が無いかも

61:31
07/06/13 22:48:45
>>50
>>>31 のコードは何をしてるのか気になる
えっと、斜めには進めないと考えて、
もしa(x,y)が1ならば、行ける場所は0(壁だから)
そうでなければ、a(x,y)=1にして、周囲4近傍における合計値+1
それの再帰で、最終的にマスすべてをしらみつぶしに調べて
行ける場所(進めるマスの総計)が求まる
はずなんだけれどなぁ、と深く考えずに書いてしまいました。
正直スマンカッタ。
でも、こんな感じの考え方を進めていけばいいんじゃないかなぁと思ったんです。

62:デフォルトの名無しさん
07/06/13 23:44:57
>>59
「配列の勉強に対する宿題かも」ぐらいの想像力があってもいいと思うんだが。

63:29
07/06/14 00:05:31
……なんか荒れてるなぁ。で、他にネタもないので質問者が見てるかもしれないので軽く説明しとこう。
朝のプログラム歩数マップ(ゲームなんかで移動範囲がピコーンって光るやつみたいな)を作成してから、目的地へのルートを撰択するのね。
で、↓がスタート地点から総当たりでルートを探索してゆく(カベにぶつかったり戻ったりはナシのほうこうで)。
途中の通った経路をどんどん覚えていってゴールまでの全ルートを列挙。最後に最短のものを選ぶ。

(defun print-maze (maze &optional path &aux (size (maze-size maze)))
(loop for row below size do
(loop for col below size do
(princ (cond ((eq (aref (maze-data maze) row col) 1) "+")
((member (list row col) path :test #'equal) "*")
(t " "))))
(terpri)))

(defun solve-maze-2 (maze &aux (start '(8 1)) (goal '(0 7)) (data (maze-data maze)) (size (maze-size maze)))
(labels ((find-path (path pos &aux (x (first pos)) (y (second pos)))
(cond ((or (< x 0) (< y 0) (>= x size) (>= y size) (= (aref data x y) 1) (member pos path :test #'equal)) nil)
((equal pos goal) (list (cons pos path)))
(t
(mapcan #'(lambda (d)
(destructuring-bind (dx dy) d
(find-path (cons pos path) (list (+ x dx) (+ y dy)))))
'((1 0) (-1 0) (0 1) (0 -1)))))))
(let ((found (find-path nil start)))
(if (null found) "経路が見つかりません!! >_<" (print-maze maze (first (sort found #'< :key #'length)))))))


64:29
07/06/14 00:06:42
age ちった…。で、おそらくこれが 31 が示そうとしたコードかなと思った。

65:29
07/06/14 00:13:15
何度もすまん、>>61 にイイ線いってたよと言いたかった。風邪ひいてボケてるな。
おしかったのは行ける方向を数値にして足しちゃうと経路として使えないんだよね。
座標を覚えておくか、歩数マップみたいに移動コストを計算して最短経路を選ぶかすれば正解だった。

66:CLer
07/06/14 01:02:39
>65
イイ線いっていないと思うんですが……。
31の回答で(解けていなくて)惜しい点というのが、
最短経路を求める問題そのものなのではないですか?
だいたい、31の方法ではある座標をすでに通過したかどうかが判定できず、
いつまでも同じところを巡回する可能性がありませんか? というか……、
この再帰は抜けられるんですかね……。

67:65
07/06/14 01:24:34
周囲を再帰的に探索していくという点が最初の壁だと思うから着眼点はいいと思うよ。
ここがわかればあとは条件を足すだけじゃん。壁チェックはしてあるから
1. 同じところでいったりきたりしない工夫 (経路を覚えるとかマップにマークするとか)
2. ゴールで止まる
の二点が不足してただけ。配列を一回り大きくして外側を全部壁で囲っちゃえば座標チェックは省略できるしー。
31 のままじゃ無限ループに陥いって抜けられないけど、俺は評価したいね。
俺が C しか知らなかった頃には再帰的な探索なんて考えつかなっただろうという個人的理由が大きいけど。

68:デフォルトの名無しさん
07/06/14 03:00:42
文字列の最初の一文字を返すのと,それ以外の部分を返す関数ってないっすか?
文字列のcar, cdr見たいなことをしたいっす.

69:デフォルトの名無しさん
07/06/14 03:20:00
>>68
(subseq "ABC" 0 1) => "A"
(subseq "ABC" 1) => "BC"

70:デフォルトの名無しさん
07/06/14 04:28:35
>>69
ありがとうございます
もう一つ質問させてください
Lispってループを抜けるC言語で言うbreak見たいな
ものってないんですか?

71:デフォルトの名無しさん
07/06/14 06:40:33
リターンを使えば抜けれますよ、sumっていう変数があるとすると
(return sum)
と書けばループを抜けて、loopの値がsumとなります
(return)
だけだとloopの値はnilになります

72:デフォルトの名無しさん
07/06/14 09:01:45
vimでlisp書いてるんだけど、インデントにスペースとタブの両方が使われる。
インデントはスペースだけにしたいんだけど、誰か何とかする方法知らない?

余談:
emacsでCを編集したらインデントにタブとスペースの両方使われて、
vimでCを編集したらインデントはタブだけが使われたはず。
なんでlispだと逆転するのかね……

73:デフォルトの名無しさん
07/06/14 09:31:31
vim tab space でググるくらいはしたらどうか。
聞くとしてもスレ違い。

74:デフォルトの名無しさん
07/06/14 15:07:33
>>72
スレチだけど、EmacsのCの編集でスペースで統一するのはc-mode-common-hookあたりで
(setq indent-tabs-mode nil)すればよろし。

75:デフォルトの名無しさん
07/06/14 16:02:36
(defpackage :maze (:use :common-lisp))
(defun read-maze (filename)
(reverse
(with-open-file (s filename)
(let* ((size (read s)) m)
(dotimes (cnt size m) (setq m (cons (read s) m)))))))
(defun print-maze-1 (row)
(format t "~&~A~%"
(loop for b in row collect (elt '(#¥. #¥X #¥Space) b))))
(defun print-maze (maze)
(loop for row in maze do (print-maze-1 row)))
(defun wall (maze x y) (elt (elt maze y) x))
(defun count-ways (maze x y)
(case (wall maze x y)
(1 nil) (2 t)
(otherwise
(loop for dx in '(0 -1 1 0)
for dy in '(-1 0 0 1)
count (zerop (wall maze (+ x dx) (+ y dy)))))))
(defun solve-maze-1 (maze)
(append (list (first maze))
(loop for y from 1 to (- (length maze) 2)
collect (append '(1)
(loop for x from 1 to (- (length (car maze)) 2)
collect (case (count-ways maze x y)
((NIL) 1) ((0 1 t) 2) ((2 3) 0)))
'(1)))
(last maze)))
(defun solve-maze (maze)
(let ((m (solve-maze-1 maze))) (if (equal m maze) m (solve-maze m))))

76:75
07/06/14 16:59:33
LISP勉強中の素人ですが
Slimeの操作の練習を兼ねて作ってみますた。
本題と違いますけどSlime便利ですね。

77:デフォルトの名無しさん
07/06/15 06:53:25
ちょっと質問なんですが

(cons "aaa" (cons "bbb" "ccc"))
ってやると
("aaa" "bbb" . "ccc")
こうなっちゃいます...
これを
("aaa" "bbb" "ccc")
こうしたいんですが...

すみませんくだらない質問で,どなたかは教えてください...

78:デフォルトの名無しさん
07/06/15 07:03:00
> (cons "aaa" (cons "bbb" "ccc"))
> ってやると
> ("aaa" "bbb" . "ccc")
> こうなっちゃいます...

当然だろ。何の不思議もない。

> これを
> ("aaa" "bbb" "ccc")
> こうしたいんですが...

(cons "aaa" (list "bbb" "ccc"))
(cons "aaa" (cons "bbb" (cons "ccc" '())))

79:デフォルトの名無しさん
07/06/15 07:21:10
cons cellとか知らないままlisp使ってる人も
最近はたくさんいそうだな。

80:デフォルトの名無しさん
07/06/15 07:29:42
>>78
すみません,もう一つ質問させてください
(setf foo (list "aaa" "bbb"))
(cons "aaa" foo)
(cons "bbb" foo)
(cons "ccc" foo))

consの説明を読むと,2番目の引数がListであれば先頭に一つ要素を追加してゆく
と書かれているので,私としては.

最終的に

("ccc" "bbb" "aaa" "aaa" "bbb")
と成るはずだと思ったのですが.
実際にやってみると

("ccc" "aaa" "bbb")
となってしまいます.
ということは
「2番目の引数がListであれば先頭に一つ要素を追加してゆく」というのは
本の間違いですか?

81:デフォルトの名無しさん
07/06/15 07:38:12
>>80
cons は先頭に追加する、んじゃないよ。新しいのを返す。
元々の foo は setq しないと変更されないよ。

82:デフォルトの名無しさん
07/06/15 07:58:37
>>81
なるほど,よくわかりました

83:デフォルトの名無しさん
07/06/15 17:08:07
岩波の「Common Lisp 入門」って良いですか?

84:デフォルトの名無しさん
07/06/16 03:14:44
良いかどうかはわかんないですけど学校の教科書にはなっとります

85:デフォルトの名無しさん
07/06/16 05:03:08
Lisp関数の探し方というか絞り込み方がよくわかりません。
java,c++,等ならパッケージ、ライブラリなどから必要そうなクラスの名前がだいたい検討がつくのですが
関数一覧から探すのはちょいとしんどいです。
なにかカテゴリー分けされた辞書みたいなものは無いものでしょうか?



86:デフォルトの名無しさん
07/06/16 07:44:04
>>85
HyperSpec はまさに辞書だけど駄目?
URLリンク(www.lisp.org)
クックブックもあるよ。
URLリンク(cl-cookbook.sourceforge.net)

おれはようやくHyperSpecの引きかたに慣れてきたよ。やっぱ辞書は
手に馴染むと便利だね。

87:デフォルトの名無しさん
07/06/16 09:36:29
ACL で、:zoom によるトレース結果ではなくて、
ソースのエラー発生箇所をそのまま出力させる事はできないですか?

88:デフォルトの名無しさん
07/06/16 09:43:11
>>86 このクックブックはいいね~。

89:デフォルトの名無しさん
07/06/16 11:13:50
任意の正実数 c,および,2 以上の任意の整数 m が仮引数として与えられたとき c の m 乗根
を計算する関数 root を,初期値を 1.0 かつ err を 0.1 としニュートン法を用いて定義したんですが、うまく作動しません。
>(root 5 5)とか入力します


(defun absolute (x)
(cond ((< x 0) (- 0 x))
((= x 0) 0)
((> x 0) x)))
(defun near (a b err)
(< (absolute (- a b)) err))
(defun betterpwr (x m c)
(+ (* (- 1 (/ 1.0 m)) x)
(/ (+ c 0.0)
(* m (mypwr x (- m 1))))))
(defun root-core (c m x err)
(if (near c (mypwr x m) err)
x
(root-core c m (betterpwr x m c) err)))
(defun root (c m)
(root-core c m 1.0 0.1))

間違っている点はありますか?

90:デフォルトの名無しさん
07/06/16 11:17:34
なんかみにくいですねすいません。インデントがうまく反映されませんでした

91:デフォルトの名無しさん
07/06/16 11:26:06
あ、解決しました
mypwr入れ忘れてた orz

92:デフォルトの名無しさん
07/06/16 11:50:30
>>86
おお、ありがたい、これのローカル参照可能な版があればもっとありがたいです。

15MB,2300fileもあってwgetするのも気が引けるし。
なにより普段からIPリーチャブルじゃないので。






93:デフォルトの名無しさん
07/06/16 12:10:48
>>84
どうも、では読んでみます。

94:デフォルトの名無しさん
07/06/16 12:44:06
>>92
URLリンク(www.lispworks.com)
Emacs+SLIMEという環境だけど、ポイント位置のシンボル拾って
hyperspecを引くコマンドもあって便利すぎます><

95:デフォルトの名無しさん
07/06/16 12:51:44
>>92
ひょっとして手元にない人も多いのか? LispWorks や Allegro 入れると一緒に入って
ヘルプコマンドが引いてくれるんだよね。フリーの CL でも SLIME から引ける。
URLリンク(www.lispworks.com)

lispuser.net で配布されてる clisp + slime のやつもローカルのを引くのが推奨みたいよ。
↓は附属の .emacs から抜粋。俺は Win じゃないんで試してないが、IE が起動するのかな?

(require 'hyperspec)
(setq common-lisp-hyperspec-root
(concat "file://" (expand-file-name "~/doc/HyperSpec/"))
common-lisp-hyperspec-symbol-table
(expand-file-name "~/doc/HyperSpec/Data/Map_Sym.txt"))

96:デフォルトの名無しさん
07/06/16 13:04:44
>>83
岩波の Common Lisp 入門って ANSI 以前の CLtL の頃の本じゃなかったっけ?
一通り読んだら ANSI Common Lisp あたりに手を出すのが良いと思う。

97:デフォルトの名無しさん
07/06/17 01:02:16
>>83
岩波 livejournal lisp でググって見て。
良い点と悪い点がかかれてるページに出くわすから。

98:デフォルトの名無しさん
07/06/17 12:50:59
sbclを使っています。requireを使うと、標準出力にぞろぞろとメッセージが出ますが
あれを出さないようにはできないんでしょうか?sb-executableで実行形式にコンパイルすれば
でないのかなとか思ってやってみましたが、実行形式でも出ちゃいます。

99:デフォルトの名無しさん
07/06/17 15:00:18
>>98
--noinform
を付けると出ないようになると思います
URLリンク(www.sbcl.org)


100:98
07/06/18 21:59:33
--noinformは付けてましたが、それでも出てしまいます・・・。


101:デフォルトの名無しさん
07/06/18 22:42:54
ACL(フリーの奴)で、巨大なテキストファイル(数十MB)を調べているのですが、
遅くて困ってます。

with-open-file で開いて普通に read-line で読んでシェルのwlとかgrepみたいな
事をしているのですが、 perl の方が早いんです…コンパイルしてるのに…orz
何か良い方法ないですか?


102:デフォルトの名無しさん
07/06/18 23:11:48
その遅いところだけ perl 使えばいいと思うが...。

103:デフォルトの名無しさん
07/06/18 23:12:29
sbclに乗り換えるとかw
製品(の評価版)だとLispWorksが速かったような記憶がある(5年くらい前の話)

104:101
07/06/18 23:18:30
>>102
perlより遅いって下手丸出しで何か悔しいんですが、、
perlはどんな技でテキスト処理を早くしてるんですかねぇ?
>>103
うーん。できればaclで済ませたいです。


105:デフォルトの名無しさん
07/06/18 23:18:51
>>102
その思考に至るまでに、大抵の奴は宗教的言語熱に嵌るんだなあ。
塩だけで料理は出来ないのに、何でも塩焼きが一番みたいに考えるw

106:デフォルトの名無しさん
07/06/18 23:35:57
俺は鯖の塩焼きより味噌煮の方が好きだな。

107:デフォルトの名無しさん
07/06/18 23:42:57
Perl の正規表現エンジンは C でカリカリにチューニングされてると聞くけど、
Perl vs CL の対決なのではなくて、C vs CL の対決になってるんじゃないの。

108:デフォルトの名無しさん
07/06/19 00:49:49
無駄なIOとか、本質的でない部分で時間くってんじゃね?

109:デフォルトの名無しさん
07/06/19 00:50:52
とりあえず、どこがボトルネックが探るのが先決だねえ

110:デフォルトの名無しさん
07/06/19 06:11:08
正規表現エンジンと言えば、CL-PPCRE はどう?

111:101
07/06/19 07:23:13
誤解を招きましたが正規表現の問題じゃなかったです。すみません。

調べかたがよく分かんないですが、perlの場合ディスクキャッシュが使えてて、
CLだと使えてないような気もしてきました。
プロファイルとっても大量に呼ばれる read-line そのものが時間食ってる感じです。


112:デフォルトの名無しさん
07/06/19 07:36:42
>>111
久しぶりに来たらなんか変な方向に進んでるな…。ディスクキャッシュは関係ないよ。

メモリ消費を比べればわかるが read-line は必ず「新しい文字列」を返すんだよ。
で、大量のテキストを読み込むと GC のコストがばかにならない。
read-sequence で一気に読んだり、同じバッファを使い回したりもできるが、
実は最新の ACL だとズバリその用途の read-line-into なんてのがある。
URLリンク(www.franz.com)

113:デフォルトの名無しさん
07/06/19 10:00:14
            _,,..r'''""~~`''ー-.、
            ,,.r,:-‐'''"""~~`ヽ、:;:;:\
           r"r          ゝ、:;:ヽ
   r‐-、   ,...,, |;;;;|       ,,.-‐-:、 ヾ;:;ゝ
   :i!  i!  |: : i! ヾ| r'"~~` :;: ::;",,-‐‐-  `r'^!
    !  i!.  |  ;| l|  ''"~~   、      i' |   グレアム見てる? イェーイ!
     i! ヽ |  | |    ,.:'"   、ヽ、   !,ノ
    ゝ  `-!  :| i!  .:;: '~~ー~~'" ゙ヾ : : ::|
   r'"~`ヾ、   i! i!   ,,-ェェI二エフフ : : :::ノ~|`T
  ,.ゝ、  r'""`ヽ、i! `:、   ー - '" :: : :/ ,/
  !、  `ヽ、ー、   ヽ‐''"`ヾ、.....,,,,_,,,,.-‐'",..-'"
   | \ i:" )     |   ~`'''ー---―''"~
   ヽ `'"     ノ

114:101
07/06/19 22:18:11
>>112
read-sequence!ビンゴです。おかげで perl と同じくらいになりました。
実はread-sequenceには気づいていたのですがシーケンスは関係ないと
思い込んでいました。文字列もシーケンスでした‥‥
探したら役に立つ記事見つけました
URLリンク(www.emmett.ca)
どうもありがとうございました。


115:デフォルトの名無しさん
07/06/20 00:32:46
>>114
君はいい子だからこれからも来るように

116:デフォルトの名無しさん
07/06/20 01:12:52
******恋のおまもり******

  これを見た人は,超超超超幸せもの☆☆

  ①週間以内に好きな人に告白されるか、
■■■■■■■■■■■■■■■■■■
■■■■□□□■■■■□□□■■■■
■■■□□□□□■■□□□□□■■■
■■■□□□□□□□□□□□□■■■
■■■□□□□□□□□□□□□■■■
■■■□□□□□□□□□□□□■■■
■■■■□□□□□□□□□□■■■■
■■■■□□□□□□□□□□■■■■
■■■■■□□□□□□□□■■■■■
■■■■■■□□□□□□■■■■■■
■■■■■■■□□□□■■■■■■■
■■■■■■■■□□■■■■■■■■
■■■■■■■■■■■■■■■■■■

  好きな人とイイ事があるよ・・・・☆★

  コレを読んだら、1時間以内にどこかに貼る★★

数ゎあなたが好きな人への思いを込めて

117:デフォルトの名無しさん
07/06/20 03:03:56
>>116
好きな人がいない場合はどうすれば良いんでしょうか?
っーか、行動半径に妙齢の女性がいないんですけれども。

話は変わって質問です。
(defun reverse$ (lst)
(if (null lst) nil
(append (reverse$ (rest lst))
(list (first lst)))))

でリストの長さnがある程度長いとするとreverse$の計算時間がnの2乗に
比例すると本に書いてあって、
時間をT(n)として、
(rest lst)の長さは
n-1なので(reverse$ (rest lst))の計算時間はT(n-1),
(list (first lst))の時間は1,appendの時間はn-1となる。
T(0)=1とみなすと、
T(n)=T(0)+1+2+......+n=(n^2+n+2)/2,n=0,1,.....
と説明してあるのですが、いまいちピンと来ません。
どうしてこのreverse$の計算時間がリストの長さの2乗になるのでしょうか?

118:デフォルトの名無しさん
07/06/20 03:24:42
わかりやすい説明だと思うが、どこがピンと来ないのかね?

119:デフォルトの名無しさん
07/06/20 08:25:12
すいません、自分が数列の和の公式を理解してませんでした。
中学校に入ってやり直してきます。

120:デフォルトの名無しさん
07/06/20 12:33:00
中学からやり直しても得られるものは何もないぞ

121:デフォルトの名無しさん
07/06/20 21:20:05
>>120
自分の周りの過半数は女子だ。
それだけでもやり直す価値はあるぞ。

122:デフォルトの名無しさん
07/06/21 23:45:04
変な流れぶったぎってちょっとしたまとめ。

(let ((buf (make-string (file-length in))))
(read-sequence buf in)
...
デカい文字列をメモリ上に作って処理すれば、
acl の正規表現は perlに全然負けてないです。shiroさん疑って
ごめんなさい。regexp2(・∀・)イイ!!
きっとperlも一行ずつ処理しているように見せて、
裏でいろいろやってるんですね。perlなめてました。

でも、コマンドラインのwc -lより速い行数計算CLプログラムは、
作れませんでした。単純な処理だとやっぱりCには勝てないのでしょうか…。


123:デフォルトの名無しさん
07/06/22 00:45:22
勝つ必要があるの?どうせ不毛な議論になるからやめよう。

用途によって言語は使い分ける、以上。

124:デフォルトの名無しさん
07/06/22 11:21:48
Perl は昔から文字列の処理に強かったからなぁ。
CGI の言語として普及したのも文字列処理の強さのお陰。
HTML を処理するには簡単に文字列処理が出来なきゃならんし。

それにスクリプト言語の中でも Perl は割と処理速度に力入れてる方だし。

125:デフォルトの名無しさん
07/06/22 11:42:38
Perl より高速なスクリプト言語ってあるの?

126:デフォルトの名無しさん
07/06/22 12:12:03
あるよ

127:デフォルトの名無しさん
07/06/22 14:05:42
それはC#とゆうものです.............

128:デフォルトの名無しさん
07/06/26 06:36:43
reverseと同じ作用をする関数をreverseを使わずに作りたいのですが

(defun my-reverse (l)
(cond ((atom l) l)
(t (cons '()(list (my-reverse (cdr l)) (car l))))))

とやると

> (my-reverse '(a b (c d)))
(NIL (NIL (NIL NIL (C D)) B) A)

となってしまいます。
どうすればよいのでしょうか?
ちなみにLISPは本当に素人です…


129:デフォルトの名無しさん
07/06/26 08:55:00
>>128
>>117

130:デフォルトの名無しさん
07/06/26 11:14:17
>>129
盲点でした…
ありがとうございます

131:デフォルトの名無しさん
07/06/28 23:38:30
occurと言う関数がtreeの中にitemが含まれる時Tを返すとすると、
(defun occur (item tree)
(if (atom tree)(eql item tree)
(if (occur item (first tree))t
(occur item (rest tree)))))
となるわけなんですが、
(eql item tree)が最終的にtを返すのであって
(occur item (first tree))でtが評価される事は無いですよねぇ。
ifが有るから便宜上tと有るだけですよねぇ?


132:デフォルトの名無しさん
07/06/29 00:11:34
まず落ちつけ。聞きたいことがよくわからん。
(eql item tree) が T を返すと (if (occur item (first tree)) T ...) の T が返るから
最終的に if の T が返ることもあるだろう。

133:デフォルトの名無しさん
07/06/29 00:36:27
ああ、分かった!
treeが分解されていって、
最終的に(eql item tree)でTが出て評価が終わり思ってたけれど、
再帰って数字だけじゃなくて、
深く降りて行ってTが返ってきてもTを返すんだ。
(語彙が少ないから適切に説明できない)

134:デフォルトの名無しさん
07/06/29 00:40:59
2番目のifを
(or (occur item (first tree)) (occur item (rest tree)))
にするとわかりやすいかな

135:デフォルトの名無しさん
07/06/29 01:03:20
例えば
>(setq a'(99 88 77 66 55))
となっていて
>(printlist a)
とすると
>( (1 99) (2 88) (3 77) (4 66) (5 55) )
と返すようにしたいんですが、うまくいきません。
どうすればいいでしょうか?
やっぱり再帰を使うんですよね?

136:135
07/06/29 01:14:13
すいません、自分では
(defun printlist(s n)
(cond ((equal n 1) s)
(t (cons n (printlist (car s)(- n 1))))))

と作ってみたんですが、
> (printlist a 5)
とやってみると、エラーで99はリストではないと怒られてしまいます。

137:デフォルトの名無しさん
07/06/29 01:19:53
こんなもんかな
(defun printlist (s &optional (n 1))
 (if s (cons (list n (car s)) (printlist (cdr s) (1+ n)))))

138:135
07/06/29 02:13:03
>>137
おお!
ありがとうございます!!

139:デフォルトの名無しさん
07/06/29 03:33:07
やっぱり再帰って Scheme のほうが向いてるんじゃないか。
反復を表現するためのドメイン特化言語 (DSL) LOOP を恐れずに使う。

CL-USER> (loop for e in '(99 88 77 66 55)
for i from 0
collect (list i e))
((1 99) (2 88) (3 77) (4 66) (5 55))


140:デフォルトの名無しさん
07/06/29 06:07:05
両方使えるのがCLの良い所。

141:デフォルトの名無しさん
07/06/29 15:29:42
doよりもloopの方を使うことが多い?

142:デフォルトの名無しさん
07/06/29 16:26:34
(defun color (fruit)
(case fruit
(apple 'red)
((banana lemon) 'yellow)
(peach 'pink)
(t "I don't know")))
と言う果物の名前を引数にとってその色を返す関数で、
(t "I don't know")の所でtが有るのはLispではNIL以外は何でも真だからですか?

143:デフォルトの名無しさん
07/06/29 18:43:22
>>141
個人的には loop は単純な無限ループ以外では使わない。知識がCLtL1で止まってるもんで。w

144:142
07/06/30 02:55:29
すいません。
本当は
(defun color (fruit)
(case fruit
(apple 'red)
((banana lemon) 'yellow)
(peach 'pink)
(otherwise "I don't know")))
なんでしょうけれども、
最後の一行を
(t "I don't know")))にしてもOKだと説明してあって、
どうしてなのかな?と自分なりに考えた結論だったのですが、間違ってました?

145:デフォルトの名無しさん
07/06/30 05:14:03
URLリンク(www.lisp.org)
ここを見る限りtとotherwiseを特別扱いしてるだけな気がする。

146:デフォルトの名無しさん
07/06/30 12:14:54
>>141
do と loop は微妙に住み分けている。基本は do なんちゃら~だけど、
以下の場合は loop を使う。とうか do より楽ができるパターンに使う。
A. collect を使いたいとき : DO だと push していって reverse だけど、このパターン用の DSL がこれ
B. ((x 1) (x 2)) みたいなパターンを for (id num) in ((x 1) (x 2) みたいな
C.

147:デフォルトの名無しさん
07/06/30 12:16:44
あ、途中でおくっちゃった。 C. 以降は気分つーことで。

148:142
07/06/30 12:49:08
>>145
特に意味はないのかなぁ。
本スレでも聞いてみますね。

149:デフォルトの名無しさん
07/06/30 23:53:48
ファイル関係で解らないことがあります。
Lispworksではfile-directory-pをつかって渡したPATHがディレクトリかファイルか区別がつくようなのですが
sbclやclispではファイルとディレクトリの区別を付ける方法がわかりません。
HyperSpecを渡り歩いたのですがこのあたりの記述をさがせませんでした。

ファイルシステム関係は言語実装と別な領域の話で仕様は無いよと言うことになってしまうのでしょうか?


150:デフォルトの名無しさん
07/07/01 01:38:22
まぁ、 Lisp は「ディレクトリ」って概念がないフィアルシステム上でも動いてきたからね…。
ファイルやディレクトリを扱うには Edi Weitz 氏の CL-FAD (File And Directory) が今は標準的。
元は Peter Seibel が Practical Common Lisp 書くときに用意したやつで、Edi 氏がパッケージにして公開してくれる。
で、件の処理はパッケージ内で以下のように定義されてる。pathname-name と pathname-type が無いものがディレクトリであると。
これで不自由はしてないよ。

(defun component-present-p (value)
"Helper function for DIRECTORY-PATHNAME-P which checks whether VALUE
is neither NIL nor the keyword :UNSPECIFIC."
(and value (not (eql value :unspecific))))

(defun directory-pathname-p (pathspec)
"Returns NIL if PATHSPEC \(a pathname designator) does not designate
a directory, PATHSPEC otherwise. It is irrelevant whether file or
directory designated by PATHSPEC does actually exist."
(and
(not (component-present-p (pathname-name pathspec)))
(not (component-present-p (pathname-type pathspec)))
pathspec))

ロード方法: SBCL なら cl-fad.tar.gz をダウンロードして展開後、
CL-USER> (load "cl-fad.asd")
CL-USER> (asdf:oos 'asdf:load-op :cl-fad)
CLISP なら ASDF も別途インストールしてくれ。

151:デフォルトの名無しさん
07/07/01 01:40:31
フィアルシステムって何だよ。ファイルシステムです。ごめん。

152:デフォルトの名無しさん
07/07/01 06:14:20
>>150
おはようございます、教わった関数とdirectory関数をつかってパスがディレクトリかどうか判定できるようになりました。
ありがとう。



153:デフォルトの名無しさん
07/07/01 07:34:09
>>150
>>Lisp は「ディレクトリ」って概念がないファイルシステム

って、どんな感じなんでしょう?

全部、ひとつのディレクトリの中に収まっているようなイメージなんでしょうか?
ぜひ、教えてください。

154:デフォルトの名無しさん
07/07/01 15:50:59
>>153
そう。一階層しかない。
Common Lispが制定された頃(20年以上前)はそういうOS(たとえばCP/M)が生き残っていたのじゃよ。

155:デフォルトの名無しさん
07/07/01 15:55:51
だれか政治力のある人に CLtL3 を提案してほしい。GLSはもう興味無いのかな。

156:デフォルトの名無しさん
07/07/01 18:05:02
>>155
何か案があるなら提案すりゃいいんじゃね。各ベンダとも独自の拡張を施してるわけだし。
で、なんで共通部分である ANSI CL の部分を変更したいんだ?
処理系の対応なんかでかなりのコストがかかるけど。

157:デフォルトの名無しさん
07/07/01 18:15:37
>>156
そりゃ独自に似たような拡張やってるなら共通部分に入れたほうが良いでしょ。
コスト掛かるって意味がわからんけど、標準になればみんな対応するでしょ。

158:デフォルトの名無しさん
07/07/01 18:48:41
よくわからん。何を標準化してほしいんだ?ただ改訂したい改訂したいといわれても…

159:デフォルトの名無しさん
07/07/01 18:50:48
憲法論議みたいだな

160:デフォルトの名無しさん
07/07/01 18:53:58
>>158
例えばちょっと上で出たディレクトリの話とか、多少時代遅れになってる部分はあると思う。
Unicodeの扱いなんかもベンダ独自でやってるけど、共通化すると便利ではないか?

161:デフォルトの名無しさん
07/07/01 19:05:35
あーそりゃ便利だと思うけどね。その程度では規格制定のコストを払ってくれるところはないと思うよ…
Unicode 周りというか国際化対応にかんしてもまだ課題は多くて The Right Thing は見えないしね。
CLRFI URLリンク(clrfi.alu.org) でどかんとブチ挙げるとか、ライブラリ書いて cliki あたりで公開してデファクト
目指すか、 CL-FAD みたいな事実上標準的なライブラリで我慢するか。

> コスト掛かるって意味がわからんけど、標準になればみんな対応するでしょ。
結構軽く考えてるな。まず R6RS の推移と主要処理系が対応するまでの過程を見てみると参考になると思う。


162:デフォルトの名無しさん
07/07/01 19:12:44
>>161
まあ軽く考えてると言われればそうかもしれん。せめて R6RS みたいな話が Common Lisp にも
出てこないかな、という無責任な希望程度の話。議論するつもりは無いので、このくらいで。

163:デフォルトの名無しさん
07/07/01 21:04:30
URLリンク(karetta.jp)
これをCLで素朴にやってみたんですけど誰か添削してくれませんか。

(defvar *capacity* nil) ; int list
(defvar *goal-p* nil) ; int list -> bool

(defun room-of (n state) (- (nth n *capacity*) (nth n state)))
(defun lset (l n v) (cond ((= n 0) (cons (+ (first l) v) (rest l)))
                           (t (cons (first l) (lset (rest l) (- n 1) v)))))

; int list -> (int . int) -> int list
(defun move (state pair)
  (let* ((from (first pair))
        (to (rest pair))
        (m (min (room-of to state) (nth from state))))
    (lset (lset state from (- m)) to m)))

; int list -> (int . int) list
(defun all-moves (l)
  (remove-if #'(lambda (pair) (= (first pair) (rest pair)))
      (mapcan #'(lambda (x)
                (mapcar #'(lambda (y) (cons x y))
                        l))
              l)))
;続く

164:デフォルトの名無しさん
07/07/01 21:05:18
;続き
; int list -> int list list
(defun successors (state)
  (mapcar #'(lambda (x) (move state x)) (all-moves '(0 1 2))))

(defun solve-abura (a b c)
  (let* ((*capacity* (list a b c))
         (target-amount (/ a 2))
         (*goal-p* #'(lambda (state) (= (count target-amount state) 2)))
         (start (list a 0 0)))
    (abura (list start))))

(defun abura (goal-stack)
  (let ((state (first goal-stack)))
    (cond
      ((funcall *goal-p* state) (reverse goal-stack))
      ((member state (rest goal-stack) :test #'equal) nil)
      ((some #'(lambda (amt cap) (> amt cap)) state *capacity*) nil)
      (t (reduce
           #'(lambda (result new-goal-stack) (or result (abura new-goal-stack)))
           (mapcar #'(lambda (s) (cons s goal-stack)) (successors state))
           :initial-value nil)))))

;(trace abura)
(print (solve-abura 10 7 3))

165:153
07/07/01 22:32:38
>>154
レス、どうもです。

ファイル操作に関連する苛立たしさ、
(cltl2の本、アンナに分厚いのに)
change directoryが無いとかは、
そういうことに起因してたんですか。

私が使っているlispのアプリの作者さんが、cd等の関数を、
処理系毎にaliasっぽく簡単な書き換えをしているのを見て、
なんでこんな基本的な関数も用意してくれないのかと思っていたのです。

「directoryの概念の無いファイルシステム」
とか言われちゃうと、仕方がないとも思えるけど、
ansi cl化する時、足してほしかったな。

166:デフォルトの名無しさん
07/07/01 23:16:49
当時、UNIX ベースのシステムが主流になるとは保証できなかったからしょうがない。
大抵の言語ではファイルシステム関連の機能は規格というよりライブラリの領分だしね。

個人的には pathname は夢の残骸みたいな感があるね。構成要素は↓だけど、
pathname-device, pathname-directory, pathname-host, pathname-name, pathname-type, pathname-version
UNIX だと directory, name のみだよね(拡張子を type とみるかもしれない)。 Windows だと device, directory, name, type か。
当時の Lisp Machine はネットワークを備えていたから host なんてのがあるし、version なんてのも面白いよね。
バージョニングを備えていたファイルシステムが当時あったのかな?

167:デフォルトの名無しさん
07/07/01 23:29:14
> バージョニングを備えていたファイルシステムが当時あったのかな?

VMS とかかな。

168:デフォルトの名無しさん
07/07/02 00:12:02
TOPSにもあった気がする

169:デフォルトの名無しさん
07/07/02 21:53:37
CommonLispでの外部ライブラリの使い方等について質問です。
htmlgenというライブラリをaptでインストールしましたが、このあと
どうやってそれを使えばいいのかが分かりません。

require? load?

ここらへんの知識が全くないのですが、
どこかに情報まとまっていたりしますか?

とりあえずaptでいっしょにインストールされたtest.clを読み込めるところまで
いきたいのですが・・・

170:デフォルトの名無しさん
07/07/02 23:07:16
apt とか Debian いわれてもわからん。SBCL か?
(asdf:oos 'asdf:load-op :htmp-gen)
でコンパイル + ロード完了だ。だめなら、これの前に
(load "/path/to/somewhere/htmlgen.asd")
を実行しとくこと。

171:デフォルトの名無しさん
07/07/02 23:15:39
    ┌─10
 ┌─┼─20
 │  └─30
 │  ┌─40
─┼─┼─50
 │  └─60
 │  ┌─70
 └─┼─80
    └─90

を表す引数なしの関数tree定義して、

次に,car や cdr 等以外の何らかのコマンドや関数等を使って,tree から次のような要素を取り出すにはどうすればいいんですか?

> XXXXXX
10
> XXXXXX
20


172:デフォルトの名無しさん
07/07/03 00:41:36
>>169
ubuntuかdebianだと思うが /usr/share/doc/cl-htmlgenとかにドキュメントが入る
んで (asdf:oos 'asdf:load-op :htmlgen)か(require :htmlgen)で使えるよ。
share/docにあんまり記述が無い奴(たまにある)だったら:htmlgenの部分は/usr/share/common-lisp/systemの中に入れたとおぼしきパッケージのasdファイルがあるから
他のパッケージでワケワカメになったら探すと良いよ。


全然関係ないけど、windowsとlinuxどっちもslime+emacs+sbclでかなり幸せになれました。
で、windowsでアプリ書くのにlispbuilder使ってますが結構しんどいです。(windowのレイアウトだけはポトペタにしたいです)
windowレイヤーだけ別にポトペタして、sbclで作ったロジックと結びつけたりするような手段って無いでしょうか?
あるいは製品版のlispworksとかだとできるのでしょうか?(aclは再配布コストを負担できないので除外してます)



173:デフォルトの名無しさん
07/07/03 00:51:19
LispWorks の InterfaceBuilder か?一応ポトペタもどきだが、 CAPI ライブラリは宣言的なので手で書いたほうが楽だったりする。
GUI の速度がいらねーなら LTK でいいんじゃね。GTK 系でも Socket で通信する GUI があった気がする。
どんなアプリ作るの?

174:デフォルトの名無しさん
07/07/03 00:57:12
>>171
宿題なら宿題とかけよ…。なんで宿題ですって正直に言えない奴が多いんだ。
宿題じゃない風を装いたいならもうちょっと日本語をなんとかしろよ…
まぁ、どうせ答え丸写しで小言なんか聞きやしないんだろうけどよぉ

(defun tree () '((10 20 30) (40 50 60) (70 80 90)))

> (caar (tree)) もしくは (first (first (tree))) もしくは (nth 0 (nth 0 (tree)))
10
> (cadar (tree)) もしくは (first (rest (first (tree)))) もしくは (nth 1 (nth 0 (tree)))
20


175:デフォルトの名無しさん
07/07/03 00:59:46
>>174
おまえ、親切だなw

176:デフォルトの名無しさん
07/07/03 01:31:07
>>173
任意のファイル開いて諸元の一部を表示して、入力欄の数値を使って解析して
結果を別の名前のファイルでしまうっていうタイプのよくある奴です。
入力欄に日本語のコメントつっこんだらLTKが毎回落ちるので orz

ATOK使ってるせいかもしれないけど。 


177:デフォルトの名無しさん
07/07/03 01:46:55
>>176
lispuser.net のスクリーンショットでは LTK の日本語入力できていたようだけどなー。
文字コードの設定まちがってるとかない?日本語入れたいなら LispWorks も厳しいかもねぇ。
IME のインライン入力なんか対応してる気配ゼロです。





178:デフォルトの名無しさん
07/07/03 08:28:50
>>177
おはようございます。
ご指摘の通りエンコードでした、cp1250だからラテンになってました。
lispuser.netとかの記事とltk.lisp本体を参考にして次のようなフック組んだらなんとかなりました。
(defun wish-enable-japanese ()
  (let* (( s (ltk:wish-stream ltk:*wish*))
   ( i (two-way-stream-input-stream s))
   ( o (two-way-stream-output-stream s))
   ( n (make-two-way-stream
    (sb-sys:make-fd-stream
    (sb-sys:fd-stream-fd i)
    :input t :external-format *CURRENTENCODE*)
    (sb-sys:make-fd-stream
    (sb-sys:fd-stream-fd o)
    :output t :external-format *CURRENTENCODE*))))
    (setf (ltk:wish-stream ltk:*wish*) n)))

(pushnew 'wish-enable-japanese ltk:*init-wish-hook*)

set-external-formatとか(setf (external-format is))とかで処理できるかと思ったのですがデキマセンでした。
ここで小一時間ほど時間を食ってしまいました(仕事に遅れるかと思ったです@通勤電車)
#slimeからだとutf-8でlispファイルダブルクリックだとsjisなのもなんとかしたいなぁ。


Lispworksですがpersonal版はちゃんとime制御されていましたのでそんなに心配はしてないのですが、いかんせん今の円ドルレートだと送料込みで16万超えるのでショボーンって感じです。
allegroは絶対安全なんですが、事業所内分のランタイムライセンス出せません(w




179:デフォルトの名無しさん
07/07/03 08:43:45
うう、lispファイルダブルクリックだとエンコードが何になるのかわからないです > _ <
ltkの戻りはutf-8で食えばsbcl側で認識するんですが orz

コンパイル時のエンコードがどこかにあるのかな?



180:デフォルトの名無しさん
07/07/03 21:05:02
(setf sb-impl::*default-external-format* :cp932)
ググリまくって該当する解見つけました、


181:デフォルトの名無しさん
07/07/04 17:02:03
numberp とかの p は predicate の p ですか property の p ですか?
たぶんどっちもありかも知れませんが、
property の p だという記述を見つけて気になったもので。


182:デフォルトの名無しさん
07/07/04 17:05:39
predicateに決まってるじゃん。number propertyじゃ意味わからん。

183:デフォルトの名無しさん
07/07/04 17:12:21
>>182
URLリンク(nicosia.is.s.u-tokyo.ac.jp)

184:デフォルトの名無しさん
07/07/04 17:20:29
>>183
単なる間違いだと思うが

185:デフォルトの名無しさん
07/07/04 17:32:59
>>183
たんなるミスでしたか。predicate だと思ってたので、あれ?って感じで。
(数値の性質 obj) でも通じるかなぁと。


186:デフォルトの名無しさん
07/07/04 22:52:18
どんだけ肩書き補正かかってんだよ。 predicate ったら predicate ~
匿名の言う事よりも肩書を信じたいなら、GLS も predicate の略だといっている、と覚えよう。

187:デフォルトの名無しさん
07/07/04 23:54:50
俺の本にも述語(predicate)って書いてあるよ。

188:デフォルトの名無しさん
07/07/07 12:19:17
>>163-164
ちょっと効率よくしてみた

(defun solve-abura (a b c)
  (let* ((*capacity* (list a b c))
         (target-amount (/ a 2))
         (*goal-p* #'(lambda (state) (= (count target-amount state) 2)))
         (start (list a 0 0)))
    (catch 'solved (abura (list start)))))

(defun abura (goal-stack)
  (let ((state (first goal-stack)))
    (cond
     ((funcall *goal-p* state) (throw 'solved (reverse goal-stack)))
     ((member state (rest goal-stack) :test #'equal) nil)
     ((some #'(lambda (amt cap) (> amt cap)) state *capacity*) nil)
     (t (dolist (s (successors state))
          (abura (cons s goal-stack)))))))

違うのは catch, throw を使うようにしたところ。
これで abura の再帰呼び出し部分の reduce, mapcar がなくなった。

あとは lset も copy-seq と破壊的操作にすると少しだけ空間効率がよくなるみたい。

189:デフォルトの名無しさん
07/07/07 16:15:51
質問です。
対話によるCommon Lisp入門 栗原正仁 著
p103で
(defun to (b) (< (random 1.0) b))
という関数toが出てくるのですが、
これが副作用を持つと書いてあります。
どこに副作用が有るのでしょうか?


190:デフォルトの名無しさん
07/07/07 16:17:29
>>189
random

191:デフォルトの名無しさん
07/07/07 22:39:11
え、randomって副作用なんですか?
副作用ってsetfで変数に値を代入したり、
defunで関数が使えるようになる事じゃないんですか?

192:デフォルトの名無しさん
07/07/07 22:46:39
randomは疑似乱数列を返す。つまり、どういう順序でどういう数値が返るのか
あらかじめ決定している。従って、randomを呼ぶか呼ばないかによって、次の
randomで返る値は変化する。これを副作用と呼ばずして何を副作用と呼ぶ?

193:デフォルトの名無しさん
07/07/07 22:56:50
ははぁ、成る程!
分かりました!

194:デフォルトの名無しさん
07/07/07 22:57:19
引数が同じなら何度呼んでも結果が変わらないのが副作用のない関数だよ。
したがって random には副作用がある。


195:デフォルトの名無しさん
07/07/07 23:02:23
こんなに詳しく解説していただいて感動です。
精進します。

196:169
07/07/07 23:29:11
>>170, 172
返答どうもです。とりあえず、(asdf:oos 'asdf:load-op :htmlgen)もしくは(require :htmlgen)
で、何やらいろいろ読み込んでいるメッセージがでます。そのあと、サンプルファイルtest.clをloadしたいのだけど、
失敗します。test.clはファイルの先頭行で

(defpackage :user (:use :htmlgen))をしているのだけど、(load "test.cl")したときに、

----ここから
debugger invoked on a SB-KERNEL:SIMPLE-PACKAGE-ERROR:
The name "HTMLGEN" does not designate any package.

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.

(SB-INT:%FIND-PACKAGE-OR-LOSE "HTMLGEN")
----ここまで

というエラーがでます。"HTMLGEN"というパッケージは存在しないという
内容のように見えますが、これはつまり最初の読み込みがうまく行ってないということでしょうか?

197:169
07/07/07 23:30:13
>>196の続き

htmlgen.asdファイルは以下のようになってます。

----ここから
kengo@Somali:/usr/share/common-lisp/source/htmlgen$ view htmlgen.asd

;;; -*- mode: lisp -*-
(defpackage #:htmlgen-system
(:use #:cl #:asdf))
(in-package #:htmlgen-system)

(defclass acl-file (cl-source-file) ())
(defmethod source-file-type ((c acl-file) (s module)) "cl")

(defsystem htmlgen
:author "John K. Foderaro"
:licence "LLGPL"
:default-component-class acl-file
:components ((:file "htmlgen"))
:depends-on (acl-compat)
:perform (load-op :after (op htmlgen)
(pushnew :htmlgen cl:*features*)))
----ここまで

まずasdfについて勉強しないと駄目なのかな・・・さっぱりわからん。。

198:デフォルトの名無しさん
07/07/07 23:38:24
>>194
> 引数が同じなら何度呼んでも結果が変わらないのが副作用のない関数だよ。

ちょっと語弊があるんじゃないか?

結果って書くと普通は戻り値と解釈されることが多いが、戻り値が一定でも
副作用のある関数を書くことはできる。

逆に現在時刻を返す関数等は副作用があるとは言わないと思うし。

199:デフォルトの名無しさん
07/07/07 23:47:54
横レスだけど、

>逆に現在時刻を返す関数等は副作用があるとは言わないと思うし。

全く同じ引数を渡したのに毎回異なる結果(現在時刻)を返すのであれば、
参照透明が崩されるので副作用があると思います。
現在時刻に合わせて変動する環境へのポインタみたいなのを引数に渡す
様になっていればその限りでは無いと思いますが。

200:デフォルトの名無しさん
07/07/08 00:36:21
>>196
ubuntuのだとhtmlgenのパッケージ宣言がnet.html.generatorになっていてtest.clと異なるからダメポみたいだね。
取り合えずこうやって呼び出しパッケージ変更すると先にはいけます
(require :htmlgen)
(defun simple-table-a ()
(with-open-file (p "test.html"
:direction :output
:if-exists :supersede)
(net.html.generator:html-stream p ;;net.html.generator:パッケージを指定
(:html
(:head (:title "Test Table"))
(:body (:table
(:tr (:td "0") (:td "0"))
(:tr (:td "1") (:td "1"))
(:tr (:td "2") (:td "4"))
(:tr (:td "3") (:td "9"))
(:tr (:td "4") (:td "16"))
(:tr (:td "5") (:td "25"))))))))


でもこれよりhtml-templateの方が使いやすい気がするんだけどそれじゃいやなのかな?

#実はcgiでlisp使おうとしてるんで学習がてらです。
#ちっともlisp自体には詳しくないです。


201:200
07/07/08 00:37:43
うぐ、コードはtest.clの物です、インデントは脳内で補間してください


202:デフォルトの名無しさん
07/07/08 00:42:57
副作用という単語の定義の問題だと思う。個人的には時間取得関数を「副作用がある」と言う
のには抵抗を感じる。便宜的に「副作用がある」と宣言して、ある種の最適化を抑止しなければ
ならないケース(言語)は多いと思うけど。

上記の乱数の例についても、もし予測不能な「真の乱数」(物理乱数)を返す関数だったらどう
だろう、とか考えてしまった。(混乱させてしまったらごめんなさい)

203:デフォルトの名無しさん
07/07/08 01:07:57
>>202
(setf a (f x))

こう書いたときにaが常に一意に決まる関数は副作用が無い。

aの結果が変わることを無視すれば副作用は無いように
見えるかもしれないけど
副作用の無い関数を組み合せた結果
副作用のある関数が作りうるのは副作用が無いといえないのではないか?

と、この観点では真の乱数は副作用があって、
疑似乱数で必ず種を受けとらないと動作しないものは副作用の無い関数として
扱ってよいと考える。

オプショナルで省略されたデフォルトグローバルな種を書き換えるかどうかは
この場合あまり重要ではない。

参照透明性とか言っている人はこういう風に考えているんじゃないかなと思った。

違ったらスマヌ

204:デフォルトの名無しさん
07/07/08 01:10:26
>>196

> (defpackage :user (:use :htmlgen))をしているのだけど、(load "test.cl")したときに、
(defpackage :user (:use :cl :net.html.generator))
とすればいいよ。asd の定義は Makefile のプロジェクト名とターゲット指定相当なんで
実際の CL におけるパッケージ名とは別。パッケージ名は net.html.generator 。
というかそのパッケージにはドキュメントついてこないのか。ヒドいなぁ…

205:デフォルトの名無しさん
07/07/08 01:11:21
思考実験をする前に、脳内定義を外界と摺り合わせしておくのも悪くない事だと思う
サンプルとして、純粋関数型言語オタクの言う副作用はこんな感じ

URLリンク(www.sampou.org)

206:デフォルトの名無しさん
07/07/08 01:54:47
wikipediaの副作用の項にある
1. 同じ条件を与えれば必ず同じ結果が得られる
2. 他のいかなる機能の結果にも影響を与えない
が良く分からん。
1は当然として(パソコンの時間が狂ってたらアレだけれど)、
2はどういう意味なんだ?
上の例だと時間取得関数は、その戻り値(時間)を使用した
関数の結果には影響を与えるから副作用を持つ?

207:デフォルトの名無しさん
07/07/08 02:16:33
>>206
2. は(上記疑似乱数の例のように)その関数を呼び出すことによって、その後に呼び出す関数の
動作が変化しないという意味じゃないかな。例えば上の疑似乱数の例は呼び出すことによって乱数
の系列がずれてしまうので副作用がある。
(正直、君の言っている意味のほうが理解できない)

208:デフォルトの名無しさん
07/07/08 02:20:03
その関数呼び出しによってほかの場所に影響をあたえる、ってのが副作用じゃない?
random を一回呼び出すと次の random 呼び出しに影響を与えるけど、
時刻取得関数を呼び出しても次の時刻取得関数には影響をあたえない。
戻り値は『ほかの場所』じゃないから気にしなくていいんじゃないかな。

って書いてたら >>206に先を越された。

209:デフォルトの名無しさん
07/07/08 02:20:40
>>206 じゃなくて >>207

210:デフォルトの名無しさん
07/07/08 02:28:09
>>206
ぶっちゃけ状態を扱う関数はみんな副作用がある関数と言える
1.が状態を取り出す
2.が状態を書き換える

副作用というと書き換えるほうをイメージしちゃって>>202みたいに思っちゃう人が多い

211:デフォルトの名無しさん
07/07/08 02:31:14
>>199
全く同じ引数を渡した時に同じ結果を返す(いわゆる「純関数」である)というのは副作用とは別の概念じゃないかな。
例えばグローバル変数の値を返すという関数は「純関数」ではないが「副作用がある」とは一般には言わないと思う。
時間を返す関数もこれと同じだよね。

もちろん、副作用のある関数は(たとえ同じ引数に同じ結果を返しても)「純関数」とは呼ばないだろうけど。

212:デフォルトの名無しさん
07/07/08 02:33:05
>>210
ああ「取り出すほうも副作用と呼ぶ」のか。議論がかみ合わない理由がわかった。
日本語的には激しく抵抗があるが、そういう定義は一般的なの?

213:デフォルトの名無しさん
07/07/08 02:42:11
関数型言語屋はそういう定義を使うことが多いね(偏見かな)

214:デフォルトの名無しさん
07/07/08 04:52:39
>>212
日本語的にとかいい出すなら、参照透明でないものを関数と呼ぶ方が抵抗あるだろ……。

215:デフォルトの名無しさん
07/07/08 05:51:37
Lispってこんなこともできねーの?

216:デフォルトの名無しさん
07/07/08 09:07:59
>>214
副作用って一般的にも使うし、そもそも「作用」の一般的な意味が

| (1)他に力や影響を及ぼすこと。また、そのはたらき。
| 三省堂提供「大辞林 第二版」

だから、「取り出すほうも副作用と呼ぶ」なんて言うのは違和感が
あるのはしょうがない。

対して、参照透明なんて普通の人はあまり使わんから、どんな定義
でも「はあそういう定義ね。」っで終わり。

専門用語と一般的に使われる言葉の意味が異なることは珍しくないよ。

217:デフォルトの名無しさん
07/07/08 09:33:01
いや、>>214が問題にしてるのは「参照透明」じゃなくて「関数」の方だと思う。
普通は関数っていったら数学の関数を想像するだろ?

218:デフォルトの名無しさん
07/07/08 10:23:20
参照透明の定義をよく知らない人にとっては、「参照透明でないものを関数と呼ぶな」
って言われたら、「ふ~ん、そうなんだ。」って思うだけで別に違和感を感じる余地
はあまりない。

「普通は関数っていったら数学的な関数を想像するだろ」とか書いてるけど、関数と
言う言葉のイメージって結構ばらばらなのはこの板の連中なら知ってて当然だから、
このスレではそういう(=「参照透明でないものは~」と言う) 定義なんだと理解でき
るだろうと思う。

219:デフォルトの名無しさん
07/07/08 10:35:44
>>218
参照透明という言葉を知ってるかどうかは関係ない。
printfみたいなのを関数と呼ぶ時点で慣れない人(非プログラマとか)には違和感があるだろ。
「副作用」という言葉が慣れない人にとって違和感のある意味で使われているのも、
「関数」という言葉の場合と同じ構造だ、って主張だと思うが。

220:デフォルトの名無しさん
07/07/08 12:53:05
副作用のあるものも含めて「関数」と呼ぶのはソフトウェア業界全体に普及している表現だが、
「副作用が無い」を「参照透明」の意味で使うのはそれほど一般的ではないと思う。

221:デフォルトの名無しさん
07/07/08 15:12:09
副作用の有無と参照透明性の有無は別々の話。関係はあるけど。
俺は「副作用」が>>210の意味で使われるのって普通じゃないと思うんだけど
そういう意味で使われている文脈って例えばどういうの?

222:デフォルトの名無しさん
07/07/08 15:19:05
>>221
>>213

223:デフォルトの名無しさん
07/07/08 15:58:07
gccのinfo、関数のattributeの説明から

> `const'
> Many functions do not examine any values except their arguments,
> and have no effects except the return value. (中略)
>
> The attribute `const' is not implemented in GCC versions earlier
> than 2.5. An alternative way to declare that a function has no
> side effects, which works in the current version and in some (後略)

この "a function has no side effects" が意味するものは当然これ。

> Many functions do not examine any values except their arguments,
> and have no effects except the return value.

224:169
07/07/08 17:07:58
>>200,>>204

おーー。できました!
どうもありがとうございます。

net.html.generatorというのは、htmlgen.clの先頭で
defpackageしている名前のことですね。

html-templateっていうのもあるんですか。
何がメジャーとかぜんぜん知らないんで一番最初に見つけたhtmlgenで
とりあえずやってみました。他にもlmlとか言う名前のhtmlテンプレートも
あったような気がする。いろいろあってわからんです

225:デフォルトの名無しさん
07/07/09 00:31:09
>>222
具体的に例えばどれ?

226:デフォルトの名無しさん
07/07/09 00:40:56
ごめ223見てなかった。Thanks.


227:デフォルトの名無しさん
07/07/09 21:24:17
CLISPでのデバッグ方法を解説している日本のサイトはないでしょうか?

228:デフォルトの名無しさん
07/07/09 23:49:25
どんなバグなのかによるんじゃないかな。バグ入り関数の例とか示せる?

229:デフォルトの名無しさん
07/07/10 08:45:11
URLリンク(www.kmonos.net)
これの、Curry-Howard Isomorphismの項なんだけれど、
これをCLでやるにはどうすればいいんだろう。
(a かつ (aならばb)) ならば b

haskellで
Prelude> :t ¥x -> (snd x) (fst x)
¥x -> (snd x) (fst x) :: (a, a -> t) -> t
らしいんだが、CLならどう書けばよいのかHaskellに詳しくないからさっぱり。
そもそもHaskellの::に相当する構文が無いからCLには無理?


230:デフォルトの名無しさん
07/07/10 09:03:24
CL には直積型がないからね
cons で代用するとこうかな
(lambda (x) (funcall (cdr x) (car x)))

231:デフォルトの名無しさん
07/07/10 09:09:01
そのまま (defun hoge (x) (funcall (cdr x) (car x))
普通にカーリー・ハワード対応で調べればいいのに。



232:デフォルトの名無しさん
07/07/10 09:16:29
>>230
(lambda (x) (funcall (cdr x) (car x)))

:t ¥x -> (snd x) (fst x)
に対応しているのは分かるんだけれど、
このラムダ式が定義できる事が、証明した事になるのかな?

233:デフォルトの名無しさん
07/07/10 09:28:45
>>232
> このラムダ式が定義できる事が、証明した事になるのかな?
疑問点がいまいちわかんない。
直観主義命題論理の証明と Lisp の関数とが対応するかということなら、
少なくとも上に書いたような方法では対応させられないと思う。

234:デフォルトの名無しさん
07/07/10 09:34:14
いや、証明に対応する関数は書けるか。
関数を書いても対応する証明があるとは限らない。

例えばこういうのは、対応する証明が命題論理の範囲にはない。
(lambda (x) (funcall x x))

235:デフォルトの名無しさん
07/07/10 09:41:03
>>233
>直観主義命題論理の証明と Lisp の関数とが対応するかということなら、
>少なくとも上に書いたような方法では対応させられないと思う。
残念、無理なのか。
いや、カーリー・ハワード対応という言葉を今回初めて知って、
(Lispで数式証明のアプリケーションが有るのは知ってるけれど)
んで、(a かつ (aならばb)) ならば bを証明してみたいなぁと思った訳です。

236:デフォルトの名無しさん
07/07/10 13:47:03
>>235
(lambda (x) (funcall (cdr x) (car x)))
を満たすようなxの値が存在することが証明に対応、
つまりそんなxを一つ挙げればいい……んじゃなかったっけ? うろ憶え。

237:デフォルトの名無しさん
07/07/10 16:38:25
静的な型がないと駄目だな。
\x -> x xはHaskellでは型エラー。

238:デフォルトの名無しさん
07/07/10 22:14:43
(defun hoge (a b)
(if (and a (eql a b)) b
nil))
じゃ、ダメなのかな?
っーかこの分野って、やってる人少ないのかな?
あんまりレスないね。
ここの人、こんなこと好きそうなイメージなんだけれど。

239:デフォルトの名無しさん
07/07/11 00:51:45
Cで書いたプログラムとCLispで書いたプログラムを
互いに通信させたいんだけど,そういった場合ってやっぱSocket?
何かいいライブラリとかありませんかね

240:200
07/07/11 01:40:07
通信だとsocketですが、お互いのやり取りの中身が直接呼び出しだったり、共有メモリでなんとかできるのならCFFIあたりを使ってみてはどうですか?
OpenGLの呼び出しとかで使われてるやつです。


241:デフォルトの名無しさん
07/07/11 04:06:54
>>238
本スレ行ったほうがいいかもね。
その手の話はスキーマーのほうが乗ってくる。

242:デフォルトの名無しさん
07/07/11 09:27:13
>>238
λ計算は知ってるけど、Lisp とはそれほどきれいに対応しないと思う。
ちなみにそのコードは Curry-Howard とはぜんぜん関係ないような。

243:デフォルトの名無しさん
07/07/13 00:19:32
(format t "~X ~X~%" a b)とやって
#(69) 69
と表示されるんですが,同じ数値でも片方に#()がついてしまいます.
これってただの数値じゃないってことですか?
その成果,後々にa = #x69とやってもTになってくれません

aは
(let ((a (make-array 1 :element-type '(unsigned-byte 8)))))
とかやって
EXT:READ-BYTE-SEQUENCEとかで読み込んだ値なんですが...

244:デフォルトの名無しさん
07/07/13 00:24:36
>>243
ただの数値じゃないんですよ。配列ってわかります?

245:デフォルトの名無しさん
07/07/13 00:27:13
>>244
それだ!

246:デフォルトの名無しさん
07/07/13 21:41:29
Lispの練習問題を探していて

Define show-list to act like Lisp's PRINT, except that it should print
square brackets instead of parentheses. (Printing to a string and
replacing parentheses doesn't count.)

Both functions should be able to print any S-expression, including
atoms.

> (show-list '(a b c))
→ [A B C]

ってのを見つけました。

これを、"ANSI Common Lisp"の第3章までの知識で解きなさい、ってんですけ
ど、オジサンの頭ではどーにもなりません。

そのものズバリでなくても、ヒントとか考え方とか教えていただけないでしょ
うか?





247:デフォルトの名無しさん
07/07/13 22:14:08
SBCLでcompile-fileしてもあんまり速くならないんですが、
何か他に速くする手段てあるでしょうか?


248:デフォルトの名無しさん
07/07/13 22:39:40
>>246
1. 全てのS式を表示だからatomの場合、consの場合、nilの場合で場合わけすることになるはず。atomとnilは自明。
2. consの場合の表示を分解すると括弧の表示+最初の要素を表示(要素はさらにconsかもしれない)+残りの表示+括弧閉じになるはず。
3. この「残りの表示」を別関数で定義してみる。(←ここがポイント)
4.「残りの表示」の場合わけもさっきと同様になる。
5. ここでconsの場合の処理はやっぱり「最初の要素について(これもconsかもしれない)」「残りについて」になる。

249:デフォルトの名無しさん
07/07/13 22:42:50
説明下手糞?

250:デフォルトの名無しさん
07/07/13 22:48:00
ごめん、代わりに頼むよ

251:デフォルトの名無しさん
07/07/14 00:35:32
>>248
おぉ、早速ありがとうございます。
参考にしていろいろいじってみます。

日本語で読むと簡単そうに見えるんだけどなぁ。

(defun show-list (lst)
 (if (null lst)
  lst
   (if (atom lst)
    :

って感じでいいんですよね?





252:デフォルトの名無しさん
07/07/14 00:55:32
配列とか構造体とか () 使うのはほかにもあるけど
symbol と cons だけでいいのかな

>>251
>  (if (null lst)
>     lst
"nil" って文字列を印字しなきゃいけないんでないの?

253:246
07/07/14 09:21:45
>>252

あぅ。やっちまった orz
自分で言っといて...

(defun show-list (lst)
 (format t "~A" (rec-show-list lst)))

(defun rec-show-list (lst)
 if (null lst)
  lst
  :

なんてのを考え中。




254:デフォルトの名無しさん
07/07/14 10:16:14
>>247
sbclはコンパイラのみの処理系だから、ソースをロードしても実行時には
コンパイルされていると思う。だから差を感じられないということじゃないかな。

255:デフォルトの名無しさん
07/07/14 13:51:28
>>253
その設計は無理があると思う
だって format って () 使うじゃん

256:デフォルトの名無しさん
07/07/14 17:59:26
>>246
問題が「show-listを作れ」ってなってるのがミスリーディングかも。
任意の式を出力する関数show-exprを作れ、が普通じゃなかろうか。
ただしリストの表示にはパーレンの代わりにブラケットを用いる。

257:246
07/07/14 19:44:08
なんか盛り上がってるし(^^;)。

>>255
> だって format って () 使うじゃん
ごめんなさい。これ分かりません。
format使うと必ず()がつくってこと?

>>256
"ANSI Common Lisp"の3章の練習問題なので、そこまでの知識で解かないとい
けないのかな、と思ってます。
出力用の関数はformat、データ形式もリスト(とアトム)のことだけ考えればい
いのかと。


258:255
07/07/14 20:17:05
>>257
たとえば
(format t "~A" x)

[a b c]
が出力されるような x ってどんなもの?

ところでリストでもアトムでもないオブジェクトってあったっけ

259:デフォルトの名無しさん
07/07/14 23:18:09
んん?問題は良い問題なのになんか根本的に間違った方向にいってないか?

S-式は、リストと思わずに木(ツリー)と思った方がいい。
で、木の要素を順番に辿る。木の要素が atom か consp かで場合分け。
consp だったら、 まず [ を出力し、hogehoge の処理をして最後に ] を出力する。
任意の入れ子になった木を出力できないと行けないんだから、
hogehoge は言わなくても分かるな?


260:デフォルトの名無しさん
07/07/15 00:39:44
要するにwrite相当を実装しろってことでしょ?

(defun write-list(exp)
(princ "[")
(loop (if (not (consp exp)) (return))
(write (car exp))
(setq exp (cdr exp))
(if (consp exp) (princ " ")
(if (not (null exp))
(progn (princ " . ") (write exp)))))
(princ "]"))

(write-list '(a b c . d))
[A B C . D]
write本体は自分で考なよおじさん


ちなみに俺もCommonLisp初めてなんだけど、
whileって無いみたいね。
上の(loop (if (not (consp exp)) (return)) ~ )
てかなりマヌケな気がするんだけど、もっと簡単にできない?
whileがあれば(while (consp exp) ~)で済むのに

261:デフォルトの名無しさん
07/07/15 00:40:40
doがあるよ

262:デフォルトの名無しさん
07/07/15 00:44:46
これでしょ?
(defmacro while (condition &body body)
`(do () ((not ,condition)) ,@body))

でもdoはなんとなくキモイんだよな…

263:デフォルトの名無しさん
07/07/15 01:57:06
ループの話題で思い出したけど、
最新版のSBCLで以下のコードがn=5000程度で死ぬんですが、
末尾再帰の最適化はしてくれないんでしょうか?
(defun w(n)
(labels ((x (n) (write n) (if (> n 0) (y (- n 1)) ))
(y (n) (write n) (if (> n 0) (z (- n 1)) ))
(z (n) (write n) (if (> n 0) (x (- n 1)) )))
(x n)))
(w 5000) ;程度で死ぬ

schemeでは
(define (w n)
(letrec ((x (lambda (n) (write n) (if (> n 0) (y (- n 1)))))
(y (lambda (n) (write n) (if (> n 0) (z (- n 1)))))
(z (lambda (n) (write n) (if (> n 0) (x (- n 1))))))
(x n)))
(w 10000000000) ;nをいくら大きくしてもOK

264:デフォルトの名無しさん
07/07/15 02:46:34
>>258
3 章までとか言われてもよくわかんないけど、princ くらいはあるのかな?
考え方:
0. リストがわたってくる
1. [ を表示
2. 各要素を表示
2-1. 要素がもうないなら終わり
2-2. 要素を一個表示して 2. へ
3. ] を表示

(defun show-list (lst)
(princ "[") ; 1
(show-list-contents lst) ; 2
(princ "]")) ; 3

(defun show-list-contents (lst)
(cond ((null lst) ; 2-1
nil)
(t ; 2-2
(princ (car lst))
(show-list-contents (cdr lst)))))


265:264
07/07/15 02:48:28
264 のリスト内のリストも [] で表示するのは課題としときます。
ヒント: 要素がリストなのかアトムなのかを判定して…

>>260
while の内部実装が do でキモいというなら↓でどうでしょう。
(loop while (consp exp) do ....)
これも嫌なら素直に Scheme を使ったほうがいいと思います。

>>263
SBCL 1.0.7 で disassemble して末尾再帰の最適化もされている事を確認しました。
(w 10000000000) も普通に動いてるようですが。

266:デフォルトの名無しさん
07/07/15 03:24:34
>>263
ごめんWindows版だから1.0.6だった。
普通にインストーラで作成されるショートカットから起動して
>>263のコードをコピペ。
(w 10000)で

12840283928fatal error encountered in SBCL pid 2812:
GC invariant lost, file "gencgc.c", line 832

LDB monitor
ldb>
となって止まる。
今確認したら5000だとなんか完了したりもするので10000で。
6000辺りだとプロンプト'*'が連続表示して暴走した風になって、
タスクマネージャで見るとメモリをどんどん消費していくのが判る。
ほっとくとOS側(XP Pro. SP2)でメモリ不足のダイアログが出る。
Windows版特有なのかな・・?

267:デフォルトの名無しさん
07/07/15 03:25:23
ごめん上は>>265宛て

268:デフォルトの名無しさん
07/07/15 03:28:54
* (disassemble 'w)してみたけど、最適化掛かってるかわからないので
よければ鑑定お願いします。

; 0A626C8E: 8B45F0 MOV EAX, [EBP-16] ; no-arg-parsing e
ntry point
; C91: 8945F4 MOV [EBP-12], EAX
; C94: E9FB000000 JMP L14
; C99: L0: 8BDC MOV EBX, ESP
; C9B: 83EC0C SUB ESP, 12
; C9E: 8B55F4 MOV EDX, [EBP-12]
; CA1: 8B05586C620A MOV EAX, [#xA626C58] ; #<FDEFINITION object for WRITE>
; CA7: B904000000 MOV ECX, 4
; CAC: 896BFC MOV [EBX-4], EBP
; CAF: 8BEB MOV EBP, EBX
; CB1: FF5005 CALL DWORD PTR [EAX+5]
; CB4: 7302 JNB L1
; CB6: 8BE3 MOV ESP, EBX
; CB8: L1: 8B55F4 MOV EDX, [EBP-12]
; CBB: 31FF XOR EDI, EDI
; CBD: E84E979DF7 CALL #x2000410 ; GENERIC->


269:デフォルトの名無しさん
07/07/15 03:29:59
; CC2: 7302 JNB L2
; CC4: 8BE3 MOV ESP, EBX
; CC6: L2: 81FA0B001002 CMP EDX, 34603019
; CCC: 750F JNE L4
; CCE: BA0B001002 MOV EDX, 34603019
; CD3: L3: 8D65F8 LEA ESP, [EBP-8]
; CD6: F8 CLC
; CD7: 8B6DFC MOV EBP, [EBP-4]
; CDA: C20400 RET 4
; CDD: L4: 8B55F4 MOV EDX, [EBP-12]
; CE0: BF04000000 MOV EDI, 4
; CE5: E848959DF7 CALL #x2000232 ; GENERIC--
; CEA: 7302 JNB L5
; CEC: 8BE3 MOV ESP, EBX
; CEE: L5: 8955F4 MOV [EBP-12], EDX
; CF1: 8BDC MOV EBX, ESP
; CF3: 83EC0C SUB ESP, 12
; CF6: 8B55F4 MOV EDX, [EBP-12]
; CF9: 8B05586C620A MOV EAX, [#xA626C58] ; #<FDEFINITION object for WRITE>
; CFF: B904000000 MOV ECX, 4
; D04: 896BFC MOV [EBX-4], EBP
; D07: 8BEB MOV EBP, EBX
; D09: FF5005 CALL DWORD PTR [EAX+5]


270:デフォルトの名無しさん
07/07/15 03:31:13
; D0C: 7302 JNB L6
; D0E: 8BE3 MOV ESP, EBX
; D10: L6: 8B55F4 MOV EDX, [EBP-12]
; D13: 31FF XOR EDI, EDI
; D15: E8F6969DF7 CALL #x2000410 ; GENERIC->
; D1A: 7302 JNB L7
; D1C: 8BE3 MOV ESP, EBX
; D1E: L7: 81FA0B001002 CMP EDX, 34603019
; D24: 7507 JNE L8
; D26: BA0B001002 MOV EDX, 34603019
; D2B: EBA6 JMP L3
; D2D: L8: 8B55F4 MOV EDX, [EBP-12]
; D30: BF04000000 MOV EDI, 4
; D35: E8F8949DF7 CALL #x2000232 ; GENERIC--
; D3A: 7302 JNB L9
; D3C: 8BE3 MOV ESP, EBX
; D3E: L9: 8955F4 MOV [EBP-12], EDX
; D41: 8BDC MOV EBX, ESP
; D43: 83EC0C SUB ESP, 12
; D46: 8B55F4 MOV EDX, [EBP-12]
; D49: 8B05586C620A MOV EAX, [#xA626C58] ; #<FDEFINITION object for WRITE>
; D4F: B904000000 MOV ECX, 4
; D54: 896BFC MOV [EBX-4], EBP
; D57: 8BEB MOV EBP, EBX
; D59: FF5005 CALL DWORD PTR [EAX+5]


271:デフォルトの名無しさん
07/07/15 03:32:07
; D5C: 7302 JNB L10
; D5E: 8BE3 MOV ESP, EBX
; D60: L10: 8B55F4 MOV EDX, [EBP-12]
; D63: 31FF XOR EDI, EDI
; D65: E8A6969DF7 CALL #x2000410 ; GENERIC->
; D6A: 7302 JNB L11
; D6C: 8BE3 MOV ESP, EBX
; D6E: L11: 81FA0B001002 CMP EDX, 34603019
; D74: 750A JNE L12
; D76: BA0B001002 MOV EDX, 34603019
; D7B: E953FFFFFF JMP L3
; D80: L12: 8B55F4 MOV EDX, [EBP-12]
; D83: BF04000000 MOV EDI, 4
; D88: E8A5949DF7 CALL #x2000232 ; GENERIC--
; D8D: 7302 JNB L13
; D8F: 8BE3 MOV ESP, EBX
; D91: L13: 8955F4 MOV [EBP-12], EDX
; D94: L14: E900FFFFFF JMP L0
; D99: 90 NOP
; D9A: 90 NOP
; D9B: 90 NOP
; D9C: 90 NOP
; D9D: 90 NOP
; D9E: 90 NOP
; D9F: 90 NOP
; DA0: CC0A BREAK 10 ; error trap
; DA2: 02 BYTE #X02
; DA3: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR
; DA4: 4D BYTE #X4D ; ECX
;
NIL

272:265
07/07/15 04:08:49
>>266
あーそゆことか。コードはちゃんと最適化されてるが GC 回りのバグですね。
SBCL の Windows 版はまだ試験的なものなんで安定してないんだよ。
Windows な開発者も少ないしね。ごめんね SBCL にかわってごめんね

273:デフォルトの名無しさん
07/07/15 04:44:16
うーむ、GC周りのバグってことは、ちゃんとプロテクトされてない
ってことかな?結構いい加減ですね・・。

ちなみにclisp(clisp-2.41-win32-mingw-without-readline.zip)で
同じ様にcompileして実行しても、
*** - Program stack overflow. RESET
と出るんですけど、こっちは何とかなりませんかね。



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