CommonLisp Scheme Part11at TECH
CommonLisp Scheme Part11 - 暇つぶし2ch159:デフォルトの名無しさん
04/08/21 00:51
>>158
156のテクニックは必要な領域を減らすことができるの?

160:デフォルトの名無しさん
04/08/21 01:19
もういいだろ!

161:デフォルトの名無しさん
04/08/21 01:26
(gc!)

162:デフォルトの名無しさん
04/08/21 01:35
釣られすぎー


163:デフォルトの名無しさん
04/08/21 03:09
xyzzy とかで lisp-interaction-mode だと
自動的にLispのインデントをしてくれますよね?
でも、*.l を開いた後、自動インデントにならないのです
*.l のときは、Lisp用のインデントをしてくれるように
設定したいのですが、方法をご存知の方いませんか?
ググって調べたいのですが、何で調べたらよいのかも
よくわからないのです。

164:デフォルトの名無しさん
04/08/21 03:15
describe *auto-mode-alist*

165:デフォルトの名無しさん
04/08/21 03:16
妙に書き込みがあると思ったら…

95は>>63を彷彿とさせるなぁ…

166:デフォルトの名無しさん
04/08/21 04:02
>>165
そうか?95 はちゃんとした人だと思うが。
当初の勘違いのせいもあって、コミュニケーションがうまく
行かなかっただけじゃないのか?

167:デフォルトの名無しさん
04/08/21 04:06
ところで、Lisp スレも現在 Part11 に至っているわけだが、
その間、スレの参加者は増えたのだろうか?
URLのパラメータがUNIX時間なので、その差分を取ってみた。

(define x '(1091456033
       1075630259
       1069594582
       1058263391
       1042167213
       1031560687
       1023091882
       1016211619
       1008220265
       1002584344
       987169286))

(let loop ((x x))
 (if (null? (cdr x))
   '()
   (cons (/ (- (car x) (cadr x)) 86400.0)
      (loop (cdr x)))))

結論:全く傾向なし。いや、増減なしと見るべきか?
Lisp 人口は生きた化石のごとく変わらないのであろうか?

168:デフォルトの名無しさん
04/08/21 04:33
>>146
ワード?


169:デフォルトの名無しさん
04/08/21 05:01
レベルは下がり続けているな。

170:デフォルトの名無しさん
04/08/21 05:54
未踏の lego 用 XS lisp って本当にいじってみた人いる?
Google で「面白そう」って意見は結構見るんだけど
おれは Lisp 入門者だけど実装側の勉強にもなるかな?


171:80
04/08/21 10:35
>>83 >>85
情報サンクス。
λ計算の理論から導出される公式として覚えておけば良いものみたいですね。
情報数学知らなかったので助かりました。


172:デフォルトの名無しさん
04/08/21 19:06
>>164
サンクス

173:デフォルトの名無しさん
04/08/21 22:33
気付いたら>>95のヴォケのおかげで無駄レスが・・

174:デフォルトの名無しさん
04/08/23 02:51
陸上の末続選手はちょっと Shiro さんに似てると思った

175:デフォルトの名無しさん
04/08/23 14:55
>>174
ぜ、全然似てない…!!!
URLリンク(images.google.co.jp)

176:デフォルトの名無しさん
04/08/23 23:02
>>174 馬鹿だな、親戚だから似てて当たり前


177:デフォルトの名無しさん
04/08/24 13:01
>>71
マクロを使ったプログラムの互換性を保障したいためでしょ。
デファクトなんだし、仕様に取り込んでもいいと思うのだが。
Schemeマクロを実装するよりも、ずっと手軽に実装できるしな。

178:デフォルトの名無しさん
04/08/24 19:39
>>177
legacyマクロでプログラムの互換性を保障するのは難しいよ。
バッチコンパイルする処理系だと、マクロから呼んでる関数が
マクロ展開時にはまだ無いってことがあり得る。
え、eval-whenですか? それはちょっと…


179:デフォルトの名無しさん
04/08/24 21:11
eval-whenは必須でしょ

180:デフォルトの名無しさん
04/08/24 21:38
そんなマクロはうちの子じゃありません

181:デフォルトの名無しさん
04/08/24 22:28
eval-whenてなに?

182:デフォルトの名無しさん
04/08/25 00:53
>>181
黒魔術。

183:デフォルトの名無しさん
04/08/26 00:50
(expt float integer)

としたとき,ちゃんと (* float float float ...) と等価になりますか?
HyperSpac では (expt rational integer) のときしか書いてないような.

普段は (expt float1 float2) == (exp (* float2 (log float1))) だと書いてありますが,
2 乗や 3 乗のときは,これでは困りますよね.

不安なら整数用の expt を作る必要がありますか?

184:デフォルトの名無しさん
04/08/26 01:32
>>183
>2 乗や 3 乗のときは,これでは困りますよね.
なにが困るのか判らない。

185:183
04/08/26 23:37
>>184
2 回か 3 回の掛け算で済むことに,log や exp の計算
(級数などを使うのでしょうか?) をしてしまうのは不経済では,と思ったのです.

186:デフォルトの名無しさん
04/08/27 00:02
それは「困る」とは違うよね

187:デフォルトの名無しさん
04/08/27 06:26
>>183
処理系任せだろうね。真面目な処理系なら最適化してるんじゃない。
心配ならプロファイリングしてみれば。
というか、そんな細かいところを気にする前にベンチ取ってボトルネック
見つける方がいいと思うよ。

188:183
04/08/28 14:02
>>186-187
みなさんのお陰で考え方が分かりました.ありがというございました.

(expt rational integer) の場合が記されているのは,
速度ではなく型の問題なんですね.

> 心配ならプロファイリングしてみれば。
> というか、そんな細かいところを気にする前にベンチ取ってボトルネック
> 見つける方がいいと思うよ。

そうですね.言われるまでこういうことには気づきませんでした.

189:デフォルトの名無しさん
04/08/29 17:38
LISPって遅そうでめちゃんこ速いね

190:44
04/08/29 18:43
数値 (float) が書かれたテキストを読んで,
それとソース内のリテラルとで算術演算する場合は,
リテラルの表記を *read-default-float-format* に合わせておくべき,
というより合わせなくてはならないのでしょうか.

もう頭が痛いです.ソース内のリテラルも *read-...-format* で読むと
不都合でもあるのでしょうか...

clisp で long-float する人たちは,
リテラル全ての箇所で coerce するなんて,そんな話はありませんよね?

191:デフォルトの名無しさん
04/08/29 18:59
必要なら全ソースを*read-default-float-format*で検索すれば
そのうちわかるんでは?
clispも企業に対して動作保障をしているわけではないし、
どの言語処理系も数値周りは手抜き工事していたり、
バグの温床だったりする可能性が高いので。

192:デフォルトの名無しさん
04/08/29 19:27
>>190
最終的な目的がなんなのかによるだろ

193:デフォルトの名無しさん
04/08/29 20:45
defineの挙動なんですが、top levelとそうでないときとで
動作が異なるってやつの実装がマンドクセえんですが

実際はどうやってんでしょう
フラグ?

194:44
04/08/29 22:54
むむ,compile しないで実行すると warning が出ない.
compile の過程で勝手に single-float にされているのかな?

>>191
探してみましたが,.lisp と .d がソースの全てでいいんですか?
grep の結果が思ったより少ないんですが...
ところで .d って何なんでしょう?
ソース/emacs/d-mode.el まであるのに何かは不明なんです.

>>192
ちょっとファイルから読んで計算するだけです.
single-float では桁が寂しい感じがしたので,せっかくだからと
long にしただけなのに怒られた,というわけなんです.

195:デフォルトの名無しさん
04/08/29 23:07
>>194
>ところで .d って何なんでしょう?

>Most of the C code of CLISP is stored in files with extension '.d'. It _is_
>C code, but the file will be preprocessed a bit.

URLリンク(cvs.sourceforge.net)

ECL とかでも使われてたと思う。何のメリットがあるかは知らない。

196:44
04/08/30 01:30
今まで eval-when を使ったことが無かったのですが,
もしかしてと思い,

