【入門】Common Lisp ..
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
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
4314日前に更新/249 KB
担当:undef