【入門】Common Lisp その8【質問よろず】
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさん
2011/07/06(水) 17:15:15.55初心者のQ&A
本スレでは恥ずかしくて聞けない人のQ&A
本スレは高度すぎて割り込めない人のQ&A
linuxでなくてwindowsでやりたいんですが・・・Q&A
lispを使用してC#やJAVAの代替にするための方法(おまけ)
ま、ゆっくりたりましょう。
「いいものの本質は、いかなる時代においても変わらない」byパワーズ
(list
(url http://pc8.2ch.net/test/read.cgi/tech/1101386936/l50 :part 1)
(url http://pc11.2ch.net/test/read.so/tech/1140012484/l50 :part 2)
(url http://pc11.2ch.net/test/read.so/tech/1181479267/l50 :part 3)
(url http://pc11.2ch.net/test/read.cgi/tech/1201402366/l50 :part 4)
(url http://pc11.2ch.net/test/read.cgi/tech/1215834213/l50 :part 5)
(url http://pc12.2ch.net/test/read.cgi/tech/1234884136/l50 :part 6)
(url http://hibari.2ch.net/test/read.cgi/tech/1270370267/l50 :part 7)
□テンプレート置き場□
ttp://wiki.fdiary.net/lisp/ (id:guest pass:cl)
0809806
2012/01/29(日) 19:47:07.24言われてみれば確かに。
slimeで勉強中にこの式をたまたま評価したらいつの間にかメモリを食い潰してしまって焦ってしまいました。
で、こういう事態に備えてヒープサイズ?を制限しようかと思ったのですが、clozureでは可能なのでしょうか。
sbclなら--dynamic-space-sizeで指定したメモリ以上は使わないようにできました。
しかしclozureでは--heap-reserve 1Gと指定しても、topで見る限り128Gまでメモリ使用を許可しているようです。
当然そんなにメモリを積んでいないし、>>806のような馬鹿をすると1Gを超えてメモリを食い出しました。
0810デフォルトの名無しさん
2012/01/30(月) 01:20:22.90>>806がdisられてる件について。
--heap-reserve 8Mくらいで>>807試すと普通にメモリ不足ですぐ例外発生したりしない?
Windows XP SP3 32-bit + CCL 1.8-dev-r14962-trunkだとそんな感じだけども。
一応、CCLのヒープ関係はこういう仕組みになってるとのこと。
http://ccl.clozure.com/manual/chapter16.1.html#Heap-space-allocation
(cl:room)するとどうなってる?
0811デフォルトの名無しさん
2012/01/30(月) 05:34:46.271.23e19
理解できないのですが
どなたか説明お願いします。
0812デフォルトの名無しさん
2012/01/30(月) 05:39:05.440813デフォルトの名無しさん
2012/01/30(月) 07:05:19.170814807
2012/01/30(月) 08:34:25.72ccl64 --heap-reserve 4Mで(cl:room)としたとき、
pproximately 24,117,248 bytes of memory can be allocated
before the next full GC is triggered.
Total Size Free Used
Lisp Heap: 39190528 (38272K) 24117248 (23552K) 15073280 (14720K)
Stacks: 51246288 (50045K) 51211592 (50011K) 34696 (34K)
Static: 19070896 (18624K) 0 (0K) 19070896 (18624K)
-4071.375 MB reserved for heap expansion.
となります。OSはlinux(64bit)で、clozureはccl-1.7-linuxx86.tar.gzの中にあるccl64を動かしています(cclはエラーになる)。
(swank:start-server :port 4005 :stlye :spawn :dont-close t)でswankサーバを建ててslime-connectして使っています。
この状態で、>>807をC-c C-cとし、数秒後に(cl:room)を実行すると
Approximately 33,554,432 bytes of memory can be allocated
before the next full GC is triggered.
Total Size Free Used
Lisp Heap: 2548170752 (2488448K) 33554432 (32768K) 2514616320 (2455680K)
Stacks: 51246288 (50045K) 51210424 (50010K) 35864 (35K)
Static: 19070896 (18624K) 0 (0K) 19070896 (18624K)
-6464.125 MB reserved for heap expansion.
となります。
0815デフォルトの名無しさん
2012/01/30(月) 15:25:59.610816デフォルトの名無しさん
2012/01/30(月) 18:19:23.92Oh... 凄く…負の値です…。バグなのかなー。>>810の環境で普通に起動するとこう。
Approximately 7,864,320 bytes of memory can be allocated
before the next full GC is triggered.
Total Size Free Used
Lisp Heap: 20119552 (19648K) 7864320 (7680K) 12255232 (11968K)
Stacks: 31317648 (30584K) 31304808 (30571K) 12840 (13K)
Static: 20140352 (19668K) 0 (0K) 20140352 (19668K)
844.812 MB reserved for heap expansion.
予約された領域の表示は、ccl:%reservedbytesで領域の境界同士を引いて算出してる。
負の値になるってことは、多分境界の値がおかしなことになってるんだと思うんだけど。
http://trac.clozure.com/ccl/ticket/890
に、"This affects me."とか書きつつ、環境と(room)の結果でも貼ってみたらどうだろう。
http://blo.udoidio.info/2008/10/out-of-memory-sad-case.html
を見ると、少なくとも1.2の時点からある問題みたいだ。
0817デフォルトの名無しさん
2012/01/30(月) 18:49:29.05ラムダは関数だから違う。強いて言うならC++のテンプレートが近い。
用途は色々あるけど、総じて他の言語ならコンパイラの書き替えや別言語の実装が必要なレベルの抽象化が出来る。
0818デフォルトの名無しさん
2012/01/30(月) 19:01:05.30なるほど、C++のテンプレートにちかいのですね。
この考えを取っ掛かりとしてもう一度勉強してみます。
0819デフォルトの名無しさん
2012/01/30(月) 19:24:25.09強いて言えばだから、テンプレートの勉強をしてもあまり参考にならないと思うよ。
Lispマクロ自体を勉強する方が良いと思う。
Paul=Grahamやgaucheの作者の書いた物がお勧め。
0820デフォルトの名無しさん
2012/01/30(月) 21:57:34.69いっしょだと思う. template_expand と template_expand_1 さえあれば...
0821デフォルトの名無しさん
2012/01/31(火) 07:26:04.21条件分岐の面倒さや再帰の深さ制限とか、実行時型情報とかやはり違うと思う。Lispにはリーダマクロ等もある。
boostにもよりLispマクロを目指したmopがあるし、D言語もASTマクロを入れる予定。
ところで調べてて驚いたけど、Perl6にもASTマクロがあるらしい。現状で一番Lispに近い言語なのかも(笑)
0822デフォルトの名無しさん
2012/01/31(火) 20:38:23.980823デフォルトの名無しさん
2012/02/03(金) 17:32:20.27https://kuomarc.wordpress.com/2012/01/27/why-i-love-common-lisp-and-hate-java/
Why I love Common Lisp and hate Java, part II – code examples « Piece of mine
http://kuomarc.wordpress.com/2012/02/02/why-i-love-common-lisp-and-hate-java-part-ii-code-examples/
0824デフォルトの名無しさん
2012/02/03(金) 21:18:26.92Compare
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
with Common Lisp’s equivalent:
"Hello World"
0825デフォルトの名無しさん
2012/02/03(金) 22:41:28.18を思い出した。
0826デフォルトの名無しさん
2012/02/06(月) 00:30:57.46特に作るののもないのでリストいじってあそんでいる。
0827デフォルトの名無しさん
2012/02/06(月) 00:35:10.040828デフォルトの名無しさん
2012/02/06(月) 02:32:05.69(format t "hoge start~%")(catch 'c1 (format t "catch c1 start~%") (fuga x) (format t "catch c1 end~%"))
(format t "hoge end~%"))
(defun fuga (x)
(format t "fuga start~%") (if (= x 0)(throw 'c1 "x = 0")(format t "x /= 0~%"))
(format t "fuga end~%"))
で質問です。このlispの実行結果は、
(hoge 0)
hoge start
catch c1 start
fuga start
hoge end
nil
となるのですが、catch c1 start後に関数fugaのif文でtrueなので
(throw 'c1 "x = 0")
を実行すると思うんですが
(format t "catch c1 start~%")
(fuga x)
(format t "catch c1 end~%")
を実行せずにそのまま"hoge end"で終わっています。
(throw 'c1 "x = 0")の時いったい次どこの処理をするのでしょうか。
また、最後、throwの戻り値の"x = 0"も出力されず、nilとなっています。
"x = 0"が返されるときとはどういうときなのでしょうか。
動きがよくわからなくて困っています。
よろしくお願いします。
0829デフォルトの名無しさん
2012/02/06(月) 04:02:22.74なので、(throw 'c1 "x = 0")によって、catchの戻り値が"x = 0"になる。以降のformは評価されない。
catchの戻り値は、件のコードでは単に捨てられるようになっているので、出力もされない。
catchの後に「hoge end」を出力して、そのまま終了する。
つまり、throwの次に実行されるのは(format t "hoge end~%")。
http://www.lispworks.com/documentation/HyperSpec/Body/s_catch.htm
というか、普通はcatchやthrowを直接使ったりせず、より上位の仕組みのコンディションを使う。
0830デフォルトの名無しさん
2012/02/06(月) 10:05:55.45回答ありがとうございます。
throwでx=0の後は、関数fugaは評価されないんですね
また、catchというかhogeのcatchが終了したところに戻るんですね
戻り値は受け手はいるけど出力して終了とはならないということですか
なるほど。。。非常に難しいですね。。。
ありがとうございます。
0831デフォルトの名無しさん
2012/02/06(月) 10:16:38.352: (catch tag
3: (throw 'hack 'yes)))
4:catch2
5:
6:=> catch2
7:
8:(catch 'hack
9: (print (catch2 'hack))
10: 'no)
11:
12:yes
13:no
というプログラムでもやはりcatch,throwのことですがいいでしょうか
先ほどの回答ですと
まず8行めのcatchから、1,2行目にとんで3行目のthrowで
すでに8行目は行ってるので、8行目に飛ばずにそのままそのthrowは終了
でyesが返ってくる。
それが9行目のprint文にもどるのでyesを出力となるわけですね。
最後の'noはどうやって出力されたのでしょうか。
ここもやっぱりよく分からないのですが。。。
0832デフォルトの名無しさん
2012/02/06(月) 10:25:18.81は
(catch 'hack
(throw 'hack 'yes))
になる。
0833デフォルトの名無しさん
2012/02/06(月) 11:19:25.562: (print
3: (catch 'hack
4: (throw 'hack 'yes)))
5: 'no)
とすると
3行目のcatchから、throwで戻り値yesをprintして
残りは'noが残ると思うのですが
すると
結果は
yes
no
となるのですが、noは'noがただ評価されたから
出力されているという解釈でいいんでしょうか。
0834デフォルトの名無しさん
2012/02/06(月) 13:34:40.81がyesを表示してて、
(catch 'hack
(catch 'hack
(throw 'hack 'yes)))
'no)
を評価したときの戻り値がno。
インタプリタ上だと標準の出力先と戻り値を表示する先が同じものが多い。
0835デフォルトの名無しさん
2012/02/06(月) 14:40:06.47(list "test2" "foo34" "bar23" "test5" "foo67" "test9" "bar8" "foo7")
こうして作成したリストを
("test234" "bar23" "test567" "test9" "bar8" "foo7")
のように変換したいです
どういうことかというと、test〜の直後の要素がfoo〜だったら
test〜とfooより右側の文字列を結合させます
そうでなければその要素はそのままにしておきます
(mapcar #'(lambda (a b)
のように書きはじめるのかと思いましたが、この場合の a bは二つのリストからそれぞれ
要素を取り出すものなので違うようです
どうすればよいでしょうか
0836デフォルトの名無しさん
2012/02/06(月) 19:03:40.19reduceを使えば良いんじゃないかな。というわけで、こんなんできました。
ハードコーディングしてる部分は、実際のコードでは修正してー。
(labels ((has-prefix-p (prefix x)
(let ((p (search prefix x)))
(and p (zerop p))))
(foop (x)
(has-prefix-p "foo" x))
(testp (x)
(has-prefix-p "test" x)))
(reduce (lambda (x r)
(if r
(destructuring-bind (last . rest) r
(if (and (foop last) (testp x))
(cons (concatenate 'string x (subseq last (length "foo")))
rest)
(cons x r)))
(cons x r)))
*list*
:from-end t
:initial-value nil))
0837デフォルトの名無しさん
2012/02/06(月) 19:05:43.41(defparameter *list* (list "test2" "foo34" "bar23" "test5" "foo67" "test9" "bar8" "foo7"))
こんな感じで。コピペし忘れた。
0838デフォルトの名無しさん
2012/02/06(月) 19:52:31.82反応遅くなり申し訳ありません。
catch内の最後に評価された式が最後の返されるんですね
だから、yesのあとにprint文でもないのにnoが出力されるということですね
ありがとうございます!!
0839デフォルトの名無しさん
2012/02/06(月) 22:14:41.11http://clhs.lisp.se/Body/s_catch.htm
# 仕様書読め(Unix で言うところの read the fucking manual)
0840デフォルトの名無しさん
2012/02/06(月) 22:53:44.57ありがとうございます。
TOEIC200点代ですが頑張って解読します。
0841デフォルトの名無しさん
2012/02/06(月) 23:16:02.80新しい制御構造でも作るの? かなり斜め上なことをしてる予感がするけども。
0842デフォルトの名無しさん
2012/02/07(火) 00:20:38.90emacsのとあるプログラムをxyzzyのcommon lispに書き換えてみたくて
解読してたんですが、catchとthrowがでてきて・・・
調べてたら、更に分からなくなりまして。。。
なので、新しく何か作るわけではありません。
あまりcatchとthrowは一般的でないみたいですね。
0843デフォルトの名無しさん
2012/02/07(火) 00:24:46.17あと、ここで質問したcatch,throwのプログラムは
解説サイトに載っているものです。
理解できなかったので部分コピペで質問させていただきました。
0845デフォルトの名無しさん
2012/02/07(火) 01:08:08.27わかりにくくてすいませんでした。
インデントおかしかったですね。今後は気をつけます。
0846デフォルトの名無しさん
2012/02/07(火) 01:23:05.94あー、ここか。あまり良い教材とは言えないと思う。
http://www.fireproject.jp/feature/common-lisp/details/catch_throw.html
Common Lispで例外処理をするときは、catchとthrowは普通使わないんだ。
その上に作られたコンディションというものを使う。
xyzzyを使っているなら、
http://www.geocities.jp/m_hiroi/xyzzy_lisp.html
の方がより正確で多くを解説しているので、こちらを参考にした方が良い。
あと、Emacs Lispについては、オリジナルのリファレンスが結局一番詳しい。
日本語でないと厳しいなら、
http://www.bookshelf.jp/texi/elisp-manual-20-2.5-jp/elisp_10.html
を読むほうが、ググッて出てきたブログとかを読むよりは良いと思う。
0847デフォルトの名無しさん
2012/02/07(火) 01:41:15.91あと、移植については、単純にxyzzyでプログラムを動かすのが目的のベタ移植なら、
そのままcatchとthrowを使えば良いと思う。
よりCommon Lisp的な表現に全体を書き換えているのなら、コンディションを勧める。
Tutorial on Good Lisp Programming Style
http://www010.upp.so-net.ne.jp/okshirai/tutorial-on-good-lisp-programming-style-ja.txt
から引用するけど、
> catchとthrowを使用に対するいくつかの忠告がある:
>
> - マクロとしてより抽象的な制御構造を実装するときに副プリミティブとして
> catchとthrowを用いること。通常のコードの中では用いないこと。
普段使いにはもっと便利なものがあるんで、そっち使いましょうよ、ってこと。
0848デフォルトの名無しさん
2012/02/07(火) 02:04:41.44>Common Lispで例外処理をするときは、catchとthrowは普通使わないんだ。
情報が少ない気がしたのですがそういうことだったんですね。
「catch,throw」より「コンディション」ですね!
調べてみます。
実は載せていただいた資料は前に読んだんですが
少し難しかったです。。。
ですが、emacsのサイトは確かに一番読みやすいですね!!
>>847
common lisp的なものを書けるようになりたいので
「コンディション」で制御できるよう勉強します。
lispで勉強会があれば出たいですが、なかなかないですね。。。
周りにlisp使ってる人がいない場合、やっぱ独学しかないんでしょうね。
0849デフォルトの名無しさん
2012/02/07(火) 09:38:28.30twitter始めてみたら?それか初心者が勉強していくblogを書く。
0850デフォルトの名無しさん
2012/02/07(火) 12:16:40.84出来ない。
(car '())=>nil
(car '(()))=>nil
で結果が同じだとマズいだろ、って事ですよね。
ttp://www.shido.info/gb/guestbook.php?id=1422
この話ってcarをscar(仮)で使った方が良いですか?
(defun scar (l) (if (tree-equal '() l) "#f" (car l)))
またもっとエレガントな方法・アプローチがありますか?
0851デフォルトの名無しさん
2012/02/07(火) 12:45:54.49次はいよいよマクロに手を出してみようかな
0852デフォルトの名無しさん
2012/02/07(火) 14:14:53.56ありがとうございます
reduceをそのように使えばいいのですね
目から鱗です
0853デフォルトの名無しさん
2012/02/07(火) 14:24:40.95(defun 50th (lst) (nth 49 lst))
(proclaim ’(inline 50th))
これと、defmacro で50thを作ったときの違いは何なのでしょうか?
2.9の最後にinline functionの制約はmacroのそれと基本的には一緒だと書いてあるのですが、
common lispのmacroとinline compileは実質的にどう違うかよくわかりません
0854デフォルトの名無しさん
2012/02/07(火) 20:06:22.87そのまま読み進めていけばinlineで書けない実例が大量に出て来る。
0855デフォルトの名無しさん
2012/02/07(火) 21:40:28.11>>835のような実用用途に対するLISPプログラムを初めて読んだ。
結構時間かかったけど、こういう風にするんだな。面白い。
destructing-bindって融通効かしてくれるんだな。きれいに書きますね〜。
(concatenate 'string "test39" (subseq "foo8" (length "foo")))
こういう実務向けの機能知らな過ぎワロタ
このぐらいの長さの物をもっと読みたいんだけど、良いサイトあります?
当方竹内さんの入門書を一冊通した程度の実力。
0856デフォルトの名無しさん
2012/02/07(火) 22:42:59.10どういう分野を勉強したいのか、具体的に詳しく書いた方がいいよ。
あと何を作りたいとか。
0857デフォルトの名無しさん
2012/02/07(火) 23:03:07.02実務向けの機能と言うか、マニュアル(CLtL2)読めばいいじゃん。
0858デフォルトの名無しさん
2012/02/07(火) 23:16:28.21Schemeを使う。半分冗談だけど半分は本気。
Common Lispは利便性と厳格さのトレードオフで利便性を採った言語だから。
多分、その辺が気になるなら、今後も色々引っかかりを覚える事が多いはず。
リーダーをいじって、'()を適当にユニークなデータに置き換えて、
cl:carとかcl:cdrとかcl:consとかも上書き定義して…みたいに頑張るよりは、
nilと空リストが同じことに慣れるか、Scheme使う方が幸せだと思う。
0859デフォルトの名無しさん
2012/02/07(火) 23:19:16.92部分的にしか読んでないけど
パス名の扱いとか懇切丁寧に書いてあってすごい参考になった
0860デフォルトの名無しさん
2012/02/07(火) 23:44:00.80> Schemeを使う。半分冗談だけど半分は本気。
> Common Lispは利便性と厳格さのトレードオフで利便性を採った言語だから。
> 多分、その辺が気になるなら、今後も色々引っかかりを覚える事が多いはず。
勉強で必要最小限Schemeやるけど、今の所、真面目に勉強する気がないなあ。
Scheme使うのは誰かに任せるよ。自分はCL道を極める。
ちなみにSchemeでデバッグ機能も強力で日本語も使える処理系ってRacket?
SchemeってCLみたいに処理系分岐ってできないの?
Gaucheの良さって分かるんだけど、学習コストをかけた後に後々やっぱり
タスキに長し帯に短しで不満が出てきそうなんだよね。
GaucheのコードをRacketに移植ってコストがかかって面倒くさいでしょ。
0861836
2012/02/08(水) 00:00:15.62私幼女だけど、concatenateの部分はむしろ教科書的というか、
多分実用的なコードなら正規表現の後方参照使うと思うの。
あと、(concatenate 'string x y)よりは、(format nil "~a~a" x y)使う。
ついでに、(length ...)の部分は#.(length ...)ってする。
あんま長過ぎず、見てて楽しいっていうと、ユーティリティライブラリじゃないかな。
例えば、こんなんどうだろう。
http://common-lisp.net/gitweb?p=projects/alexandria/alexandria.git;a=tree;js=1
http://www.flownet.com/ron/lisp/rg-utils.lisp
0862デフォルトの名無しさん
2012/02/08(水) 00:27:18.15CL続けるなら、tやnilの使い回しには慣れたほうが良い。
じゃないと、多分CLOSを学習するとき、一番底にあるクラスにビビる。
Schemeだと、現状だとRacketが優秀過ぎるってのはある。
CLに比べると処理系切り替えは楽じゃない。処理系依存部分が大きく、ある程度は面倒。
でもまあ、Gaucheかはともかく、Schemeを勉強するのは、視野が広がって良いと思うよ。
0863SCHEME餃子 ◆8X2XSCHEME
2012/02/08(水) 00:45:13.51処理系ごとの切り替えは srfi-0 があるが…。
http://srfi.schemers.org/srfi-0/srfi-0.html
そもそも srfi-0 をサポートしてない処理系もあるからなー。
racket だと srfi-7 を使えってことになってたと思う。
0864デフォルトの名無しさん
2012/02/08(水) 00:47:07.73> でもまあ、Gaucheかはともかく、Schemeを勉強するのは、視野が広がって良いと思うよ。
英語できて、フランス語できれば、視野が広がるのは分かるんだけど、
時間は有限だからなあ。
0865デフォルトの名無しさん
2012/02/08(水) 18:28:29.02>>855に関連することですが、
THE SEASONED SCHEMERのような短いコードでcommon lispのノウハウを一通り学べるサイトはありますか?
とくにseriesの実例をいくつも見てみたいのですが。
0866デフォルトの名無しさん
2012/02/08(水) 20:41:13.84インラインの装飾をどう変換するのでしょう
あ\*ああ**//強調&斜体//**ううう
この行を
(:P "あ*ああ" (:EM (:ITALIC "太字&斜体")) "ううう")
こうしたいのですが(//で囲まれていればitalic、**で囲まれていればem、\*は*に)、
(defun wiki-syntax->html-like-sexp (text)
;; cl-ppcre
(ppcre:register-groups-bind (first second third)
("^(.*?)\\*\\*(.+?)\\*\\*(.*?)$" text)
(list first (list :em second) third)))
このように書くと:italicに対応するため正規表現を複雑にしなければなりません
読み込んだ文字列全体を:pでまとめるというのも入れると、こんがらがりそうです
どうすればいいのでしょう?
0867デフォルトの名無しさん
2012/02/08(水) 20:53:05.55clikiを見たらwiki用のライブラリもあるみたいだから参考にすると良いんじゃないかな。
0868デフォルトの名無しさん
2012/02/08(水) 20:56:16.480869デフォルトの名無しさん
2012/02/08(水) 21:20:22.06いくつかあるパーサコンビネータライブラリを使うかした方が多分楽だと思う。
多分、最終的にはもっと多くのWiki構文をサポートするんでしょ?
0870デフォルトの名無しさん
2012/02/09(木) 14:41:12.30ありがとうございます。たしかに既存のパーサを利用するのがよさそうですね。
はい。多くのwiki構文をサポートするつもりです。
早速やってみます。
0871866
2012/02/09(木) 18:55:09.42字句解析を書いたのですが:があらわれると
illegal terminating character after a colon: #\
となってしまいます
ソースはこちらです
http://paste.lisp.org/display/127608
コロンを特別の字句として解析するにはどうすればいいのでしょうか。
0872デフォルトの名無しさん
2012/02/09(木) 21:21:08.69:もreadが読んでる。:の解析部分はこの場合には使用されてない。
もともと内部的にもLispではない文字列だからreadは使えない。怠けず全文字処理すべし。
0873デフォルトの名無しさん
2012/02/10(金) 14:34:06.44cl-yaccを使うなら、lexerもライブラリを使えば?
0874デフォルトの名無しさん
2012/02/11(土) 15:48:00.58ありがとうございます
指摘を受けてloopのacrossを使って全文字を処理するようこう書き換えました
http://paste.lisp.org/display/127669
処理できたようなのですが、なぜかサンプルと同じように動きません
http://lispuser.net/memo/lisp/2006-03-30-23-58.html
の「つくったら早速 REPL で試してみましょう.」以下と同じく出力されると思うのですが
>>873
http://blogs.yahoo.co.jp/oiron_abok/archive/2011/9/21
これを見てcl-lexをいじってみたのですが#\newlineと#\spaceの検出方法がわかりませんでした
0875デフォルトの名無しさん
2012/02/12(日) 02:09:23.54あんまloop詳しくないけど、do節の使い方が間違ってる気がする。
あと、字句解析器(lexer)はトークンをひとつずつ返せばいいので、
一度に全体を走査する必要ないはず。
http://ja.wikipedia.org/wiki/%E5%AD%97%E5%8F%A5%E8%A7%A3%E6%9E%90
それと、想定外の結果になったら、問題の切り分けからすると良いと思う。
この場合、まずlexerが正しく動作するか確認すれば、問題の位置を特定できる。
lexerの中にはloopしかない。loopをマクロ展開すると、どうやら値を返すようになってない。
じゃあ、HyperSpecやCLtL2とかのリファレンスを見てみよう、って感じで。
0876デフォルトの名無しさん
2012/02/12(日) 03:22:32.57こんな感じのことがやりたかったってことで良いんだろうか。
http://paste.lisp.org/display/127683
0877デフォルトの名無しさん
2012/02/12(日) 10:58:50.37もう要らないかも知れないけど、cl-lexはlexと同じく正規表現で指定する。
0878デフォルトの名無しさん
2012/02/12(日) 18:22:23.84cl-lexを使うパターンと使わないパターンの二つを書いてみました。
>>875-876
たしかにご指摘のとおりloopの部分がおかしかったです。
そしてまさに>>876の例が行いたかった処理です。うまく動きました。
ただ、コメントにあるように効率的に処理するために一度に複数のトークンを切り出すのが理想的ですが
peek-charを使っても一つ先しか見れません
http://paste.lisp.org/display/127703
このようにして先の文字を読み込むのではなく、はじめにpeek-charを使うと今度は": "の読み込みで
引っかかってしまいます。
>>877
正規表現を書き直したら大方うまく動きました。行も判定できました。
ですが、backslashの判定と、パースの結果をまとめる部分がうまくいきません。
cl-lexを使ってこのように書きました。
http://paste.lisp.org/display/127704
引き続き調べます。
0879デフォルトの名無しさん
2012/02/12(日) 20:40:33.48> ただ、コメントにあるように効率的に処理するために一度に複数のトークンを切り出すのが理想的ですが
なぜトークンを切り出す関数を別に作らない?
(t (values :token (get-token c in)))
とかすれば, ええんちゃう?
0880デフォルトの名無しさん
2012/02/12(日) 23:42:39.64分かってるっぽいけど「複数のトークン」じゃなくて、「複数文字のトークン」。
構文解析のときに一文字ずつ解析するより、ブロックごとの方が効率良くなるという話。
とりあえず、ライブラリで字句解析するみたいだからこの辺で止めとく。
あと、コメントに書いたように、"う\うう"だと"ううう"と同じに解釈されるからね。
"う\\うう"じゃないと、文字列にバックスラッシュが含まれることにならない。
あと、colonの区別が付かないのはread-from-stringしてるから。
元の値を使えば良いと思うんだけど、readしてるのは何か事情があるの?
0881デフォルトの名無しさん
2012/02/13(月) 14:12:28.41>>880 read-from-stringを使っていたのはミスでした
そのまま値を返せばよいだけでした
バックスラッシュについても勘違いしていたようで、
他のファイルのテキストから読み込むときにはバックスラッシュをきちんと認識できていました
これで問題が無事解決しました
お騒がせいたしました
0882デフォルトの名無しさん
2012/02/14(火) 17:57:50.83schemeのsicpなら
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/
がありますが。
0883デフォルトの名無しさん
2012/02/14(火) 18:47:06.73win
0884デフォルトの名無しさん
2012/02/14(火) 20:18:01.64lispboxでいいんじゃない?
紫藤のWiki と lispbox で検索
0885デフォルトの名無しさん
2012/02/14(火) 22:19:27.24おなじの物ばかりかもしれないが。
0886デフォルトの名無しさん
2012/02/15(水) 14:08:33.85(print (make-sequence 'list 100))
これをsbclやclispで行うとNIL19個毎に改行されてしまいます。
どうすれば改行せずに出力出来ますか?次工程でgrepなんかを使いたいのです。
よろしくお願いします。
0887デフォルトの名無しさん
2012/02/15(水) 14:38:12.07(let ((*print-pretty* nil)
(*print-length* nil))
(print (make-sequence 'list 100)))
0888デフォルトの名無しさん
2012/02/15(水) 14:46:42.86動きました。ありがとうございます。
pretty print絡みだったんですね。
0889デフォルトの名無しさん
2012/02/15(水) 15:24:36.69ありがとう
slimeの入門動画なんてものがあったんだな
知らなかったよ
0890デフォルトの名無しさん
2012/02/15(水) 18:43:19.33株式会社数理システムの子会社化について
ttp://www.nttdata.co.jp/release/2012/021500.html
0891デフォルトの名無しさん
2012/02/16(木) 07:02:40.13Common Lispユーザにとって色々有益な情報を出してくれる所だから、少し不安。
0892デフォルトの名無しさん
2012/02/17(金) 01:32:25.22以下の方法でSBCL 1.0.40.0.debianでは動いていたはずなのですが、
SBCL 1.0.50.0.debianではエラーが出てしまいます。
メモリが少ないために小分けで何万回と実行する予定ですので
コンパイル済みのバイナリとしたいのです。
どうすれば良いでしょうか?よろしくお願い致します。
hell.lisp:
(print "HELL!")
$ sbcl --noinform --disable-debugger --eval "(compile-file \"hell.lisp\")" --eval '(quit)'
; compiling file "/.../hell.lisp" (written 17 FEB 2012 XX:XX:XX AM):
; compiling (PRINT "HELL!")
; /.../hell.fasl written
; compilation finished in 0:00:00.003
$ chmod +x hell.fasl
$ ./hell.fasl
unhandled SB-C::INPUT-ERROR-IN-COMPILE-FILE in thread #<SB-THREAD:THREAD
"initial thread" RUNNING
{AA65919}>:
READ failure in COMPILE-FILE:
SB-INT:SIMPLE-READER-ERROR at 27 (line 2, column 2) on #<SB-SYS:FD-STREAM
for "file /.../hell.fasl"
{AA697D9}>:
illegal sharp macro character: #\
0893デフォルトの名無しさん
2012/02/17(金) 01:34:17.670: (SB-DEBUG::MAP-BACKTRACE #<CLOSURE (LAMBDA #) {AA75BAD}> :START 0 :COUNT 128)
1: (BACKTRACE 128 #<SB-SYS:FD-STREAM for "standard error" {AA669C9}>)
2: (SB-DEBUG::DEBUGGER-DISABLED-HOOK
#<SB-C::INPUT-ERROR-IN-COMPILE-FILE {AA71861}>
#<unavailable argument>)
3: (SB-DEBUG::RUN-HOOK
*INVOKE-DEBUGGER-HOOK*
#<SB-C::INPUT-ERROR-IN-COMPILE-FILE {AA71861}>)
4: (INVOKE-DEBUGGER #<SB-C::INPUT-ERROR-IN-COMPILE-FILE {AA71861}>)
5: (ERROR
SB-C::INPUT-ERROR-IN-COMPILE-FILE
:CONDITION
#<SB-INT:SIMPLE-READER-ERROR "illegal sharp macro character: ~S" {AA71791}>)
6: (SB-C::READ-FOR-COMPILE-FILE
#<SB-SYS:FD-STREAM for "file /.../hell.fasl"
{AA697D9}>
25)
7: (SB-INT:LOAD-AS-SOURCE
#<SB-SYS:FD-STREAM for "file /.../hell.fasl"
{AA697D9}>
:VERBOSE
NIL
NIL
:CONTEXT
"loading")
0894デフォルトの名無しさん
2012/02/17(金) 01:34:51.958: ((FLET SB-FASL::LOAD-STREAM)
#<SB-SYS:FD-STREAM for "file /.../hell.fasl"
{AA697D9}>
NIL)
9: (LOAD
#<SB-SYS:FD-STREAM for "file /.../hell.fasl"
{AA697D9}>
:VERBOSE
NIL
NIL
:IF-DOES-NOT-EXIST
T
:EXTERNAL-FORMAT
:DEFAULT)
10: ((FLET SB-IMPL::LOAD-SCRIPT)
#<SB-SYS:FD-STREAM for "file /.../hell.fasl"
{AA697D9}>)
11: ((FLET #:WITHOUT-INTERRUPTS-BODY-[PROCESS-SCRIPT]69))
12: (SB-IMPL::PROCESS-SCRIPT "./hell.fasl")
13: (SB-IMPL::TOPLEVEL-INIT)
14: ((FLET #:WITHOUT-INTERRUPTS-BODY-[RESTART-LISP]30))
15: ((LABELS SB-IMPL::RESTART-LISP))
unhandled condition in --disable-debugger mode, quitting
$
0895デフォルトの名無しさん
2012/02/17(金) 05:07:44.25落としてきてbat実行するだけじゃダメなのかこれ?
linuxのはsh実行するだけで普通に動いたんだが
0896デフォルトの名無しさん
2012/02/17(金) 05:39:03.41これは昔のバージョンだけ?lispbox-0.7には入ってないみたいだけど
0897デフォルトの名無しさん
2012/02/17(金) 06:20:45.30ダブルクリックではなくコマンドプロンプトから実行すれば
何かしらエラーメッセージでも出そうなものだけど
0898デフォルトの名無しさん
2012/02/17(金) 06:46:01.31むしろ、その話が事実だと、前はFASLをそのまま実行できたということに。マジですか。
SBCLでバイナリを作るには、cl:compile-fileじゃなくてsbcl-ext:save-lisp-and-dieを使えば大丈夫。
Common Lispでは(Cとかでもそうだけど)コンパイルと実行形式を作ることとは別なのでご注意。
http://cl.cddddr.org/index.cgi?%bd%e8%cd%fd%b7%cf%3a%bc%c2%b9%d4%a5%d5%a5%a1%a5%a4%a5%eb%a4%ce%ba%ee%a4%ea%ca%fd
ただ、メモリの消費量とバイナリにすることって、多分あんまり関係ないと思うけど、
それはそれで大丈夫なんだろうか。
0899デフォルトの名無しさん
2012/02/17(金) 08:02:38.86すいません、自己解決しました;
windowsのユーザーフォルダ名が日本語だったのでそれが原因でエラーが
起きてた模様
レスありがとうございました
0900デフォルトの名無しさん
2012/02/17(金) 13:12:34.76ありがとうございます。
>むしろ、その話が事実だと、前はFASLをそのまま実行できたということに。マジですか。
faslにはシバン(#!/usr/bin/sbcl --script)が付加されてるので実質はsbcl呼んでるんですけどね。
0.50にも付いてるのですが動かなくなりました。
>SBCLでバイナリを作るには、cl:compile-fileじゃなくてsbcl-ext:save-lisp-and-dieを使えば大丈夫。
save-lisp-and-die時のTOPLEVELの指定が分かりません。
スクリプトとコンパイルのソースを共有したかったので。
実行時型チェックすれば良いのだろうけど。
>ただ、メモリの消費量とバイナリにすることって、多分あんまり関係ないと思うけど、
起動に掛かる時間を減らしたいのです。
コンパイルとか数秒掛かるでしょ。何万回とかになると何時間にもなるのではないかと。
実際は何百万回とかだた。
0901デフォルトの名無しさん
2012/02/17(金) 13:27:19.85# save-lisp-and-die時のTOPLEVELの指定が分かりません。
WEBだと関数を指定しているものばかりなのですが、
スクリプトの場合は関数の呼び出しまで記述する必要があり
共用させるのに「おまじない」が必要になります。
例示した様なスクリプト形式のままで実行出来る
コンパイルの方法が分からないとの意味です。
0902デフォルトの名無しさん
2012/02/17(金) 14:18:49.78なるほど。そちらの事情は把握できたと思う。
とりあえず、1.0.51以降でのFASL周りの変更は、型関係の不具合修正だけなはずなので、
1.0.55でも直ってない気はする。1.0.40以降のリリースノートにも書いてないように見える。
それって正式な機能なのかな? マニュアルのFASLの項には特に書いてない感じだけど。
正式な機能ならLaunchpadへ報告どうぞ。そうでなくとも、MLで聞いてみても良いかも。
自分なら、トップレベルの関数を利用する形にスクリプトのコードを自動変換し、
それをコンパイルしてロード、save-lisp-and-dieするまでの処理を自分で書いちゃって、
今度からそれを使うようにすると思う。一度書いちゃえば次からは使い回しもできるし。
ただ、いかにもkludgyではあるので、そちらのお気には召さないかも。
それと、多分バイナリにまでする必要はなくて、ロードした状態のイメージを保存して、
それを処理系を起動するときのイメージとして指定すれば、同じ効果が得られると思う。
ロード時間を削るために良く使われる手じゃないかと。
0903デフォルトの名無しさん
2012/02/17(金) 18:03:16.60いまいち何がしたいのか理解できてないけど、バイナリにしたいのではなくて、コンパイル済のファイルを呼び出したいだけではないの?
シバンに任せずに普通にloadしてはいけないの?
0904デフォルトの名無しさん
2012/02/17(金) 18:07:10.83エラーの直接の原因としてはfaslファイルの2行目の# FASLの部分でマクロキャラクタと判別してるからだと思う。
0905デフォルトの名無しさん
2012/02/17(金) 20:30:39.44>>902
LISP初心者なんでLaunchpadとかよく分かりません。
ベテランLISPerが誰も困ってないのなら仕様どおりなのでしょう。
処理時間の関係だけなので実はソースを弄ってsave-lisp-and-dieで既に動かしてはいます。
今まで便利だったのでそのまま使えたらと考えました。
>ただ、いかにもkludgyではあるので、そちらのお気には召さないかも。
ソースコードの可読性が損なわれないなら問題ありません。
>トップレベルの関数を利用する形にスクリプトのコードを自動変換し、
LISPならこんな事も簡単?に出来るのでしょうか。勉強してみます。
>ロードした状態のイメージを保存して、それを処理系を起動するときのイメージとして指定すれば、
これってsave-lisp-and-dieの事ですよね。
>>903
個人的にsave-lisp-and-dieの方法も検討していたので書き方が混乱していました。
目的は処理時間の短縮なので方法には拘りません。今まで(とは言っても数日ですが)
動いていたのが環境を変えたら動かなくなったのでどうなったのかなと。
>>904
なるほど。
実は0.40ではシバン付けたままでもコンパイルが通ってたんですよ。
シャープマクロ?の解析方法が変わったのかもしれませんね。
0906デフォルトの名無しさん
2012/02/18(土) 00:55:04.52Launchpadってのは、オープンソースプロジェクトのホスティングサービスで、
その機能のひとつであるバグトラッキングシステムをSBCLは使ってる。
非公式な機能でなければ、開発者に不具合報告してみれば良いのでは、って話。
イメージの件はそう。:executable tを指定しなければ単なるコアイメージができる。
あと、コードの変換については、別にそんな難しいことを言ってるわけじゃなくって、
こういうのをcompile-fileの代わりに使えば良いんじゃないかと思う。
(defun script->executable (exe-file-name src-file-name)
(let ((tmp-file-name (format nil "~a.tmp" src-file-name))
(toplevel-symbol (gentemp "TOPLEVEL")))
(with-open-file (src src-file-name)
(with-open-file (tmp tmp-file-name :direction :output :if-exists :error)
(format tmp "(defun ~a ()~%" toplevel-symbol)
(do ((line (read-line src nil) (read-line src nil)))
((null line))
(write-line line tmp))
(format tmp "~&)~%")))
(compile-file tmp-file-name)
(load tmp-file-name)
(delete-file tmp-file-name)
(sb-ext:save-lisp-and-die exe-file-name
:toplevel toplevel-symbol
:executable t)))
0907デフォルトの名無しさん
2012/02/18(土) 18:08:27.54コードまでありがとうございます。全体をdefunで括っても構わないのですね。
何となくdefunやrequireなんかを除外しないといけない様な気がしていました。
早速シバンの除去とコマンドラインから起動出来る様にしました。
これで今まで同様の操作で行けます。本当にありがとうございました。
0908デフォルトの名無しさん
2012/02/18(土) 18:09:12.81SBCL自体では *シバンはサポートしてない* みたいです。
私の環境で動いたのは~/.sbclrcに以下を記述していた為でした。
(同様な記述がいくつもありますがおそらくhttp://www.kono.cis.iwate-u.ac.jp/~hiki/?SBCLからのコピペ)
0.40でも0.50でも全く同じに設定(FTPでコピーしたのでcksum値も同じ)してあるのですが、
動作が変わった理由が分かる方おられますか?
なお、上記代替策がありますのでそれ程逼迫したものではありません。
お騒がせして申し訳ありませんでした。
;;; If the first user-processable command-line argument is a filename,
;;; disable the debugger, load the file handling shebang-line and quit.
(let ((script (and (second *posix-argv*)
(probe-file (second *posix-argv*)))))
(when script
;; Handle shebang-line
(set-dispatch-macro-character #\# #\!
(lambda (stream char arg)
(declare (ignore char arg))
(read-line stream)))
;; Disable debugger
(setf *invoke-debugger-hook*
(lambda (condition hook)
(declare (ignore hook))
;; Uncomment to get backtraces on errors
;; (sb-debug:backtrace 20)
(format *error-output* "Error: ~A~%" condition)
(quit)))
(load script)
(quit)))
レス数が900を超えています。1000を超えると表示できなくなるよ。