(eval-when (compile load)
  (setf *read-default-float-format* 'double-float))

としたら,問題無くなりました.コンパイル時にも,その後の実行の時も
double-float で読む,ということなんですね.
今までこんな便利なものも知らなくて問題を長期化させました.すみませんでした.

197:デフォルトの名無しさん
04/08/30 19:45
>>193
環境を見ればトップレベルかどうかはわかるよね。

internal defineはマクロとの絡みがややこしい。
実装者泣かせかな。


198:デフォルトの名無しさん
04/08/30 21:49
内部defineはふつー実行前にletrecに変換するでしょ
まともな処理系なら

199:デフォルトの名無しさん
04/08/31 18:59
Dr.Schemeで「独習Scheme三週間」で紹介されてるすべての構文を使用するには
どうすればいいの?
ドットリストで構文エラー出るよ・・・

200:デフォルトの名無しさん
04/08/31 21:42
>>199
ドットリストで構文エラー出るなんてありえねー
そのコードさらしてみ

201:デフォルトの名無しさん
04/08/31 22:00
>>199
Language → choose Language で Full Scheme

202:デフォルトの名無しさん
04/09/01 01:57
9月の言語はSchemeと決まっています.

203:デフォルトの名無しさん
04/09/01 18:52
8月の言語は何だったの?

204:デフォルトの名無しさん
04/09/01 20:14
Augustだ。
略してAda。

205:デフォルトの名無しさん
04/09/02 14:12
cl の loop が,*短ければ* 読みやすさも書きやすさも両立してて,
すごくいいことを知りました.
lisp らしくないからと拒んでいた自分が悲しいです.
; グレアム氏の入門書が偏っているせいかと w

ところで,ファイルを丸々 string にする方法を探していたところ,
make-string したところに read-sequence を
使って書き込んでいくやつを見つけました.
でも,これしか無いんですか?

get-output-string-stream の input-stream 版が無いのは残念ですね.

206:デフォルトの名無しさん
04/09/02 20:22
そうこうしてるうちにOnLisp邦訳も更新されてたね。乙
後2章か、がんがれ

207:デフォルトの名無しさん
04/09/02 21:38
URLリンク(www.itmedia.co.jp)

208:デフォルトの名無しさん
04/09/02 22:44
>>207
なんだかなぁ... すべてが痛々しい

209:デフォルトの名無しさん
04/09/02 23:53
>>205
骨格だけ。
with-outpt-to-string (out)
(loop for line = (read-line stream) do (write-line line out)
とか。eofをどうするか(whileにするかエラー捕まえるか)は好きにすれ。
loopはcollect intoとかfor acrossとかfinallyとか使い出すと妙に可読性が
上がるので結構多用してるカモ。Lispらしからぬ見た目になるけどね。

210:デフォルトの名無しさん
04/09/03 00:04
3年前はロン毛だったと記憶してるんだけど・・・これヅラだよね?普通に考えて。

211:デフォルトの名無しさん
04/09/03 01:07
>>209
read-line は改行を消してしまうね.
「行の区切り」を指定できるスペシャル変数があればいいのに.
; awk みたいだ...

212:デフォルトの名無しさん
04/09/03 01:30
学生時代に授業でSchemeをちょこっとやったんですが、
最近CommonLispをいじってます。
で、CLのlambdaなんですが

(lambda (x) (* x 2)) => error
#'(lambda (x) (* x 2)) => anonymous closure

これにすごい違和感があります。この「#'」はナニモノで
何故必要なんでしょう。

213:デフォルトの名無しさん
04/09/03 02:00
>>212
このページが大変参考になる。
URLリンク(www.ice.nuie.nagoya-u.ac.jp)

214:デフォルトの名無しさん
04/09/03 02:28
LISP-1か2の違い。

215:デフォルトの名無しさん
04/09/03 04:24
数ヵ月前に見た時もロン毛だったよ>ドクターT。



216:デフォルトの名無しさん
04/09/03 13:12
cmuclで関数の実行時間をはかりたいのですが、何を使うのが適当でしょうか?
変数にとりたいのですが、timeマクロは出力してしまうから使えず、
get-internal-run-timeは秒単位らしくて粗すぎて使えず、です。



217:デフォルトの名無しさん
04/09/03 14:43
>>216
(get-output-string-stream)
で作ったストリームで *standard-output* を let で上書き,,,でできますか?

218:デフォルトの名無しさん
04/09/03 15:44
cmucl でコンパイルすると,結果がおかしくなりました.

(let ((alist '((:file . "foo.txt")
(:bar))))
(with-open-file (istrm (cdr (assoc :file alist)))
(rplacd (assoc :bar alist) 6))
(format t "~S~%" (assoc :bar alist))
(format t "~S~%" (car (assoc :bar alist)))
(format t "~S~%" (cdr (assoc :bar alist))))

これは,clisp ではコンパイルしてもしなくても
(:BAR . 6)
:BAR
6
となりますし,cmucl でもコンパイルしなければ同じ結果になります.しかし,

# lisp -eval '(compile-file "foo.lisp")' -eval '(quit)'
...
# lisp -load foo.x86f -eval '(quit)'
(:BAR . 6)
:BAR
NIL

となります.cdr 部はどこへ行ってしまったのでしょうか.困ってしまいました... (⊃д`)
バージョンは以下です (起動時のメッセージの一部).
CMU Common Lisp CVS release-19a 19a-release-20040728 + minimal debian patches, running on

219:218
04/09/03 15:45
追記.with-open-file を外せば直ります.

220:デフォルトの名無しさん
04/09/03 19:44
>>218
リテラルリストを破壊的に変更しちゃいかんよ。


221:218
04/09/03 20:35
>>220
結果は処理系依存ということなんですか.
最初の alist を,
(list (cons :file "foo.txt")
      (cons :bar nil))
に変更すればいいのでしょうか.

こういうのを警告してもらう方法がありましたら教えてください.

222:デフォルトの名無しさん
04/09/03 20:39
(rplacd (assoc :bar alist) 6))

(setf alist (cons (cons :bar 6) alist))

223:218
04/09/03 22:16
>>222
assoc で引かれることがないとしても,なんとなく違和感がありませんか?
こういうのを普通に感じるて初めて中級者なのでしょうか.

224:デフォルトの名無しさん
04/09/04 02:10
リテラルを書き換えちゃだめってのは別にLispに限らない、プログラミング言語
一般(とくにコンパイラが介在するもの)に言えることでしょう。
Cでも文字列リテラルには手は出せませんし。


225:デフォルトの名無しさん
04/09/04 03:01
> Cでも文字列リテラルには手は出せませんし。

んなこたあない。

普通はしないけど。

226:デフォルトの名無しさん
04/09/04 03:09
OS-9 の C言語処理系は literalが code module (だっけ?) に
置かれるので、書き換えちゃだめでした...

昔話かつ lispじゃないので sage


227:デフォルトの名無しさん
04/09/04 08:18
>>225
> > Cでも文字列リテラルには手は出せませんし。
> んなこたあない。

いや、んなことあるよ。
リードオンリーなセグメントに置かれるので、変更しようとするとbus errorになる。
そうしないとリテラルはプロセス間で共用することも実行ファイルを直接バッ
キングストアにしてmmapすることもできなくてメモリ利用上非効率。
よしんばそうでなくとも複数の同じ内容の文字列リテラルは一つにまとめられるので、
そういうものだと変更すれば当然悪影響が出る。


228:デフォルトの名無しさん
04/09/04 13:43
古き悪しきお行儀の悪いやつ用のコンパイルオプションも大抵用意されてはいるけどね

229:デフォルトの名無しさん
04/09/04 23:18
警告も何も出ない?
セルにimmutableフラグとか付いてないのか。
tinyschemeだか何かの処理系はそういうフラグがあって、
破壊代入するとエラーか何か出た記憶がある。
LISPの場合大抵は複製するから、個人レベルでは対策しなくても
あんま問題にはならないけど、時間置いて使うとたまにやってしまったりするな。
こういう場合の処方で処理系にセーフティレベル上げるとか何らかの
モードがある場合もあるが、実際は目先の速度に気を取られて
気付かない&あえて無視する可能性が高いんだよな。
結局デバッガ立ち上げて原因がわかると。
cmuclレベルの処理系なら何らかのオプションがあると思う。

230:デフォルトの名無しさん
04/09/05 17:46
InterLispって良く見るんですが、これはLisp方言の一種ですか?
それともCL実装の名前ですが?

231:デフォルトの名無しさん
04/09/05 17:52
URLリンク(foldoc.doc.ic.ac.uk)


232:デフォルトの名無しさん
04/09/05 22:03
>>217
折角教えていただいたのですが、出力文字列を解釈しなくちゃいけなくて大変そうで、
unix-gettimeofdayでusecをとってごまかしてしまいました。
プロセス時間じゃなくて実時間ですが。
経験値を上げてもうちょっと賢くなったらトライしてみます。


233:デフォルトの名無しさん
04/09/05 22:49
WindowsでLISPでマルチメディアが扱える
処理系ってないのでしょうか

234:デフォルトの名無しさん
04/09/05 23:48
マルチメディアってなんなんやー?

235:デフォルトの名無しさん
04/09/06 00:37
メディアが複数同時に使えることでは?

236:デフォルトの名無しさん
04/09/06 02:06
フロッピーとハードディスクのファイルを読み書きできるとかか。

237:デフォルトの名無しさん
04/09/06 03:12
クイックディスクを忘れないで欲しい。

238:デフォルトの名無しさん
04/09/06 06:22
えっと、lispacheの苫米地氏とオウム事件「逆洗脳」の苫米地氏って、
同じ人なんですか??

239:デフォルトの名無しさん
04/09/06 10:34
>>234-238
おまえら、いい加減にしろw

>>233
やっぱりACLじゃないの?
なんでもできそうだけど。

240:デフォルトの名無しさん
04/09/06 15:00
gauche用のsdlラッパというのが一番ありがちなパターンに見えるなあ

241:デフォルトの名無しさん
04/09/06 15:39
>>233
LISPならxyzzy,SCHEMEならHandySchemeのMCI関数でどうよ?


242:233
04/09/06 22:15
ACLインストールしました
HandyScheme は知りませんでした
なんかゲームの挙動をLISPで書いて
細かい部分をCで書いて、みたいな
ことを考えてるんですけど・・・
とするとgauche の sdlラッパというのがよさげですね
有難うございました

243:デフォルトの名無しさん
04/09/06 23:52
>>238
t

>>233=242
Corman Common Lispも見てみれば? IDE使わなきゃ無料だしWindows APIと
仲良くするのも結構得意だというのを聞いた希ガス。実体験ではないので本当のトコロが
どんなもんか知らんけど。
マニュアル眺めた限りではDLL作ったりとかインラインアセンブラ使ったりとかWindowsが
主環境であればそれなりに使えそうだったよ。SDLも誰かライブラリ作ってたはずだし。

244:233
04/09/07 00:48
>>243
有難うございます
いつも不思議に思うのですが
私も結構Lisp関連のサイトをこまめに
調べてはいるのですがそういう情報にたどり着けない・・・
どこでそういう情報を得るのですか?
英語圏を調べろってことですかね・・・欝

245:デフォルトの名無しさん
04/09/07 07:22
Cormanは日本語が通らないのが難点。ゲームとか作るんなら要らないかも知れないが。
それとも今は通るようになったのかな?


246:243
04/09/07 21:19
どこでって普通にググるとかcomp.lang.lisp読むとか。
英語圏避けてたらLisp関連サイト調べてないのとほぼ等価と思われ。
ってか折角ただでいろんな情報転がってるのに自分で枠狭めてちゃもったいない。
RCE関連サイトにはロシア語圏にディープなのが多いね。

247:デフォルトの名無しさん
04/09/07 22:41
Arcの話題ってこことは違う?

248:デフォルトの名無しさん
04/09/08 00:46
ここでいいんじゃないの。何か進展あった?

249:デフォルトの名無しさん
04/09/08 02:20
slime 1.0
URLリンク(common-lisp.net)

250:デフォルトの名無しさん
04/09/08 05:53
gaucheってそもそも Windows に正式対応してたっけ?
Windows 2000 + cygwin でなんとかコンパイルできる段階みだいだけど、
ちゃんと使えてる人いる?




251:デフォルトの名無しさん
04/09/08 09:17
XP + Cygwin でとりあえず gosh が起動しますが
それ以上の確認はしてないっす

252:デフォルトの名無しさん
04/09/08 10:19
普通に使える
GLも使える
問題なし

253:デフォルトの名無しさん
04/09/08 17:50
>> 251-252
有難う。
どうやら、家のCygwinは古いようなので新しいやついれて
ためしてみます。


254:デフォルトの名無しさん
04/09/09 05:26
今日はFranzセミナーですね。終わったら報告キボンヌ

255:名無しさん@
04/09/09 08:26
前から気になってたんですが、CLOSにはコンストラクタってないんでしょうか?

256:デフォルトの名無しさん
04/09/09 09:39
:initformじゃだめ?
だめなら make-instanceをオーバーライド。



257:デフォルトの名無しさん
04/09/09 09:44
gauche-sdl
URLリンク(michaelvess.com)


258:デフォルトの名無しさん
04/09/09 14:42
Win XP + ACL 6.2 + slime 1.0 + Meadow-2.10-dev (ASAGAO)
を使っているんですが、日本語が表示できる設定おしえてください。




259:デフォルトの名無しさん
04/09/10 00:40
>>256、に限らず
:initformと:initargsって何か使い分けるのに明確な基準とかある?
make-instanceをオーバーライドするんじゃなくてmake-fooみたいなのdefunして
その中でmake-instanceして細工したオブジェクト返すのはよくやるけど、CLOS的には
ダサいっすか?

260:デフォルトの名無しさん
04/09/10 07:24
ダサいというより、しっかりドキュメントしとかないと(していても)忘れそうじゃない?
間違ってmake-instance単独で使われたときに検出してエラーを出すようにしないと、
しばらくたって保守するときとかにやばそう。


261:デフォルトの名無しさん
04/09/10 08:10
>>255
> 前から気になってたんですが、CLOSにはコンストラクタってないんでしょうか?
どの言語のコンストラクタを想定しているのか分からないけど、make-instanceが
それにあたのるのかな。あるクラスに固有の初期化はそのクラスに特化した
make-instance(やinitialize-instance, reinitialize-instanceなど)のメソッドを
定義して行います。

>>259 :デフォルトの名無しさん :04/09/10 00:40
> >>256、に限らず
> :initformと:initargsって何か使い分けるのに明確な基準とかある?
スロットオプションの:initformと:initarg、それとクラスオプションの
:default-initargsにはそれぞれ微妙な使い分けの基準となりそうな違いが
あります。

簡単に言ってみると、
:initformは、あるスロットの初期値だけを指定するのに使う。
:initargは、initialization argumentの宣言に使う。
:default-initargsは各スロットの初期値の指定と、初期化メソッド群が
とるinitialization argumentのデフォルト値を一箇所にまとめて指定するのに使う。
つまり、必ずしもスロットの初期化に直接かかわらないものも指定できる。
initialization argumentを宣言したことにはならない。

initialization argument名の宣言がされていると、make-instanceと
その手下である関数が呼び出された時に、引数チェックに引っかからなくなる。

規格のココを読むと書いてあります。
7.1 Object Creation and Initialization
URLリンク(www.lispworks.com)

262:233
04/09/10 23:05:30
gauche Windowsで使う方法がいまいちわからない・・・

ところでこういうCのライブラリのラッパをSchemeで
使えるようにする手順て以下のようなものでしょうか

(1) C でgauche から呼ぶためのdllを作成
(2) gauche から それを呼び出す

(2)の方法が良くわからないのですがCのライブラリに
gaucheからアクセスするのは簡単なのですか?
だとしたら自分で使いやすいようにラッパを作っても
いいんですけどね・・・

263:デフォルトの名無しさん
04/09/10 23:44:32
>>262
Gauche は examples/spigot/ が参考になるかと

264:233
04/09/11 01:41:51
>>263
(2)は define-module, select-module, dynamic-load, provide
の手順でいけるんですね
gauche が理解できる形でstubというのを作ってそこから引っ張るんですね
なんとなくわかったような・・・

@GOSH@ ってのは そのstubというのをつくるコマンドですか?
GOSH getstub $<
スタブとか言葉は聞いたことあるけど実はあんまりわかってないw

265:264
04/09/11 16:06:15
gauche インストールしました
gosh ってgouche のリスナーの名前だったんですね・・・
お恥ずかしい


266:デフォルトの名無しさん
04/09/11 22:18:30
>>258
(process-send-string proc (string-make-unibyte string))
string-make-unibyte してちゃ日本語は無理だよな。
さて、どうするか

267:デフォルトの名無しさん
04/09/12 00:16:38
>>258 266
とりあえず、次ので日本語できたっぽい。
Mac OS X, OpenMCL でだけど
diff -r1.397 slime.el
1430c1430
< (set-buffer-multibyte nil))
---
> (set-buffer-multibyte t))
1439c1439,1440
< (let* ((msg (concat (slime-prin1-to-string sexp) "\n"))
---
> (let* ((msg0 (concat (slime-prin1-to-string sexp) "\n"))
> (msg (encode-coding-string msg0 'euc-jp-unix))
1442c1443
< (process-send-string proc (string-make-unibyte string))))
---
> (process-send-string proc string)))
1502c1503,1504
< (let ((string (buffer-substring start end)))
---
> (let* ((string0 (buffer-substring start end))
> (string (decode-coding-string string0 'euc-jp-unix)))


268:デフォルトの名無しさん
04/09/12 01:00:18
うおおお
sortがでけた

269:デフォルトの名無しさん
04/09/12 16:27:08
Corman Lispの作者のCormanさんから宣伝メールが来たよ。
Lispの処理系売って食ってくというのは苦労してるんかね。
とにもかくにも日本語がちゃんと扱えないことにはねえ。


270:デフォルトの名無しさん
04/09/13 16:15:43
前から思っていたんだけれど、
スペシャルフォームをファーストクラス・オブジェクトにすることはできない
だろうか?
スペシャルフォームを引数にとったり、関数の戻り値としたりできないだろうか?

> or
<#special form>  <-- 通常なら syntax error
> (or #f 3)
3

こんな感じで、スペシャルフォームが単独で入力されても文法エラーに
ならないようにすれば、うまく行くような気がするのだけど、どうでしょう?

271:デフォルトの名無しさん
04/09/13 16:32:46
>>270
Gaucheだとできてしまう。

gosh> set!
#<syntax set!>
gosh> define
#<syntax define>
gosh> (define hoge #f)
hoge
gosh> (set! hoge define)
#<syntax define>
gosh> (hoge x 1)
x
gosh> x
1


272:270
04/09/13 16:37:59
ええー!Gauche って便利なのね。すごーい!

と言うか、なんで PetiteChezScheme だとできないのだろう??
何か不都合があるのでしょうか?
使えるほうが、絶対便利だと思うのだけど。

273:270
04/09/13 16:55:53
すると Gauche では、こんなこともできちゃうのでしょうか?

gosh> ((lambda (x y) (x #f y)) or 3)
3

スペシャルフォームは、car の位置にきたときだけ機能するようにすれば
こういう書き方も ok だと思うのだけど。

274:デフォルトの名無しさん
04/09/13 16:56:18
もはやGaucheは、かつてgccがCじゃなかったくらいにschemeじゃない気がする。
gccの場合はしばらくしたら標準が追い付いてきたので、
schemeもあと十年くらい待てば>>270みたいのが標準で使えるようになるかもよ。


275:デフォルトの名無しさん
04/09/13 17:01:39
>>273
やってみた。

gosh> ((lambda (x y) (x #f y)) or 3)
*** ERROR: invalid application: (#<syntax or> #f 3)
Stack Trace:
_______________________________________
gosh> (let ((hoge or)) hoge)
#<syntax or>
gosh> (let ((hoge or)) (hoge #f 3))
*** ERROR: invalid application: (#<syntax or> #f 3)
Stack Trace:
_______________________________________

意外とよわよわだったな、Gauche……。


276:270
04/09/13 17:17:52
>>275
あれれ、残念。
shiro さん、もし見てたら、ご検討お願いします。

277:デフォルトの名無しさん
04/09/13 17:18:15
guile> ((lambda (x y) (x #f y)) or 3)
3

できました

278:270
04/09/13 17:20:20
>>277
おお!さすが何でもありの Guile!

279:デフォルトの名無しさん
04/09/13 19:01:09
それにしても、こんなに便利そうなのに、どうして標準になっていないのだろう?
何か問題があるのだろうか?

280:デフォルトの名無しさん
04/09/13 19:59:08
そりゃSchemeが便利ならなんでもありとは対極にあるような言語だからだろ


281:デフォルトの名無しさん
04/09/13 20:17:07
マクロの展開についての根深い対立が…。

282:デフォルトの名無しさん
04/09/13 20:32:55
夢の中で問題点を一つ思い付いた。関数はまず全部の引数を評価してしまうが、
syntaxはそうではない。わかりやすいところではand, or, begin, ifなど。

(define foo #f)
(or #t (begin (set! foo 3) foo))
とこれ↓を比べてね:
((lambda (x y) (x #t (begin (set! foo y) y))) or 3)

そう考えるとトップレベルでのみ別の名前に束縛できるというのは
それなりに意味があるかも。
しかしguileだと後者も難なくこなしてしまうようだ。どうなっとるんだ。

guile> (define foo 1)
guile> ((lambda (x y) (x #t (begin (set! foo y) y))) or 3)
#t
guile> foo
1
guile> ((lambda (x y) (x #t (begin (set! foo y) y))) and 3)
3
guile> foo
3

きっと、こんなことやってるからguileは遅いんだな……。


283:デフォルトの名無しさん
04/09/13 20:34:59
>>279
(or a b) はaがtrueならbが評価されないってところが大事なところでしょ。
手続きとして使いたければormapとかanyとかあるわけだし、自分でも作れる
わけだし。
構文は、実行前に意味が確定できることが肝なんであって、>>277みたいのを
標準にする意義がわからん。




284:270
04/09/13 20:45:37
>>282
すばらしい!Guile のその挙動こそ、私が望んでいたものです。

>>283
それが、『Scheme手習い』の「lambdaは最高だ」に、スペシャルフォームを引数に
取れたら非常にシンプルに書けるような例が出ていたのです。
(実際はできないから、本では相互再帰を行って何とか解決していた)

285:270
04/09/13 20:48:12
>>282
Guile の実装はぜんぜん知りませんが、
きっとスペシャルフォームを実行するのは car の位置に来たときだけ、という
ルールでやっているのじゃないかなあ。

そんなに速度も落ちないのじゃないかと思うのだけど。

286:デフォルトの名無しさん
04/09/13 21:36:01
実行時に展開と評価時に展開じゃ速度にかなり違いが出るような気が。

287:デフォルトの名無しさん
04/09/13 21:41:43
"special formを実行する" のは構文を parseするときではないのか?

>>277みたいなのは parseするときに決まってないんだからだめじゃん。

Haskellの世界にでもくれば shortcutなんかわざわざ意識しないでいいよ :-)


288:270
04/09/13 22:02:21
うー、そういう問題があるのですか…。

スペシャルフォームを引数に取れると便利だという例をちょっと
書いてみました。
関数と違い、すべての要素を評価しないスペシャルフォームなので、
途中で結果がわかれば、リストを最後まで評価せずに止まります。

テストはしておりませんので、バグっていたらごめんなさい。

;関数を返す関数。引数に and か or を取る。
(define make-function
 (lambda (s-form)
  (lambda (list0)
   (s-form (atom? (car list0))
       ((make-function s-form) (cdr list0))))))

;リストにアトムが含まれるか?
(define has-atom? (make-function or))

;リストの要素がすべてアトムか?
(define all-atom? (make-function and))


289:270
04/09/13 22:03:35
もしかして、Haskell のように遅延評価がデフォルトだと、
スペシャルフォームのほとんどは不要になるのでしょうか?

290:デフォルトの名無しさん
04/09/13 22:14:28
>>274
標準 (R5RS) では未定義あるいは実装依存とされている領域を利用しているだけだから
scheme ⊃ Gauche だよ

291:デフォルトの名無しさん
04/09/13 23:13:29
ふと気づいたのだけど、マクロもスペシャルフォームの一種だよね?
Guile って、マクロも実行時に展開しているんだろうか?
だとしたら、遅いのも道理だなあ…。

どなたかGuileユーザの方、確かめていただけませんか?

292:デフォルトの名無しさん
04/09/13 23:34:50
guile> (define-syntax my-or
    (syntax-rules ()
     ((_ x y) (or x y))))

guile> ((lambda (s-form y) (s-form #t (display y))) my-or 3)

これを試していただけませんか?
#t が返ってくるなら、マクロを実行時に展開していると思う。


293:デフォルトの名無しさん
04/09/14 00:00:24
>>292
Unbound variable: define-syntax
とか怒られた。

294:デフォルトの名無しさん
04/09/14 00:06:55
あれ?当然エラーは 2つ目の式で出たんですよね?
1つ目のdefine-syntax の式の実行で出たのではないですよね?

するとやはり Guile は他と同じで、パース時にマクロを展開するのかな?

295:293
04/09/14 00:14:21
>>294
ごめん。(use-syntax (ice-9 syncase))忘れてた。
2つめの式で
ERROR: invalid syntax my-or
って出た。

296:デフォルトの名無しさん
04/09/14 01:24:16
了解。いずれにせよ、マクロ展開は実行時ではなく、解釈時なのね。
どうもありがとう。

そうしてみると、first class objectとして扱える special form はGuile の
場合、システム組み込みのものだけなのか。
ユーザ定義のマクロと、システム組み込みの special form を区別せずに扱えるのが
Lisp の良さの一つなのに、これでは価値半減だなあ。
実行してみるまで区別がつかないから、わかりにくいバグの元にもなりそうだ。

これなら、special form に別名を付けることしかできない Gauche の方が現実的な
落としどころのような気がする。

special form を first class として扱うためには、マクロ展開を実行時に行っても
構わないような、マシンパワーのあまりある時代を待つしかないのかもしれない。

297:デフォルトの名無しさん
04/09/14 01:28:42
まてよ。Gauche でも、マクロには別名は付けられないよね?
(define new-or my-or) は syntax error になると思う。

すると、ChezScheme のように、special form を一切拡張しないのが一番
現実的なのだろうか。何か寂しいなあ。

298:デフォルトの名無しさん
04/09/14 01:39:04
Gaucheではできる。Gaucheでは、コンパイル時に(手続き呼び出しではなく)
マクロだとわかるものならマクロ展開をしてくれるし、マクロの名前は
マクロそのものを返す。(define new-or my-or)も可能。

syntax classをapplicable objectにして、実行時に展開したら
おもしろいかも。evalが必要になるし、トップレベル以外の環境は
取得できないから無理だろうけどさ。

299:デフォルトの名無しさん
04/09/14 05:00:28
>>270
そういうのはマクロでやる。
実際、make-functionのコンパイル時にはs-formが構文かどうかは
わからないわけだから、コンパイラは ((make-function s-form) (cdr list0))
を評価してからs-formを呼ぶってコードを出すしかないじゃん。

>>287
Lazyなセマンティクスなら評価順の問題は出ないけど、「構文を
パラメタライズする」っていうのはもっと広い問題を含んでる。
Haskellでも、構文要素である '\' や '=' を関数引数として
渡すわけにはいかない。
構文のパラメタライズってのはメタプログラミングしてることになる。
Lispではマクロがメタプログラミングの道具。



300:270
04/09/14 10:38:48
>>298
やっぱり Gauche はバランスがよく取れているということなのでしょうか。


>>299
そうか!マクロか!と思って、さっそく>>288 のコードをマクロ化してみました。

;元の関数
;(案の定バグがあった(停止しない)ので修正してある。)
(define make-function
 (lambda (s-form null-value)
  (lambda (list0)
   (if (null? list0)
     null-value
     (s-form (atom? (car list0)
         ((make-function s-form null-value) (cdr list0))))))))

;マクロ化したもの
(define-syntax make-function
 (syntax-rules ()
  ((_ s-form null-value)
   (lambda (list0)
    (if (null? list0)
      null-value
      (s-form (atom? (car list0))
          ((make-function s-form null-value) (cdr list0))))))))

そうしたら、マクロ展開が停止しないんです。再帰的定義なのに停止条件がないから。
この場合、どう書いたらよいのでしょうか?ヘタレですみません。

301:270
04/09/14 13:12:00
『On Lisp』邦訳 10 マクロのその他の落し穴 10.4 再帰(P81)を読んでみました。
思ったより、解決は難しそうです…。

302:デフォルトの名無しさん
04/09/14 15:30:55
>>300
> やっぱり Gauche はバランスがよく取れているということなのでしょうか。

つーより、事前にコンパイルするんじゃguileみたいな挙動は不可能じゃね?
S式をそのまま解釈実行するのでないと。当然その場合実行速度は遅くなる。


303:デフォルトの名無しさん
04/09/14 15:58:30
なんか似たような話を見たことあるなあ……と思ってたんですが、
これなんか参考になりませんか? Common Lisp だけど。

URLリンク(home.comcast.net)

304:デフォルトの名無しさん
04/09/14 16:14:46
>>270
実行時の停止条件と展開時の停止条件をごっちゃにしてると思われ。
停止を実行時に判断するなら、ループは実行時手続き呼び出しになる。

(define-syntax make-function
(syntax-rules ()
((_ s-form null-value)
(rec (f list0)
(if (null? list0)
null-value
(s-form (atom? (car list0))
(f (cdr list0))))))))

recはsrfi-31ね。letrecを使ってもよい。

停止を展開時に判断する場合は、実行しないでも停止条件がわかる
ことが必須。たとえば引数がリテラルリストで与えられているとか。
その場合はsyntax-rulesで再帰を書けばいい。

(syntax-rules ()
((_ s-form null-value val0)
(s-form (atom? val0) null-value))
((_ s-form null-value val0 val1 val2 ...)
(s-form (atom? val0)
(make-function null-value val1 val2 ...))))







305:270
04/09/14 22:43:09
ありがとうございました。言われてみれば『On Lisp』そのままの話でしたが、
具体的に書いていただくまで分かりませんでした。お恥ずかしい。

rec という構文は初めて知りました。
ChezScheme ではそのままでは動かなかったので、少し変えました。

;; rec 版
(define-syntax make-function
 (syntax-rules ()
  ((_ s-form null-value)
   (rec f
    (lambda (list0)
     (if (null? list0)
       null-value
       (s-form (atom? (car list0))
        (f (cdr list0)))))))))

;; 名前つきlet (letrec)版
(define-syntax make-function
 (syntax-rules ()
  ((_ s-form null-value)
   (lambda (list0)
    (let loop ((list0 list0))
     (if (null? list0)
       null-value
       (s-form (atom? (car list0))
        (loop (cdr list0)))))))))

(define has-atom? (make-function or #f))

(define all-atom? (make-function and #t))

306:270
04/09/14 23:26:58
今回は本当に勉強になりました。
今まで、special form が first class でない理由がずっとわからなかったの
ですが、答えはこうだったのですね。「マクロがあるから」

first class というのは関数抽象に関する概念で、special form は構文であるから、
そこには収まらない。それを扱うのは構文抽象の手段であるマクロ。

漠然としていますが、こういう理解でよろしいでしょうか。

以前 ruby の matz 氏が、マクロでできることはほとんど高階関数でできてしまう
と言っていましたが、決してそうではないですね。

今までマクロと言うと、パワフルだが汚いという負のイメージが強かったのですが、
今回それが変わりました。むしろ、関数抽象と補い合って Lisp の総体を支える
本質的なものだと感じました。今後もっとマクロを深く知りたいです。

ありがとうございました。

307:デフォルトの名無しさん
04/09/15 01:29:34
高尚なネタで盛り上がってるとろこスマン。
BKNL,TBNL,IMHO,UncommonWeb,AllegroServe+WebActions,CL-HTTPといろいろある
ウェブサーバ on CLなモノタチのなかでこのスレ住民のお勧めはどれなのか教えて欲しい。
できれば理由も。処理系はACLかCMUCLの予定です。

308:デフォルトの名無しさん
04/09/15 10:05:40
>>307
おれも知りたいな
ACL の WebAction はセミナー聞いただけだと
そう良くも悪くもなさげだった、ほとんど Apache Struts の焼直しって感じだけど
他のも Web 「アプリケーション」サーバーなのかしら?



309:デフォルトの名無しさん
04/09/16 00:57:02
スレの内容が高度すぎる…
初心者スレは良かった…

310:デフォルトの名無しさん
04/09/16 04:28:41
ちっとも高度じゃないよ。
分からないうちは飛ばしとけ。

311:デフォルトの名無しさん
04/09/16 10:42:55
>>309
大丈夫。あきらめなければそのうち、ちゃんとわかるようになるから。
シンプルなのが Lisp の身上。
スレの過去ログの、昔読んで分からなかったところが、少したつととても面白く
読めるようになります。経験者は語る。

-------------------
新山氏の日記に、久しぶりに Lisp のことが書かれている。
URLリンク(tabesugi.net)

新山氏は相変わらず冴えてます。読んで「うわー、そういう感じ、よく分かる」
と思った人も多いのではないだろうか。

312:デフォルトの名無しさん
04/09/16 13:59:44
>>306
> マクロでできることはほとんど高階関数でできてしまう

そこで高階関数と言っているのは、評価したくないコードブロックをラムダで
括ってしまうということを言ってるわけで、>>300 の前半の関数版に対して

;リストにアトムが含まれるか?
(define has-atom? (make-function (lambda (a b) (or a b)) #f))

と書けばよい、ということじゃない?


313:デフォルトの名無しさん
04/09/16 15:44:06
>>311
>「うわー、そういう感じ、よく分かる」
Lisp側から見て? それともPython側から?
ちなみに俺はSchemeもPythonも好きで両方使ってるけど,
Lisp側の意見はあまり共感できないなぁ.(マクロまんせーには同意するけど)

314:311
04/09/16 15:56:34
>>312
確かに引数として与えたとき or は評価されないけれど、has-atom? の内部で
or ではなく、or に似た働きの関数になっちゃうでしょ? or に与えたい引数
の両方をまず評価してしまうから、リストを最後まで評価しないと止まらない。

>>313
Python 側。と言うか、外から見た Lisper の雰囲気。(私は Python 知らないので)

315:312
04/09/16 16:42:23
>>314
あーそうか

(define make-function
  (lambda (operator null-value)
  (lambda (list0)
  (if (null? list0)
  null-value
  (operator (lambda () (not (pair? (car list0))))
  (lambda () ((make-function operator null-value) (cdr list0))))))))

(define has-atom? (make-function (lambda (a b) (or (a) (b))) #f))

こんな感じでどう?もしかしてまた勘違いしてるかな


316:デフォルトの名無しさん
04/09/16 18:15:12
>>315
今度はOK。つうか、煩雑で最初はよく分からんかった。
分かりやすいよう、遅延評価に直せるところを書き直してみた。
(かえって分かりづらい?)
やっぱりマクロのほうが分かりやすいと思う。

;;遅延評価版
(define make-function
 (lambda (operator null-value)
  (lambda (list0)
   (if (null? list0)
     null-value
     (operator (delay (atom? (car list0)))
          (delay ((make-function operator null-value) (cdr list0))))))))

(define has-atom? (make-function (lambda (a b) (or (force a) (force b))) #f))


それにしても、関数型言語方面の人が「Lispで遅延評価など書いておれるか!」と言ってるけど
気持ちがわかったような気がする。やっぱり煩雑だよね、これ。

317:デフォルトの名無しさん
04/09/16 19:14:58
リストの評価が途中で止まるのは、いずれもspecial form である or のおかげ
なのだから、or をそのまま渡せるマクロのほうが、はるかに自然。

or に仕事をさせるために、lambda や delay で囲んで、引数の強制的な評価を
回避させなければならない高階関数は冗長。

318:デフォルトの名無しさん
04/09/16 19:23:34
細かい話だけど、それぞれ1個目の delay と force 、要らないじゃん。

319:デフォルトの名無しさん
04/09/16 22:43:03
special-formをfirst-classにするってことは,
実行時にマクロ展開を行わせることになるよね.
そうすると静的スコープがグチャグチャになるような,ならないような….
あぁ,メタメタしてワケ分からん.

ところで,暗黙のforceを実装した処理系ってある?
暗黙のforceを実装してれば,遅延評価版>>316とかは,delay一つでよくなる.

320:312
04/09/17 00:45:57
>>318
そうだね、 or の第一引数はかならず評価されることが決まってるから
delay する必要はないのか

>>316-317
冗長で分かりにくい、こんなコード書きたくも読みたくもない、というのはもちろん同意。
今回意地になってしまったのは >>306

> 以前 ruby の matz 氏が、マクロでできることはほとんど高階関数でできてしまう
> と言っていましたが、決してそうではないですね。

に反論したくなっただけdeth。テヘ


321:デフォルトの名無しさん
04/09/17 09:16:08
>>320
> 以前 ruby の matz 氏が、マクロでできることはほとんど高階関数でできてしまう
> と言っていましたが、決してそうではないですね。

これ,orとかの評価を遅延させるためのマクロのことを念頭に置いてるんですかね.
「できる」と「やりやすい」は違うし,だいたい,できないこともおおいじゃん...

322:デフォルトの名無しさん
04/09/17 11:56:01
やりやすくないとやりたくない.

323:デフォルトの名無しさん
04/09/17 13:39:34
>>321
マクロでしかできないことってどういうものがありますか?
マクロは興味はあってもとっつきにくいなあと思っています。
教えてもらえるとイメージが湧くかも。


324:321
04/09/17 13:57:18
URLリンク(www.shiro.dreamhost.com)
マクロの応用方法を分類して解説しているので,参考になるのでは.

「宣言的コードにみせる」や「ミニ言語のうめこみ」あたりが
美しいマクロの使い方だとおもいます.

325:デフォルトの名無しさん
04/09/17 14:19:47
>>321
まさに去年の今頃、似たような話をしていた記憶が。懐かしい。
ちなみに matz 氏の発言ていうのはこの辺。
URLリンク(www.rubyist.net)

何となくだけど、matz 氏の意図しているところは
「dolist って for-each でいいじゃん?」ていう程度の話な気がする。
遅延評価がどうとか call-by-name がどうとかってところまでは風呂敷は広げてない感じ。

326:321
04/09/17 14:38:04
ああ,これって算符の記でやってた議論なんですね.しらなかった(赤面)
両者のスタンスの違いがよくわかりますた.


327:デフォルトの名無しさん
04/09/17 22:04:43
評価を遅延させるだけの目的でマクロを使うのはよくないと思う.
引数が評価されるかどうかが定義を見ないと判らないわけで,
むしろ可読性を損なっている気がする.
マクロはマクロを使わないとできないこと,例えばdefineを拡張して
パターンマッチできるようにするとか,そういう目的で使うべき.

328:デフォルトの名無しさん
04/09/17 23:35:35
Common Lisp使ってCみたくメモリ上のビット単位まで意識したコードって簡単に
書けますか? 書けるとしたらその方法が知りたいです。memory mapped I/Oの操作
みたいな低レベルな操作ができるのかな、ってのと、やっぱりそんな処理はCでヤレ、
そもそもLisp使ってやる内容じゃないだろ、って結論しかないのかを教えてくれるとうれしい。

329:デフォルトの名無しさん
04/09/18 01:26:48
素人でスマンが、Cで簡単に拡張ライブラリが書けるような
Lisp処理系を使う、って答えになるんじゃなかろうか。

330:デフォルトの名無しさん
04/09/18 01:33:48
最近の主なLisp処理系ならFFIでCのコードを呼べて楽よ。
>>328みたいなこともやればできそう。
でも分野的に、Cで書く方が直感的でメンテもしやすい気がしなくもないので、
そういうコードをCで書いてFFIで使うというのがいいんじゃないかい。




331:328
04/09/18 02:36:20
レスどうもです。やっぱりFFI使ってCで書くのが定石なんですね。
Cltl2眺めててbit-vectorのオブジェクトの存在するアドレスを物理メモリにマップできれば
もしかして・・・と思ったのですが違ったようです。LispMachineとかだとできたのかなぁ。
データの圧縮とかビットマップインデックスみたいに素のLispが提供していないメモリ上のデータ構造を
ゴリゴリ扱いたいなぁ、と思ったらLisperの取る道はFFIしかないんですかね。それともマクロで
抽象化してarray :element-type (unsigned-byte 32)の上で操作するのでしょうか。

332:デフォルトの名無しさん
04/09/18 03:06:04
物理メモリにmapするには、もひとつOSの助けも必要だと思われ。
Linuxはユーザ空間にmemory mapped I/Oをmapできたんだっけか。
ユーザ空間にI/OをmapするAPIと、具体的な仮想アドレスのreferenceを
取得できるAPIをFFIで書いたらできるのかな。


333:デフォルトの名無しさん
04/09/18 03:26:40
結局そういうインタフェース作ったとして問題は参照方法だろ
さすがにメモリ走査とかはポインタないと辛い
Cでやった方が全然楽だし速いよ

(let (ptr (make-integer-ptr mem)) ;; ポインタの作成
(ref ptr) ;; 参照
(deref ptr value) ;; 逆参照
(inc ptr)

こんなことやってられっか?
実際は型の問題もあるし、もっと煩雑になる
そもそも演算子がないのが痛い

int *ptr = mem; // ポインタの作成
&ptr; // 参照
*ptr = value; // 逆参照
++ptr;

やっぱ記述量が割に合わない

334:デフォルトの名無しさん
04/09/18 03:35:32
餅は餅屋

335:328
04/09/18 03:55:28
はぅあ。袋叩きにあってしまいましたな。記述量が割に合わないとかLisp向きじゃないよなぁ
とは思いながらも知らない世界があるかも程度の好奇心で聞いただけなのでした。

>>334 餅は餅屋
御意。いまも仕事でLispのコード書いてたんだけど、Lispで書いてるととにかく楽なんで
何でもかんでもLispで書けないかなとか思った私が阿呆でした。
どうでもいいけど、みんなこんな時間まで何やってんの?皆もデスマ?

336:デフォルトの名無しさん
04/09/18 04:01:40
Schemeで名前空間で名前を分類するようなことをしたいのですが、どういう方法を
取ればよいのでしょうか?
C++でnamespaceでモジュール全体を囲って名前の衝突が起きないようにして、
using namespaceで名前空間を使うというようなことです。
名前空間を階層化したりもしたいのです。


337:デフォルトの名無しさん
04/09/18 04:22:51
標準的な方法はないから
toplevelをletか何かで包んで必要な名前だけ外部に出すとか

(define proc1 #f)

(let ()
(define (proc1-sub1) ... )
(define (proc1-sub2) ... )
(set! proc1 proc1-sub1)) ;; export

あとは処理系依存だから、付属のマニュアルでも嫁

338:デフォルトの名無しさん
04/09/18 05:32:43
>>328
>>338 の言う通り、やってできなくはないと思う。mapしたアドレス値を
取得するのと、そのアドレスにアクセスするプリミティブは処理系
依存になるが。だがCでポインタを扱いなれてると、Lispでのアクセスは
冗長だね。マクロが使えることはメリットだけど。



339:デフォルトの名無しさん
04/09/18 09:28:32
>>336
処理系依存でよければmoduleシステムやなんやらを使うのがいいでしょう。

どうしてもportableでやりたいなら、top levelの束縛を変更する関数を
マクロで置き換えて、ほげほげとか。
って、top levelの束縛をマクロにするのはR5RS的にはだめなんだっけか...

340:デフォルトの名無しさん
04/09/18 10:40:21
スペースで区切られたテキストが以下のようにあったとして
A B C
D E F
↓(変換)
A
D

B
E

C
F

みたいな文章に整形するプログラムを作ろうと思ったのですが
いまいちエレガントにかけません
読み込むテキストファイルを"test.dat"として
以下のように書きました

(with-open-file (in "test.dat" :direction :input)
(let ((buff)
(str1)
(str2)
(str3)
(vstr))
(while (setq buff (read-line in nil))
(setq vstr (split-string buff "\t"))
(setq str1 (concatenate 'string str1 (first vstr) "\n"))
(setq str2 (concatenate 'string str2 (second vstr) "\n"))
(setq str3 (concatenate 'string str3 (third vstr) "\n")))
(format t "~A\n~A\n~A\n" str1 str2 str3)))

誰かアドバイスください・・・

341:デフォルトの名無しさん
04/09/18 13:02:49
縦読みデコーダでも作るの?


342:340
04/09/18 13:15:05
>>341
そんな大層なものではなくて
練習用に書いているのですが・・・

上の例では3列と固定しているところを可変で
対応できるようにしたいのです
str1,str2,str3 とかやるのは格好悪いし・・
もっとすっきり書けませんかね?

343:デフォルトの名無しさん
04/09/18 13:32:22
下のコードはヒントにならない?
(mapcar #'list '(a b c d e) '(3 4 5 6 7))
=> ((a 3) (b 4) (c 5) (d 6) (e 7))



344:340
04/09/18 15:24:32
>>342
有難うございます
で、さっそく以下のように書いてみたのですが、
結果が nil になってしまいます

(defun util (fname)
(with-open-file (in fname :direction :input)
(let ((buff)
(output))
(while (setq buff (read-line in nil))
(setq output
(mapcar #'list output (split-string buff "\t"))))
(mapcar #'(lambda (s) (format t "~A\n" s)) output))))

(util "test.dat")
nil

なぜ nil になってしまうのでしょうか?

345:デフォルトの名無しさん
04/09/18 16:18:32
whileの返り値

346:デフォルトの名無しさん
04/09/18 18:07:39
(defmacro for ((var start stop) &body body)
 (let ((gstop (gensym)))
  `(do ((,var ,start (1+ ,var))
     (,gstop ,stop))
     ((> ,var ,gstop))
   ,@body)))

これはOnLispに載っている "正しいforマクロ" (図42)
ですが、このgensymの例が何故正しいのかよくわかりません。

bodyの中にフリーなgstopが出てきたらやはり名前衝突を
起こしてしまう気がするのですが、私は何か勘違いして
いるのでしょうか。

347:デフォルトの名無しさん
04/09/18 18:16:40
>>344
(mapcar #'list nil '(1 2 3)) => nil だよ
まず output として '((A B C) (D E F)) を作ってこれを '((A D) (B E) (C F)) に変換する
と思えば良いんじゃない?
あんま考えてないけど↓
(defun util2 (output result)
(if (car output)
(util2 (mapcar #'cdr output) (cons (mapcar #'car output) result))
(reverse result)))

>(util2 '((A B C) (D E F)) '())=>((A D) (B E) (C F))


348:デフォルトの名無しさん
04/09/18 18:45:50
gensymはinternされない (システム内部の、名前からシンボルへの
対応表に登録されない) シンボルを作るので、このマクロの展開時に
作られるシンボル (#:G0031とか) と同じシンボルを外から与えることは
できない。(同じ名前にしてもシンボル自身は別オブジェクトなので
衝突しない)



349:340
04/09/18 18:56:21
nil にリスト追加してもnilなんすね
また修正してみました
途中経過ですが・・・
(with-open-file (in "test.dat" :direction :input)
(let((buff)
(output '()))
(while (setq buff (read-line in nil))
(if (null output)
(setq output (split-string buff "\t"))
(setq output
(mapcar #'list
output
(split-string buff "\t")))))
output))

としたら2行だと上手くいきますが => ((A D) (B E) (C F))
3行目からは(((A D) G) ((B E) H) ((C F) I))
となってしまふ・・・
<<347 のように今度は再帰で考えて見ます

350:デフォルトの名無しさん
04/09/18 19:24:40
>>348
ああそうか!
` が付いて無いからマクロの展開時に (let) は消えるんですね
納得・・・ありがとうございました

351:340
04/09/18 19:48:28
ようやく上手くいきました
良いLISPの勉強になりました

(defun util (filename)
(with-open-file (in filename :direction :input)
(let
((buff)
(output))
(while (setq buff (read-line in nil))
(if (null output)
(setq output (split-string buff "\t"))
(setq output
(mapcar #'(lambda (v1 v2)
(if (listp v1)
(append v1 (list v2))
(list v1 v2)))
output
(split-string buff "\t")))))
output)))

知恵を下さった皆さん有難うございました
もっとエレガントにいけるとかあったら
ぜひ教えてください

352:ミミ
04/09/19 10:40:16
Scheme の継続と、Win32 API のウィンドウ プロシージャ コールバック
って、共存可能だと思いますか?

353:デフォルトの名無しさん
04/09/19 11:07:15
不可能な理由がなかったら可能だよ。

354:& ◆TACpYgPjX6
04/09/19 11:17:07
それがよくわからないんですよ。
だって、OS 側でどんな処理をしているか分からないじゃないですか。

たとえば WM_KEYDOWN ハンドラ内で継続を作成して、
一度そのハンドラを終了して OS に制御を返すでしょ。
そのあと WM_LBUTTONDOWN ハンドラ内で
先ほどの継続を呼び出すと、WM_KEYDOWN メッセージの処理が
再開されるわけですよね。

OS 側でスタック上のデータではない
グローバル変数をいじっていたとすると、
コンテキストがめちゃくちゃになって、
よくない気がするんです。

355:デフォルトの名無しさん
04/09/19 11:26:55
> OS 側でどんな処理をしているか分からない

分からない以上、可能だという確認ができないんじゃないか?

356:ミミ
04/09/19 11:31:53
いえいえ、今の私の知識ではわからないということなんです。
どなたか深い知識をご存知の方はいらっしゃらないかなと思いまして。

357:デフォルトの名無しさん
04/09/19 11:33:02
354の話で使いたい場面と、問題意識が少しわかったので
もう少し整理してから、その問題意識を中心に調べものしたらわかるのではないかな。
イベントハンドラまわりなんだよね。
;;; Windowsのことはよく知らないけど...


358:& ◆TACpYgPjX6
04/09/19 11:36:15
実は Windows 専用 Scheme を作りたいと思っているんです。
特にシステム ハックをするためのツールを
Scheme でガンガン作りたいんですよねぇ。

コンセプトは
"Scheme as a better C."
"Scheme as a hacking tool."

359:デフォルトの名無しさん
04/09/19 11:50:34
で?

360:ミミ
04/09/19 11:51:32
協力してくれたらうれしい。
できたら使わせてあげるから。

361:デフォルトの名無しさん
04/09/19 11:54:40
面白そうではあるが,コールバックまで正常動作させようとすると
継続はおろかクロージャさえ厳しいだろうな…

362:& ◆TACpYgPjX6
04/09/19 11:56:17
だいたいですね、Lisp 系の言語って、
どれもこれも Unix っぽいのがよくないと思うんですよ。
Perl や Python も同じなんですけど、
Java はちょっと違う感じ。

Windows みたいな素敵なシステムに、
Scheme みたいな素敵な言語があれば、
みんな幸せだろうなぁ、と思ってさ。

363:ミミ
04/09/19 11:59:09
すいません、どうしてクロージャが難しいのでしょうか。
何も OS が直接クロージャを呼び出すことは期待していないです。
間に C 関数をかませば問題ないですよね?

> 面白そうではあるが,
ありがとう。

364:デフォルトの名無しさん
04/09/19 12:00:52
PythonはMac出身じゃなかったっけ.
まぁ、それはともかく、Unixっぽいってどういうこと?

365:デフォルトの名無しさん
04/09/19 12:13:05
>>363
話の流れからすると,Win32APIを丸々wrapするんじゃなくて,
Cの関数を直接呼び出したりできる機構を用意しようってことだよね?

366:& ◆TACpYgPjX6
04/09/19 12:18:32
一番大きなのは、コンソール (標準入出力) を前提としていること。

あと、いろんな Scheme 処理系をみてみても、
最初にサポートされるライブラリが POSIX ライブラリを移植したものとか、
GNU の readline たら curses たら、
/etc/network の存在を仮定したソケット ライブラリとか (Winsock にしてくれ)、
Windows で使うにはほとんどいらないものばっかりあって、
肝心の Windows 用のライブラリがないんですよ。

レジストリ アクセスや COM バインディングは必須でしょう。
もちろん ウィンドウ プログラミングができないとだめ。
(Unix では X がオプションだから困る)

あと、リソースのアクセスとか、シェル サービスへのアクセスとか、
さまざまな Win32 API をオブジェクト指向的にパックしたものとか
Win32 のセキュリティ機構は Unix と大きく異なっているから、
それを無理やり Unix 的に狭めても、使う気になれない。

Scheme だけで DLL を書くとか、サービス書くとか、
スクリーン セーバー書くとか、Scheme だけでデバドラ書くとか。
そんなのができない。

しようとすると、既存の Scheme に拡張機能を実装しないとだめで、
その Scheme 実装系の内部動作から把握しないとだめってことになる。
しかも Scheme 実装系自体が Unix を基盤としているので、
Windows 用に最適化されているわけでもない。

であれば、Windows 専用の Scheme 実装の上に
Windows 専用のライブラリを構築するほうが
ずっといいと思う。

367:デフォルトの名無しさん
04/09/19 12:27:13
うーん、Scheme.NETか?

368:ミミ
04/09/19 12:28:34
>>365
> 話の流れからすると,Win32APIを丸々wrapするんじゃなくて,
> Cの関数を直接呼び出したりできる機構を用意しようってことだよね?

構想としては WIn32 API (というか任意の DLL 関数)
をすべて生で呼び出し可能にしたいとは
思っています (間に多少のサンクは入ってもよし)。

VB の Declare 文みたいに、Scheme ソース上で
宣言するだけで、外部の API を呼び出したいです。

たとえば、
(dll-import MessageBox
((DWORD hwnd)
(WSTR text)
(WSTR caption)
(UINT type))
(alias "MessageBoxW"
stdcall)
)
という感じで宣言して、
呼び出すときは
(MessageBox 'hwnd hwnd
'text "テキスト"
'caption "キャプション"
'type (| MB_OK MB_ICONINFORMATION) )

コールバックの話は、ウィンドウを使いたいために出てきた話です。
ウィンドウを使うには OS からのコールバックとして実装しなくてはならず、
その場合、継続と相性悪くないのかなぁ、とふと思ったのです。

369:デフォルトの名無しさん
04/09/19 12:34:50
>>366
> であれば、Windows 専用の Scheme 実装の上に
> Windows 専用のライブラリを構築するほうが
> ずっといいと思う。
そういうことは、既存Scheme処理系をWindowsに移植しようとして
挫折してからいうべきなのではないか。先人の知恵は偉大だよ。
;;; 挫折というのは移植者の能力不足のことではないよ。

あ、もしかして、scheracy?

370:& ◆TACpYgPjX6
04/09/19 12:37:25
>>369
>あ、もしかして、scheracy?
え? Scheme ヤラシイ?
なんですかそれは。

371:デフォルトの名無しさん
04/09/19 12:40:07
>>367
だよね。他にもあるかも知れないけど、
.NETFramework をサポートする Scheme を開発するプロジェクト

URLリンク(radio.weblogs.com)
URLリンク(www.cs.indiana.edu)

372:デフォルトの名無しさん
04/09/19 12:45:12
チョット前に出てたハンディスキームじゃダメなのか?

373:ミミ
04/09/19 12:49:18
>>371
情報ありがとうございます。一度よく調べてみます。

うーん、私は .NET 勉強してからしばらくたつので、
いろいろ忘れていますが、.NET ってそんなにいいものですかね?

どうも GUI が重ったるいし、C# も VB.Net もなんかシンプルじゃないし、
.NET ライブラリってあんまり洗練されていないような気がするし (MS的ゴテゴテ)、
いじってたらバグがごろごろ出てきたし (もう直ってるだろうけど)
"as a hacking tool" というコンセプトと馴染むでしょうか。

"as a hacking tool" ===> "cool and cute" ですよ?


374:& ◆TACpYgPjX6
04/09/19 12:55:32
>>372
> チョット前に出てたハンディスキームじゃダメなのか?
むむ!
これ、なんだかよさげですね。
こんなのがあったんですね。
ちょっと今日の宿題にしてみます。
ありがとうございます!

375:デフォルトの名無しさん
04/09/19 13:13:42
おぇ

376:デフォルトの名無しさん
04/09/19 13:17:42
"as a hacking tool"
===> "as a hacking tool"

377:デフォルトの名無しさん
04/09/19 14:24:34
なんでハンドル二つ使って常時ageなんだ?

378:デフォルトの名無しさん
04/09/19 14:34:01
Cからのscheme呼出しの中で補足された継続のエクステントが無制限な処理系ってあるの?
GaucheでもCからのコールバックで補足されたもののエクステントはコールバック内に限定されるし

379:デフォルトの名無しさん
04/09/19 15:02:33
>>363
クロージャが難しいというよりはガーベジコレクションが難しそう.
Schemeで書かれた関数をWin32APIに渡して,コールバック関数として登録したとして,
その関数がいつまで使われるかはSchemeインタプリタ側では判別できないと思う.

380:デフォルトの名無しさん
04/09/19 16:06:22
>>377
1. 2ch が Netscape や Mozilla に対応していない。
2. よって、cookie に書き込まれた全角のハンドル名が化ける。
3. あわててハンドル名を入れなおすと、そのときは正しい名前で掲示板に
  書き込まれる。
4. 次に書き込むと、またハンドルが化ける。
5. 以下繰り返し。

Netscape, Mozilla ではハンドルは半角英数にするのが吉。

常時 age については分からない。

381:デフォルトの名無しさん
04/09/19 16:13:53
>>380
> >>377
> 常時 age については分からない。
sage を知らない、だろうな。

382:デフォルトの名無しさん
04/09/19 17:31:16
> Windows みたいな素敵なシステムに、
ここんとこに賛同できないのは漏れだけなのか。s/Windows/MacOSX/だったら同意なんだが。

383:デフォルトの名無しさん
04/09/19 17:42:53
その部分は罠と判断した。

384:デフォルトの名無しさん
04/09/19 17:53:10
>>366
> 一番大きなのは、コンソール (標準入出力) を前提としていること。

なにか大きな誤解をしているような。
Schemeって必ずしもトップレベル環境のreader/writerと標準入出力が結びついている
必要はないでしょ。Dr.Schemeとか触ってみれば? URLリンク(www.drscheme.org)

あとDLLの動的呼び出しそのものはそれほど難しくないと思われ

URLリンク(www.kt.rim.or.jp)
> 共有オブジェクト(Win32ではDLL)を動的にロードし、
> 中の関数をscheme コードから呼び出すことができる。
> さらにコールバック関数をscheme コードで記述できる。


385:デフォルトの名無しさん
04/09/19 22:06:34
DrSchemeって、一応他のエディタで編集してロードすれば、日本語表示できるみたいだな。
例えば、「あ」と言う文字のように二文字目が\と同じコードの場合には「あ\」と、\を余分にくっつけて
\\を\と認識させるという技を使わなくちゃいけないのが面倒だけど。

ランタイムDLLが必要になるがEXEも作れるようだし、俺の中ではDrScheme最強になりつつある。

386:デフォルトの名無しさん
04/09/20 01:04:59
gaucheでhtml解析するときって皆さんどうやってます?
saaxとかつかってます?
それとも自分で解析モジュールを書いちゃいます?

387:デフォルトの名無しさん
04/09/23 02:10:26
やっと cygwin + slib のインスコ完了したよ・・・
なんでこんなに疲れるんだろう

388:デフォルトの名無しさん
04/09/23 11:27:01
>>386 これは? 使ったことないけど。
URLリンク(www.neilvandyke.org)


389:デフォルトの名無しさん
04/09/23 18:33:55
gosh のload-path は add-load-path 以外に方法がないのですか?
毎回指定するの面度印ですけど・・・

390:デフォルトの名無しさん
04/09/23 18:40:08
>>389
command line optionの-I

391:デフォルトの名無しさん
04/09/23 19:04:22
>>368
継続はコールバックに跨らなければ問題ない。
ハンドラからtoplevelに直接行ったりきたりする様な継続の呼び出しは
不可能ではないけど、コールバックを叩くWindows側で何をしているのかわからんから、
こっちはやらない方が良いとは思う。
ちゃんとコールバックに制御を返却する当てがあるなら、たぶん問題なし。
これに関しては結局セオリーみたいのは見つからなかった。

(deine user32 (loadlib "user32.dll" ))
(define DefWindowProc (getproc user32 "DefWindowProcA" __stdcall '(h m w l)))

(define handler (make-callback __stdcall
(lambda (hwnd msg wparam lparam) (DefWindowProc hwnd msg wparam lparam))))
(define (single-window handler) (make-window handler))

自作の処理系ではこういう感じで窓を作成する。
make-callbackでクロージャとC関数をブリッジする以外に特別な物はない。
schemeの様に内部定義を許す言語のメリットはここから。
handlerはclosureそのものなので、関数外の局所変数をあえて引数渡しする必要がなく、
C言語だとグローバル変数に移したり関数で分離していた箇所を一つにまとめることができる。

(define (test foo)
(make-window (make-callback __stdcall (lambda (hwnd msg wparam lparam)
(display foo) ;; ハンドラ外の変数の参照
(DefWindowProc hwnd msg wparam lparam))

この辺の自由度はC言語と比べると比較にならない。(gccはExtensionで関数内関数が
使えるんだけど制限が多く、schemeの様に内関数同士の再帰やコールバック関数にできない。)

ただね、いまんとここれ使って何がしたいって訳でもないので、そのまま放置状態。
とにかく機構そのものより、ラッパとか書くのが面倒すぎて、型変換も適当。

392:& ◆TACpYgPjX6
04/09/23 19:48:16
>>391
> 継続はコールバックに跨らなければ問題ない。
> ちゃんとコールバックに制御を返却する当てがあるなら、たぶん問題なし。
> これに関しては結局セオリーみたいのは見つからなかった。

OS から コールバック A が呼ばれ、そこで継続 ContA を作成して、
トップレベルに束縛したとします。
次に、OS から別のコールバック B が呼ばれ、そこから ContA を呼び出すとします。
ContA を呼び出した直後は別に問題は発生しませんよね。
問題は、ContA を呼び出し後に、コールバック A から呼び出し側に戻って
しまうことが問題なのですよね。

であれば、コールバック A から OS 側に戻ろうとする直前に、
あたかも、コールバック B から戻ったように見せかけることができれば、
いい感じがしませんか?


393:ミミ
04/09/23 19:48:51
具体的な実装方法は、コールバック クロージャ B の
サンクとなる C 関数において、
コールバック開始時の継続をキャプチャしておきます。
また、「コールバック B のコンテキストである」という記録を
g_callbackContext グローバル変数に保持しておきます。

ここで、コールバック クロージャ A のサンクとなる C 関数から
OS 側に戻ろうとするとき、g_callbackContext を確認し、
それがコールバック A のコンテキストであれば、
そのまま OS 側に戻ります。
コールバック A のコンテキストでなければ、
そのコンテキストに対応する継続 (コールバック B 開始時にキャプチャしたもの)
を呼び出すことで、コールバック B のコンテキストを回復した上で
OS 側に戻ります。

少し問題なのは、コールバックの戻り値をどのように決定するかですが。。。


394:デフォルトの名無しさん
04/09/23 20:27:26
>>393
>問題は、ContA を呼び出し後に、コールバック A から呼び出し側に戻って
>しまうことが問題なのですよね。

Scheme の継続って、OS 側のコンテキストすら
捕獲できるほど強力だったか?

根源的に何か勘違いしていないか?


395:& ◆TACpYgPjX6
04/09/23 20:40:39
>>394
実装によってはできますよ。
スタックをすべて記憶する類の実装の場合です。

396:デフォルトの名無しさん
04/09/23 20:48:45
なんでそんなに継続にこだわってるんだ?
コールバックの中で補足した継続にそこまで意味があるとは思えないんだが。
具体的にどういう使いかたを想定しているの?

397:ミミ
04/09/23 21:06:20
いやー、コールバック ベースではない普通の Scheme コードの場合
(C でいう main() プログラム)、継続はどこで作成されたものであっても
自由に使えますよね。

でも、コールバック ベースの Scheme コードの場合
(C でいう WinMain() プログラム)、その継続がどのコールバック内
(「どの」というのは空間および時間で区別しなければならない)
で呼び出されたかを覚えていないとだめですよね。

継続を1つのコールバック内に閉じ込めて使用しなければならないという
この窮屈さを解消したいだけなのですけど。。。

398:ミミ
04/09/23 21:07:40
すいません、間違い。
× で呼び出されたかを覚えていないとだめですよね。
○ で作成されたかを覚えていないとだめですよね。


399:デフォルトの名無しさん
04/09/23 21:10:25
いいかげんsageてくんないかなあ・・・

400:デフォルトの名無しさん
04/09/23 21:22:30
こんなことでぐだぐだ言ってないで、さっさと処理系書いてみれ。
コールバックをまたぐ継続が動かないことくらいすぐ分かるよ。

401:ミミ
04/09/23 21:37:21
>> 400
いや、私がいいたかったのは、そうじゃないんですよぉ。。。
おこんないでくださいよぉ。。

402:デフォルトの名無しさん
04/09/23 21:41:42
具体的に 「こういう使い方すると非常に便利だから絶対使いたい」 というわけでもないのに、
処理系云々の前段階げグダグダいっても意味無いだろ。
実装するにはいろいろ難しい問題があり、汎用的なものにすることは不可能なんだから、
要求が出る前から考えたって良い解法が出るわけがない。
あと、いいかげんsageろ知障。

403:デフォルトの名無しさん
04/09/23 21:43:55
くれぐれもshiroさんとこ行ったりして迷惑かけるなよ

404:デフォルトの名無しさん
04/09/23 21:52:20
汎用的に実装するのはまず無理だろうし,できたとしても
OS側の継続(変な言い方だけど)が戻らないんじゃ意味無し.
が,絶対に無理かと問われると断言できないのが歯痒いというか何というか.

405:ミミ
04/09/23 22:02:04

> 汎用的に実装するのはまず無理だろうし,
うーんと、私はコールバックを超えて継続したいと言っているんではないのですよ。

> OS側の継続(変な言い方だけど)が戻らないんじゃ意味無し
いや、ですから、OS 側の継続を行うのは可能なんですって。。。

> くれぐれもshiroさんとこ行ったりして迷惑かけるなよ
あのう、shiroさんて、誰でしょうか。。。

> あと、いいかげんsageろ知障。
すいません、やっと意味が分かりました。m(_ _)m


406:デフォルトの名無しさん
04/09/23 22:22:17
> コールバック A から OS 側に戻ろうとする直前に、
> あたかも、コールバック B から戻ったように見せかけることができれば、
この時点でOS側の継続は戻ってないと思うんだが

そもそもOSがコールバック関数を呼ぶってのは言わば見せかけであって,
実際にはプロセス間通信なんかが絡んでるの判ってる?

407:デフォルトの名無しさん
04/09/23 22:26:21
>>406
Windows素人は黙ってて欲しいなあ・・・

408:ミミ
04/09/23 22:31:33
>>406
たぶん、私の意図を誤解されています。
実際に OS 側の継続を戻す Scheme 実装系はありますよ。

409:デフォルトの名無しさん
04/09/23 22:33:06
OS のコールバックを跨ぐ事を前提にしているのに、
Scheme 側で生のスタックを使おうとしているのが、
根本的な設計ミスだろ?

普通の Scheme コンパイラで生のスタックを使っていたりするのは、
それが "たまたま" 使えたから。

それを理解せずにスタックに拘る奴は愚かと言う他はない。


410:デフォルトの名無しさん
04/09/23 22:35:34
>>408
> 実際に OS 側の継続を戻す Scheme 実装系はありますよ。

それはどの OS 上のどの実装系?
OS 側のサポートが無い限り setjmp/longjmp 以上のことができるとは思えないんだが。

411:ミミ
04/09/23 22:45:10
> 409
> OS のコールバックを跨ぐ事を前提にしているのに、

ですから、私はコールバックをまたぎたいんではないんですって。
コールバックをまたぐことはできないことは、最初っから分かっているんですよ。
私がやりたいのは、いかに継続をコールバックというしがらみから解放させたように
見せかけるか、という手法なんですよ。

> 普通の Scheme コンパイラで生のスタックを使っていたりするのは、
> それが "たまたま" 使えたから。
> それを理解せずにスタックに拘る奴は愚かと言う他はない。

スタックを記録するタイプの実装を行っている SCM は、
Mac, Win, Linux, BSD, Solaris, AIX, HP-UX, OS/2,
DOS, Amiga, Atari など多くの OS に移植されています。
これほど汎用的に使える手法を"たまたま"と表現することはできないでしょう。


412:デフォルトの名無しさん
04/09/23 22:54:28
>私がやりたいのは、いかに継続をコールバックというしがらみから解放させたように
>見せかけるか、という手法なんですよ。
で、そう見せかけるためには、実際にはコールバックをまたぐ必要があるんだろ?

>これほど汎用的に使える手法を"たまたま"と表現することはできないでしょう。
"たまたま" の意味を取り違えているな。
レジスタに 0 をセットのには、たまたま XOR が使えるけど、
123 をセットする為には、どんなにビットをいじくりまわしても
無理。素直にロード命令を使っとけって事。


413:デフォルトの名無しさん
04/09/23 22:55:51
> ですから、私はコールバックをまたぎたいんではないんですって。
まず,「コールバックを跨がなければ問題なく継続を扱える」のは
>>391さんの言う通り問題ない.
>>392の発言はどう読んでも「コールバックを跨ぎたい」という風にしか
読み取れないんだが.
> いかに継続をコールバックというしがらみから解放させたように
> 見せかけるか、
もう少し具体的に書いてくれ.これでは全く意味不明.

414:デフォルトの名無しさん
04/09/23 23:00:38
なんか変なやつが増えた?
具体的には412だけどさ・・・
おねがいだからこれ以上変なスレにしないでね(苦笑

恐らくミミが言ってるのはschemeで擬似的な継続を作ってやりすごそうって事だよな?
その偽の継続と、OS側の本物の継続はかならずしも一致しなくていい。


415:デフォルトの名無しさん
04/09/23 23:03:01
つまりschemeコード上で破綻してなければどんな手段の継続であるうとかまわない、
最終的にプログラムを終了させたときにOS側の継続と一致していれば良い、
って事だと思う。

416:デフォルトの名無しさん
04/09/23 23:05:21
だからコールバックに突入してそのままルートの継続呼び出して戻ってきても、
OS側の本物の継続はまだコールバックの中、ってこともありえる。

417:デフォルトの名無しさん
04/09/23 23:11:02
>>416
言ってることは分からなくもないが,別に疑似的な継続なんて持ち出さなくても
「コールバックを跨がなければ問題なく継続を扱える」
方法はあるわけで.

418:デフォルトの名無しさん
04/09/23 23:17:24
で,コールバックを跨ぐために疑似的な継続を持ち出してみたものの,
どのみちOS側の継続は戻せないので意味ないじゃん…という感じ.

419:デフォルトの名無しさん
04/09/23 23:19:33
別にOS側の継続戻す必要ないよ

420:デフォルトの名無しさん
04/09/23 23:23:51
おまいらちょっと用語の整理が居るんじゃないか?
おれは理解が追いついていないから何もできんですまんが


421:デフォルトの名無しさん
04/09/23 23:26:00
>>419
WM_* のコールバック中に継続を保存し、それを再開できるとでも?

422:デフォルトの名無しさん
04/09/23 23:29:22
コールバックをまたがないのなら、それは継続ではないし、継続である必要も無い。
全く無意味で非実用的な事態を想定し、無駄に思考時間を消費しているだけ。

423:デフォルトの名無しさん
04/09/23 23:31:10
>>420
ついでにカキコしてる人の整理もな…
どれとどれが同じ人の書き込みなのかさっぱり

424:デフォルトの名無しさん
04/09/23 23:32:44
>>423
「ミミ」以外は区別する必要無い気が

425:デフォルトの名無しさん
04/09/23 23:54:40
>>392 を図示してみた。間違っていたら指摘してくれ。
注)[Sn]:Scheme で使うスタック要素, [On]:OS で使うスタック要素

1.
>OS から コールバック A が呼ばれ、
スタック:[S1][S2][O1][O2][A]

2.
>そこで継続 ContA を作成して、
>トップレベルに束縛したとします。
スタック:[S1][S2][O1][O2][A]
ContA:[S1][S2][O1][O2][A]

3.
>次に、OS から別のコールバック B が呼ばれ、
スタック:[S3][S4][S5][S6][O3][O4][O5][O6][B]
ContA:[S1][S2][O1][O2][A]


426:デフォルトの名無しさん
04/09/23 23:55:07
4.
>そこから ContA を呼び出すとします。
>ContA を呼び出した直後は別に問題は発生しませんよね。
スタック:[S1][S2][O1][O2][A]

5.
>問題は、ContA を呼び出し後に、コールバック A から呼び出し側に戻って
>しまうことが問題なのですよね。
スタック:[S1][S2][O1][O2] <-これが問題。本来なら[O6]に戻るべき。

6.
>であれば、コールバック A から OS 側に戻ろうとする直前に、
>あたかも、コールバック B から戻ったように見せかけることができれば、
>いい感じがしませんか?
3.から4.に遷移する時に
スタック:[S3][S4][S5][S6][O3][O4][O5][O6][A]
となればいい、って事か?


427:ミミ
04/09/24 00:07:07
>>415
>>416
私の意図を汲み取ってくれています。
ありがとうございます。

>>425
>>426
最後の 6 だけ私の意図とは違います。

> 3.から4.に遷移する時に
> スタック:[S3][S4][S5][S6][O3][O4][O5][O6][A]
> となればいい、って事か?
のではなくって、
継続 A へ飛んだあと、
コールバックを終了して OS 側に戻る直前に、

スタック:[S3][S4][S5][S6][O3][O4][O5][O6]

となるということです。
したがって、これを行うのは、
コールバック A の C サンクの中です。


428:デフォルトの名無しさん
04/09/24 00:07:16
コールバックの用途が概ね副作用であり、大域的状態変化が伴う事を無視して
スタックだけを取り上げるのはいかがなものかと

429:デフォルトの名無しさん
04/09/24 00:10:13
>>410は無視ですかそうですか

430:デフォルトの名無しさん
04/09/24 00:17:24
410に限らず、都合の悪いレスは無視みたいね
オナニーは一人でやってほしいもんだ

431:デフォルトの名無しさん
04/09/24 00:17:45
>>429
素人さんは、すっこんでろ

432:デフォルトの名無しさん
04/09/24 00:20:10
410は何が知りたいんだろう・・・

433:デフォルトの名無しさん
04/09/24 00:25:59
>>410=429=430
setjmp/longjmpは、別に「OSの機能」で実現されてるわけじゃないぞ?
ほぼレジスタやスタックの操作だけ。
アセンブラというものが使える状況なら基本的にどのOSでも作れる。


434:デフォルトの名無しさん
04/09/24 00:29:04
>>433
だからこそOSを含めて継続の保存/復帰を実現するには、OS側のサポートも必要だろってことだよ。
で、そういう実装があるのなら参考のために是非知りたいということ。

435:デフォルトの名無しさん
04/09/24 00:30:55
>>434
おまえさ、わざと勘違いしてんのか?
つまんねえよ。
話の腰を折るだけのつもりなら消えてくれ。


436:デフォルトの名無しさん
04/09/24 00:35:35
なんか、OSを含めて継続保存とか意味不明なこと言ってるアフォがいるけど、
いつからOS含めた話になったの?

437:デフォルトの名無しさん
04/09/24 00:37:55
>>436
>>408に、「実際に OS 側の継続を戻す Scheme 実装系はありますよ。」とあり、
>>410は、その実装系はなんなのかを知りたいという。
ただそれだけの話なんだが、そんなに分かりづらいか?

438:デフォルトの名無しさん
04/09/24 00:38:21
WindowsプログラマとUNIX BAKA (BAd Knowhow Association)の
間で文化摩擦が発生しています

439:デフォルトの名無しさん
04/09/24 00:42:16
「OS側の継続」の定義がそれぞれ違うんだろうね。
なんかプロセス間通信とか言ってる馬鹿(=410)が混じってるので
これ以上続けても無駄な気がする。

それでも続けるなら、
ここからは「Windows限定」でどぞ↓


440:デフォルトの名無しさん
04/09/24 00:42:35
なんでそーなるの?
Windows でも X でも、Scheme 的継続はコールバック跨げないよ。

441:デフォルトの名無しさん
04/09/24 00:44:31
>>440
だから話をシンプルにするための処置だよ。
おまえた単にWindows嫌いなだけだろ。
以降「Windows限定」でどぞ↓

442:デフォルトの名無しさん
04/09/24 00:46:44
('A`)

443:デフォルトの名無しさん
04/09/24 00:48:36
そもそもXなんて誰も使わないしUNIX系は無視してもいいと思う。
「ミミ」自体Windowsって言ってるんだし。

444:デフォルトの名無しさん
04/09/24 00:49:15
いや~、やっぱり Scheme は面白いですね。


445:デフォルトの名無しさん
04/09/24 00:50:30
(gc)

446:デフォルトの名無しさん
04/09/24 00:50:58
(exit)

447:デフォルトの名無しさん
04/09/24 00:59:15
UNIX馬鹿の粘着のおかげで横道逸れすぎて話が全然進まなかったな。

448:デフォルトの名無しさん
04/09/24 01:00:04
なんでもいいからさー、実装出してよ。

449:デフォルトの名無しさん
04/09/24 01:10:55
程よく荒れてきたようなので、一つ質問。

例えば、
ContA:[S1][S2][O1][O2][A]

で、[A] から抜けて([O2][O1]の事は脇に置いておいて)
[S2]に戻るから、これを「継続」って呼んでいるんだよね?

なのに 6.のように
[A] から抜けた後、[S6]に戻る(?)ものを
「継続」って呼んでも良いとでも思っているの?
それは Scheme でいう「継続」とは全く別のものじゃないの?


450:デフォルトの名無しさん
04/09/24 01:30:40
ミミタンの作る処理系は独自実装なので
そんなコトはどうでもいいのです。

451:デフォルトの名無しさん
04/09/24 01:32:18
別に問題ない。
スタックのどこであろうとschemeコードに制御が移ったのなら、それは立派な継続。
コールバック内外へ飛んだ事を「継続を使うユーザー」が知っていればいい。

452:デフォルトの名無しさん
04/09/24 01:32:59
とりあえず Scheme にやさしい OS をつくろうよ。

453:デフォルトの名無しさん
04/09/24 01:45:21
頭固い人多いね
ま、一人が粘着してるだけかもしらんけど・・

>>449
>「継続」って呼んでも良いとでも思っているの?
>「継続」って呼んでも良いとでも思っているの?
>「継続」って呼んでも良いとでも思っているの?

もうね、君に理解は無理だよ

454:デフォルトの名無しさん
04/09/24 01:55:24
>>453
>もうね、君に理解は無理だよ
いや、それはすなわち規格で規定された動作が
出来なくなってしまうという事を意味すると思ったのだが・・・

ま、確かに俺には理解不能だな。


455:デフォルトの名無しさん
04/09/24 02:26:12
>>454
ミミが定義した偽継続だからそれでいいんだろ。scheme的継続だと思ってはいけない。

456:デフォルトの名無しさん
04/09/24 02:37:43
規格に通らなくなるってわけでもなさそうだけど。
規定された動作って、どの辺の事?>454

457:デフォルトの名無しさん
04/09/24 02:59:31
実装の話もいいけど、
使う側の話もしようぜ?

458:デフォルトの名無しさん
04/09/24 04:27:16
ヒント。partial continuaionについて調べよ。


459:デフォルトの名無しさん
04/09/24 08:17:03
事の発端となった香具師の要件が明確でないのに本人はうやむやにしたまま消えちゃうし、
まるでそれと入れ替わるかのようにいつもは議論になっても出てこないような類のレベルの低い煽りのみを繰り返す香具師が出てくるし、
そんな状態で外野が言い合ってたって全く意味が無く、時間の無駄以外の何者でもないと思う。

460:デフォルトの名無しさん
04/09/24 09:25:41
ミミは夜行性だから夜まで待て

461:デフォルトの名無しさん
04/09/24 13:45:00
話を蒸し返すようで悪いが,「プロセス間通信云々」→「Windows素人は黙ってろ」
の流れの意味が分からない.誰か説明キボン.
例えば,Windowsのウィンドウプロシージャが呼び出される過程は,
・OSからウィンドウの属しているスレッドのメッセージキューに
 メッセージが送られる.(ここでプロセス間通信)
・ウィンドウの属しているスレッドにて,キューからメッセージ取り出し.
・取り出したメッセージを引数にコールバックプロシージャを呼び出す.
こんな感じじゃないの?
明らかにプロセス間通信は絡んでると思うんだけど.

462:デフォルトの名無しさん
04/09/24 15:50:49
URLリンク(www.double.co.nz)

463:デフォルトの名無しさん
04/09/24 16:23:22
>>461
必死に慣れない参考書読んで調べたんだろうけどさ、基本的なことを
まるで理解してないな。
おまえが調べた内容は、OS側でブラックボックス化してる部分を
ただほじくりかえしただけ。つまり大ハズレもいいとこ。
これはね、まず恥ずかしいことなんだと認識してくれよ?
悦に浸るどころじゃないよ?(w
なんのためにスレッド毎にメッセージキューがあるのかをまずよく考えてね?
Windowsの開発者はメッセージキューの知識だけでプログラミングできるだろ。
あえて「プロセス間通信」を意識して扱う必要なんてないんだよ。
別にOSを作るわけじゃないんだから。
つーかプログラム書いた事もなさそうだし、どっか他行って勉強してきて。
もうね、ここで続けられると邪魔だから消えろ。

464:デフォルトの名無しさん
04/09/24 17:38:49
全然素人なんだけど、WindowsってOSの使用するスタック領域と
アプリケーションプロセスの使用するスタック領域は連続しているの?
連続しているからスタックを保存すれば継続が補足できると言う前提で
議論しているみたいだけど、OS側に制御が渡った瞬間、別のプロセス空間の
スタック領域にスイッチする場合、どう考えてもOS側の継続を制御するのは
無理のように思えるけど。。


465:デフォルトの名無しさん
04/09/24 17:59:39
>>464=461
全部間違ってる
もう引退時じゃね?
LISPには柔軟な頭が必要なのよ

466:デフォルトの名無しさん
04/09/24 18:06:09
> ・OSからウィンドウの属しているスレッドのメッセージキューに
>  メッセージが送られる.(ここでプロセス間通信)

PostMessage,SendMessageは
・他プロセスの場合は最初に該当するスレッドの保有するメッセージキュー領域を
メモリマップドファイルを使って共有し、データ書き込み。
・同一プロセス、他スレッドの場合は受信スレッドのメッセージキューに直接書き込み。
・同一スレッドなら、コールバックの直接呼出し。
こんな感じか?

467:464
04/09/24 18:11:17
一応いっておくけど、461とは別人です。
>>425みてもわかるように、OS側の継続がアプリケーションと
同じスタックに乗っている前提で話してるよね?
違うのかな?


468:デフォルトの名無しさん
04/09/24 18:11:50
>>463
反応するのも馬鹿らしいが,
メッセージキューってのは立派なプロセス/スレッド間通信の一種.
あと,この部分は別にブラックボックスにはなってない.むしろ基礎の基礎.

>>464
> OS側の継続を制御するのは無理
これは正しい.
> スタックを保存すれば継続が補足できると言う前提で議論している
こっちは×.最終的にスタックを元の状態に戻してやれば
Schemeインタプリタ側では好き勝手にいじってもいいよねー,って話.
たぶん.

469:464
04/09/24 18:15:44
>>468
コールバックは常に同一プロセス内から直接呼び出されるのなら、
スタックコピーで制御は戻りそうなんだけど、私が疑問に思ったのは、
コールバックを渡すOS側は同じプロセス空間で動いてないような気が
するんだけど。あてずっぽうですが。


470:デフォルトの名無しさん
04/09/24 18:16:57
>>458
URLリンク(www.google.co.jp)
R5RS partial continuaionに該当するページが見つかりませんでした。
URLリンク(www.google.co.jp)
scheme partial continuaionに該当するページが見つかりませんでした。


>>462
規格とは関係ないみたいよ?
もちろん部分継続も問題ないし。
いったい何を危惧してるのかね。
ちゃんと継続を理解してる人って少ないの?


471:デフォルトの名無しさん
04/09/24 18:19:46
>>464
スレ違いな質問繰り返してんじゃねーよ
デバッガ使って自分で確かめろ
ミミよりウザイ

472:464
04/09/24 18:20:40
Schemeインタプリタ自体は同一プロセス内で動いてるから、
スタックコピーで継続が戻るのは当たり前だと思うけど、
Schemeインタプリタとは異なるプロセスの継続も補足できるの?


473:デフォルトの名無しさん
04/09/24 18:21:27
>>469
メッセージキューにメッセージを置くのはOS側(もちろん違うプロセス空間で動いてる)だけど,
メッセージを取り出すのは自分なので問題ない.というか,別に違うプロセス空間から
呼び出されても問題ないと思うけど.

>>470
ミミがやりたいのは部分継続じゃないの? ってことだと思う.

474:464
04/09/24 18:24:37
>>473
ああ、ここでコールバックって言ってるのは、あくまでも
イベントキューから自分で読み出して関数を呼ぶイベント駆動
プログラミングのことなんだね。
違うものを想像してたよ。


475:デフォルトの名無しさん
04/09/24 18:25:26
>Schemeインタプリタとは異なるプロセスの継続も補足できるの?
で き ま せ ん

なあ、その電波な質問はどっからやってくるんだ?


476:464
04/09/24 18:26:20
>>475
言葉のすれ違いと思ってくんなまし。


477:デフォルトの名無しさん
04/09/24 18:26:43
つーか試しもしないで質問ばかりする464は不要な人材

478:ミミ
04/09/24 18:46:38
こんにちは。
昨日は遅くまでありがとうございます。
細かい議論はあるかもしれませんが、
おおまかなアイデアは理解していただけたようですね。

私は部分継続を行いたいのではなくて、
コールバックの検問所を作りたいということです。
図にまとめてみました。

479:ミミ
04/09/24 18:47:08
■従来のコールバックの実装

┌─┐
│ │ ┌──┐
│ │ ┌┘ │
│ CbA├─┘ │
OS │ ├─┐ ContA │
側 │ │ └┐ │
│ │ └──┘
│ │ ┌──┐
│ │ ┌┘ │
│ CbB├─┘ │
│ ├─┐ o--───ここから ContA を呼ぶと
│ │ └┐ │ CbA から出て行ってしまう。
└─┘ └──┘ これは破綻する。


480:ミミ
04/09/24 18:47:28
■検問所式コールバックの実装

┌─┐
│ │
│ │ CbA ┌───┐
│ │ ┌─┘ │
│ ├─┼─┐ ContA │
OS │ │ │ └───┘
側 │ ⇔ │
│ │ │ ┌───┐
│ ├─┼─┘ │
│ │ └─┐ o--─── ここから ContA を呼んでも
│ │ CbB └───┘ OS 側に正しく戻ってくれる。
│ │
└─┘


コールバックは必ず検問所(⇔)を通して呼び出されるし、
検問所を通して戻る。検問所を通して戻るときは、
必要があればスタックの回復を行ってくれる。
したがって、Scheme 側では継続とコールバックの関係を
気にしなくてよい。


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