05/06/14 22:24:29
>>351
初期のJavaの研究会行ったら「私の仕事はGuy L. Steele 仕事ですw」という奴が居て噴いたなぁ。
Scheme → CommonLisp → StarLisp, C* (ThinkingMachine) → HighPerformanceFortran → Java
のうち、漏れ自身ThinkingMachine以外はやってたw
353:デフォルトの名無しさん
05/06/14 22:48:06
C: A Reference Manual を書いたり ECMAScript の標準化を手伝ったりも
354:デフォルトの名無しさん
05/06/15 00:09:09
ガイ・スティールの手のひらでころがされてる気分になってきた
355:デフォルトの名無しさん
05/06/15 00:20:44
>>344
反応するなよ
>>349
騙されるなよ
356:デフォルトの名無しさん
05/06/15 00:31:28
>>345
ダウト
357:デフォルトの名無しさん
05/06/15 01:21:56
r6rs の作業が始まってから一年半経つけど、あとどのくらい掛かるんだろうか。
UNICODE サポート、例外機構、モジュール機構、構造体辺りが楽しみだ。
モジュールは長く標準化が待ち望まれた機能だしね。
358:デフォルトの名無しさん
05/06/15 01:28:41
構造体作るから多値はいらないという
多値は受け取ったり受け取らなかったりと、今一不可解なプロトコルと言える
参照ベースな言語では構造体パックが正解なのかもしれない
359:デフォルトの名無しさん
05/06/15 03:35:45
>>339
そこで Arc ですよ。
>>358
個人的には多値で渡していくやり方は細かいことを気にせずに済んで好きなんだけど、
いまいち現状だと構文上すっきりしないところが多いのも確かですね。
wiliki であった、アリティに応じて返す値の数を変えられるようにする、
ってのは結構面白いなあと思った。問題が色々出て来ちゃうみたいだったけど。
……でもその辺すっきりしたいなら他の関数型言語に転んじゃった方が楽な気が。
どうせ構造体でパックしちゃうなら 1-in 1-out で、型付けも静的な方が楽じゃないですか?
360:デフォルトの名無しさん
05/06/15 07:09:22
多値で受け取るのも、構造体のアクセッサ経由で値を受け取るのも、
手間は変わらないって考えて良いのかな。
361:デフォルトの名無しさん
05/06/15 11:25:48
こんな感じかな?
(i) 構造体のコンストラクタが関数の末尾位置にあるときは、構造体
そのものをスタックにアロケートして、
(ii) その関数の呼び出し側で返値(構造体)がエスケープしないなら
そのままスタックの上で使う。
362:デフォルトの名無しさん
05/06/15 11:37:37
割り込み失礼。スラドに載った。シンボルを HashTable にしたのが後藤氏の
仕事とは知りませんでした。
「日本のコンピュータ研究の先駆者、後藤英一さん他界」
URLリンク(slashdot.jp)
363:デフォルトの名無しさん
05/06/16 11:02:58
質問です。
『初めての人のためのLISP』を図書館で借りて読んでいるのですが、ちょっと
分からない点があります。
P147
-------------------------
初心者は nconc の使い方でミスをするケースが非常に多い。例えば,プログ
ラムの中で
(setq x (nconc '(title =) y))
などとやると,プログラムの中の
(title =)
というリストの後ろに y の値がくっついてしまう。だからふたたびこの式を
評価すると,前回くっついたものの後ろにまた nconc することになる。プロ
グラム中で quote されたリストもデータには代わりはないから要注意。
-------------------------
しかし、手元の処理系(emacs21, xyzzy)では、上の式は何度評価しても、x に
は同じ(equalな)値がバインドされています。どんどん長くなったりしません。
私が勘違いしているのでしょうか?それとも、昔の処理系なら x はどんどん
長くなったのでしょうか?
364:ζ
05/06/16 12:21:12
こうゆーことが言いたいんじゃないのか?
(setq a "hi" )
=> "hi"
(setq a (nconc '(title =) a))
=> (title = . "hi")
=> (title = title = . "hi")
=> (title = title = title = . "hi")
=> (title = title = title = title = . "hi")
365:363
05/06/16 12:37:21
ちょっと違うと思います。それだったら、nconc ではなく append でも同じで
すから。
366:デフォルトの名無しさん
05/06/16 13:31:00
評価するときに
(setq x (nconc '(title =) y))
ってもう一度打ち込んでるとか。
そうすると '(title =) のリストが(多くの処理系では)再評価のたびに新しく作られる。
(defun f () (setq x (nconc '(title =) y)))
のような関数を作って (f) を再評価してみては?
ちなみにANSI Common Lispの規定ではquote式のリストを書き換えることは禁止
になっていたと思う。
367:364
05/06/16 14:06:31
当方の環境は emacs と xyzzy ですので、新たに手入力をしたりはしていませ
ん。*scratch buffer* の同じ行で、C-j を繰り返しています。それでも x は
伸びないのです。
なお、念のため (defun f () (setq x (nconc '(title =) y))) も書いてみま
したが、やはり emacs、xyzzy とも x が伸びたりはしません。
368:デフォルトの名無しさん
05/06/16 14:15:10
こうじゃないの?
(setq x '(1 2 3))
(nconc x '(4 5))
nconc を繰り返すと x は長くなっていく(@emacs21)。
369:デフォルトの名無しさん
05/06/16 14:15:44
>>367
>C-j を繰り返しています。
これはLispインタプリタ側から見たらテキストを再入力してるのと同じ。
内部的にはトップレベルの (read) がもう一回呼ばれるからね。
ところで y の値には何を入れて試してるの?
370:364
05/06/16 14:36:05
(setq y 'hoge) としてから実行しています。ちなみに、先の関数 f をバイト
コンパイルしても、やはり x は伸びません。
私の疑問をまとめますと、'(title =) を評価したら、それが再度の手入力で
あれ、バイトコンパイル後の関数内であれ、毎回新たな cons セルが生成され
るのが自然なのではないか、x が伸びるのはおかしいではないか、というもの
です。
しかし、よく考えてみると、伸びないのが逆におかしいような気もします。混
乱してきました。
nconc に渡されるものの実体は何でしょうか?渡されるものがただの文字列で、
それを nconc が評価してリストを生成するなら、伸びないのが自然だし、渡
されるものが cons セルそのもので、その生成は最初にコードを書いたときに
行われるなら、伸びるのが当然のような気がします。
皆さんの処理系では、どうなるでしょうか?
371:デフォルトの名無しさん
05/06/16 14:44:44
destructive か non-destructive の差だろ。
実装による。
372:デフォルトの名無しさん
05/06/16 14:48:44
>>370
'(title =)のセルが作られるのはトップレベルの内部で呼ばれるread関数の中。
エディタは文字列で持っているが、それがLispの世界に渡されるときにconsセル
に変換される。君の場合はC-jを押したときに起こっているはず。
あとyの値がアトムでは面白いことは起きないだろ。
(setq y '(hoge))
(defun f () (setq x (nconc '(title =) y)))
しておいて(f)を評価してみ。2回目の評価で凄いことが起きるぞ。w
373:デフォルトの名無しさん
05/06/16 14:50:01
>>371
nconcがdestructiveでない実装ってある?
374:364
05/06/16 16:39:48
大変よく分かりました。ありがとうございます。というか、実に自分は分かっ
てませんでした。
(setq y '(hoge); リストを入れる。
(f); 評価にあたって、バイトコンパイルの必要はない。
=>(title = hoge) ; 1回目
=>(title = hoge hoge . #2) ; 2回目
=>無限ループ ;3回目...あわてて C-g で停止。
nconc は破壊的だから、同じリストを nconc で何度も結合すると、自己参照
が起きてしまうのですね。私のところで問題が起きなかったのは、一つはアト
ムを nconc していたからなのですね。
まとめると、こんな感じでしょうか。
・(setq x (nconc '(title =) y)) の評価は、これを素で評価するのと、関数
に入れて評価するのとで、結果が違う。
・(setq z '(title =)) として、(setq x (nconc z y)) を評価すると、素で
評価しても、関数に入れても同じ結果になる。
・だから、Common Lisp では、quote 式のリストに破壊的操作を行ってはなら
ないことになっている。
375:デフォルトの名無しさん
05/06/16 18:54:46
違う。それだと (setq x (nconc (list 'title '=) y)) でも同じだよね。
* '(a b c) のようなフォームはリテラルと呼ばれ、コンパイル時に作成される。
* だから (defun f () '(a b c)) の時、(eq (f) (f)) は真になる。
* もしここでリテラルの変更を許可してしまうと
(f) => '(a b c)
(nconc (f) '(d e f))
(f) => '(a b c d e f)
となり、参照透過性が保てなくなる。
* また、コンパイラは同じ値のリテラルを同じオブジェクトにしてもかまわない。
(setq x '(a b c) y '(a b c)) において (eq x y) が真になってもかまわない
ということ。そのような最適化をするコンパイラでは
(setq x '(a b c) y (nconc '(a b c) '(d e f))) で x まで '(a b c d e f)
になってしまう。
376:デフォルトの名無しさん
05/06/16 20:06:54
>>375
「コンパイル時に作成される」という言い方は抵抗あるなぁ。
基本的にはインタプリタでも事情は似たようなもんだから。
同一リテラルを再利用する最適化はread関数が行う可能性も
あるし、もちろんコンパイラが行う可能性もある。
(実際にやる処理系は見たことないけど)
377:363
05/06/16 21:16:25
興味深い、ありがとうございました。
しかし、後者の理由はわかりますが、前者の参照透過性については、副作用の
ある関数も多いわけですから(カウントアップのクロージャとか)、純粋な関
数型言語でない LISP にとってそれほど重要なのか、よく分からないです。
あと、
(setq y '(hoge))
(defun f ()
(setq x (nconc (list 'title '=) y)))
これだと、(f) を何度評価しても、結果は (title = hoge) なのですが。
378:363
05/06/16 21:17:16
あ、日本語がおかしい。「興味深いお話、ありがとうございます」でした。
379:375
05/06/16 22:16:50
>>376
インタプリタであっても、クロージャの作成等ある程度の変換処理が入るので、
そういった物も含めてコンパイラと書いたんだけど、 Common Lisp では
「コンパイラ」という用語は interpreted function を compiled function に
変換する機能として定義されてるからよくなかったね。
「処理系によって作成される」等に訂正。
ところで、read 関数が返すのは #n# 等の例外を除いて新規に割り当てられる
ことが保証されてなかったっけ。reader の段階では '... を (quote ...) と
変換できることは知ってても (quote (a b c)) がリテラルであり再利用可能
であることは知らないはずだけど。
もし保証されてないとすると、prin1 で保存したデータを read して破壊的操
作してるコードを修正しないと。。。
>>377
一見参照透過に見えるのにそうでないのは混乱の元だってこと。
実際にはリテラルを直接返すのは呼び出し元の挙動に依存するので
あまり好ましいやり方じゃないんだけどね。
あと、後半部についてはそのとおり。(setq x (nconc (list ... はまとめ
の部分に対してのコメント。
380:363
05/06/16 23:07:13
なるほど、意図を逆だと勘違いしていました。すみません。
381:デフォルトの名無しさん
05/06/16 23:26:37
すみませんが質問です。
Windows で Scheme を書いておられる方は、環境に何をお使いですか?Emacs の
scheme-mode + run-scheme と似たような環境がほしいのです。
・ChezEdit ... Shift + F2 で範囲選択した個所を評価・実行できるので、Emacs と
かなり使い勝手は近い。しかし Petite Chez Scheme 専用。また Windows95 系の
OS では動かない。
・xyzzy ... scheme-mode はあるが、run-scheme はない。
・Meadow ... 使ったことないけれど、run-scheme は Gauche ではうまく動かない
らしい。
・Dr.Scheme ... MzScheme 専用。英語なので使い方がよく分からない。
382:デフォルトの名無しさん
05/06/17 04:17:37
お願い:
ある処理系で Shift_JIS をサポートするに当たり、locale が Shift_JIS の
際の nl_langinfo(CODESET) の値を調べてます。
以下のコードを foo.sh と保存し、sh foo.sh の結果を教えてください。
ちなみに、当方では以下のようになります。
FreeBSD 5.4-RELEASE-p2
codeset: SJIS
--ここから-- foo.sh
#! /bin/sh
c=$0.$$.c
o=$0.$$.out
cat > $c <<__EOF__
#include <langinfo.h>
#include <locale.h>
#include <stdio.h>
main()
{
setlocale(LC_ALL, "");
printf("codeset: %s\n", nl_langinfo(CODESET));
}
__EOF__
cc -o $o $c
uname -sr
for l in $(locale -a | grep -i -e sjis -e 'shift.*jis'); do
LC_ALL=$l ./$o
done | sort -u
rm $c $o
--ここまで--
383:デフォルトの名無しさん
05/06/17 05:25:49
SolarisではPCKだったと思うのでひっかからないような。
384:デフォルトの名無しさん
05/06/17 05:27:28
スレ違いなものにレスをつけてしまったorz
385:デフォルトの名無しさん
05/06/17 09:07:13
あっそ、じゃあ調査は終了。
386:381
05/06/17 10:42:50
うわーい、全然レスがついてません。まいりました。
みんなホント、Windows でどうやってるんですか?Gauche を Windows に移植
した人たちとか、一体どんな環境で Gauche を使いたくて移植したんでしょうか?
387:デフォルトの名無しさん
05/06/17 11:18:19
>>381
Windows でも Emacs(Meadow) + scheme-mode + run-scheme ですが何か?
388:381
05/06/17 12:52:38
>>387
すみません、Meadow は Gauche を普通に使えるみたいですね。
URLリンク(64.233.161.104)
Meadowのrun-schemeでGaucheを使う場合には-iオプションを付ける必要がある.
(setq scheme-program-name "gosh -i")
少し質問させてください。
・Meadow で MzScheme、Chez Scheme などは使えますか?
・もう少し軽い環境はないでしょうか?VisualStudio が軽々動くマシンでし
たら、Meadow + Cygwin も問題なく使えるのだろうと思うのですが、私の
Windows 機は xyzzy ももっさりしているぐらいなので。
389:デフォルトの名無しさん
05/06/17 12:59:07
Windowsの代わりにLinuxかFreeBSDでも入れて、GnomeやKDEなんかの
重たいデスクトップ環境を使わないようにすれば古いPCでも快適ですよ。
当方は初代ThinkPad560をそうやって使ってます。買い替えたのは内蔵
ハードディスクだけ。GoshもMzSchemeもそこそこ快適に動きますよ。
390:381
05/06/17 15:15:05
ありがとうございます。実は、Linux をすでに別のマシンに導入しており、
Emacs21 + Gauche を快適に使っています。それまでずっと Windows (とその
系統のソフト)しか使っていなかったので、こんなに便利な環境があるなんて、
想像もしていませんでした。今まで使わないで大損をしていた、と後悔してい
るほどです。
URLリンク(www.math.s.chiba-u.ac.jp)
現用の Windows(98)機は事情があって、Linux を入れることはできないのです
が、このマシンでも Petite Chez Scheme は意外に早く動くので、こちらでも
もう少し環境を整えられないかな、と思ったのです。Emacs 環境がいかに便利
とは言え、長く使った Win 版ChezScheme に少々愛着もありますので。
391:デフォルトの名無しさん
05/06/17 21:13:21
>381
>Windows で Scheme を書いておられる方は、環境に何をお使いですか?
DrScheme 使ってる。
>Dr.Scheme ... MzScheme 専用。英語なので使い方がよく分からない。
最近 GUI が日本語化されたよ (v299.106 以降)。
マニュアルは英語のままだけど。
392:デフォルトの名無しさん
05/06/17 21:39:49
>>391
それって、どこでダウンロードできますか?下記のサイトではまだ
Version:299.100 なんだけど。
URLリンク(download.plt-scheme.org)
393:デフォルトの名無しさん
05/06/17 21:50:31
URLリンク(pre.plt-scheme.org)
394:デフォルトの名無しさん
05/06/17 22:20:52
ありがとう!これはなかなか凄そうだ!
395:381
05/06/17 23:44:45
Dr.Scheme(PLT Scheme)は、Windows の COM オブジェクトの操作ができるとい
うので、とても興味があります。
いくつか質問させてください。
・開発環境は、日本語は通りますか?
・エディタ画面の、指定した範囲の評価はできますか?
(Emacs の C-x C-e にあたるもの)
・エディタ画面は、S式単位の編集はできますか?
(参照:4.2. カーソル移動)
URLリンク(www.kahua.org)
・Emacs キーバインドにすることはできますか?
・以前試したとき、素のMzScheme は結構早いのに、Dr.Scheme環境だと大変遅
くなった記憶があります。今はどうでしょうか?遅いままだとしたら、使い
方による回避はできますか?
たくさん聞いてすみません。私のほかにも、興味はあるけど手を出せないでい
る人は多いと思いますので。少しでも答えてもらえたら、大喜びです。
396:デフォルトの名無しさん
05/06/17 23:52:39
>興味はあるけど手を出せないでいる人は多いと思いますので。
この辺が漏れには理解できないんだよね。
とりあえず試してみればいいのに。
397:デフォルトの名無しさん
05/06/18 00:08:12
(本音-of >>395)
=> いちいち試すの面倒だからさっさと教えろよ!
398:デフォルトの名無しさん
05/06/18 07:13:00
>>395
(cond
(開発環境は、日本語は通りますか?
今時Unicode対応は標準だと思うんだが.....)
(エディタ画面の、指定した範囲の評価はできますか?
そんなことすらできないものをIDEと呼ぶはずが無いと思うんだが....)
(エディタ画面は、S式単位の編集はできますか?
できなかったらキーボードに突っ伏して寝てしまうほど基本的な機能だと思うんだが....)
(Emacs キーバインドにすることはできますか?
キーバインド固定のIDEなんて絶滅して久しいと思うんだが....)
(素のMzScheme は結構早いのに、Dr.Scheme環境だと大変遅くなった記憶があります。
デバッグ機能を外せば実行は早くなると思うんだが....)
(else
予想と現実ってあんまり一致しないんだよな))
399:381
05/06/18 08:48:50
すみません、確かに少々ずうずうしい質問でした。
実は、最新版を一応インストールして、少し試してはいたのですが、知人のマ
シンを借りて行っていたので、きちんと試す時間がなかったのです。だから試
したとは書かなかった(書けなかった)のですが、>>395の質問項目は、いず
れもその短い時間で解決できなかった項目を、知人のマシンから書き込んだも
のです。
現在は自宅の自分のマシンですが、実は、インストールしようとすると、何度
やってもインストーラが途中で失敗してしまいました。おそらくメモリ不足で
しょう。知人のマシンで試した時、かなり重かったので、うまく行かないよう
な気がしてはいたのですが。
ただ、開発環境としては非常に興味があります。将来、新しいマシンを入手し
た時のために、参考になることを教えてもらえたら、大変ありがたいのです。
400:デフォルトの名無しさん
05/06/18 18:14:12
(atom 381)
nil
401:デフォルトの名無しさん
05/06/18 20:25:36
Scheme で
(if #t
(define abc 123))
とするとエラーになるのはなんで?
402:デフォルトの名無しさん
05/06/18 20:31:44
>>401
そこは define の書ける場所ではなから。
403:デフォルトの名無しさん
05/06/18 20:36:01
なぜ、書けないのでしょうか。
たとえば、何らかのフラグ (これこれのシンボルが定義されているかどうか)
によって、定義を変えたいときは、どのようにするのがよいでしょうか。
404:デフォルトの名無しさん
05/06/18 20:37:27
>>403
set!
405:デフォルトの名無しさん
05/06/18 20:38:24
>>404
すいません、もう少し詳しく説明していただけませんか?
406:デフォルトの名無しさん
05/06/18 20:42:17
>>405
(define abc 123)
(if 何かの条件
(set! abc 456))
みたいにすればいい。
define は他の言語での変数の宣言に近い。
純粋な代入は set! を使う。
407:デフォルトの名無しさん
05/06/18 20:47:23
> 他の言語での変数の宣言に近い。
なるほどー。
今の例だと、123 という簡単な値なのでよいのですが、
たとえば、構文の定義を変えたい場合はどうでしょう?
たとえば、Windows と Mac で、構文の定義を変えたい場合です。
シンボル WIN32 が定義されていれば Windows の定義にしたい。
これも set! で可能でしょうか?
408:デフォルトの名無しさん
05/06/18 20:47:26
>>402
ブロックの先頭だから書けるはずじゃない?
ローカルスコープなので>>401の例では無意味だが。
ちなみにGaucheだと書けるが、グローバルにabcが定義されちゃう。
これはバグだと思うが。
409:デフォルトの名無しさん
05/06/18 20:56:48
>>408
R5RS的にはdefineが書けるのはトップレベルか<body>の先頭。
ifの中の式は<body>ではないのでR5RS的には駄目。
つまり、lambdaとかletなどの新しいスコープを作る場所でのみ許すという
考え方だとおもわれる。
Gaucheの場合、トップレベルのifの中はまだトップレベルのスコープだという
解釈なのではないかな。これはこれで便利に使えそうな気がする。
410:デフォルトの名無しさん
05/06/18 20:58:01
おれならMLですまーとにかくけどねw
411:デフォルトの名無しさん
05/06/18 21:00:46
>>407
構文というのがマクロの定義を変えたいという意味なら不可だと思う。
(Gaucheなどは>>409で書いたように可能かもしれないが)
関数の定義を変えたいという意味であれば、
(set! func (lambda (...) ...))
のようにすれば定義を変更できる。
412:デフォルトの名無しさん
05/06/18 21:10:01
>>411
> 構文というのがマクロの定義を変えたいという意味なら不可だと思う。
そうですかー。
できてもよさそうな機能なんですけど。。
> 関数の定義を変えたいという意味であれば、
> (set! func (lambda (...) ...))
> のようにすれば定義を変更できる。
Scheme コードをコンパイルする場合、
これだと無駄なコードがコンパイルされてしまいますよね。
だから、構文展開時に切り替えたいんです。。
413:デフォルトの名無しさん
05/06/18 22:07:43
>>412
> これだと無駄なコードがコンパイルされてしまいますよね。
仮に if の中に define が書けたところで、この辺の事情は
変わらないと思うのだが。
414:デフォルトの名無しさん
05/06/18 22:09:07
>>412
そんなのが気になるなら、win32.scm macos.scm とかにプラットフォーム
依存の構文を入れておいて、make 等でそれを target.scm にコピー、
使用する際は (load "target.scm") するようにすれば?
415:デフォルトの名無しさん
05/06/18 22:22:48
基本すら理解できていないのに、何故そんな枝葉にこだわるのか
416:デフォルトの名無しさん
05/06/18 23:22:26
俺もそうだけど、初学者ってそういうもんじゃないかな。
今の疑問が枝葉かどうか判別するには、ある程度見通しが立ってないと。
417:デフォルトの名無しさん
05/06/19 00:39:27
それは学習の仕方が下手なだけ。
ある程度学習経験があれば、そういうところにあまり時間を浪費せずに進み
後でわかるようになってるという進め方が普通。
その決断が自分でできないなら、疑問点をまとめてリストアップしておく
ノートを作っておけばいい。ノートに覚えてもらうわけだ。
先に進んで問題にぶちあたったとき、スキップした項目が理解に関連するなら
そのとき立ち戻ればいい。
418:デフォルトの名無しさん
05/06/19 00:58:21
まぁ、理想的にはその通りなんだろうけどね。
マンドクサ狩りの俺みたいなのは
Scheme には #ifdef ないのか マンドクセ とりあえず放置...
で終了する事が多いんで、疑問は感じた時に解決っつー
スタンスもありだと思うよ。
419:デフォルトの名無しさん
05/06/19 00:59:43
結局だれも解決できないんじゃ。。。
だから初学者だの何だのと言って話をそらすんじゃ。。
420:デフォルトの名無しさん
05/06/19 01:08:10
>>419
んなこたぁないょ
421:ミミ
05/06/19 01:15:26
こんなんでどう?
MzScheme だけど。
(define-syntax (if-for-syntax stx)
(syntax-case stx ()
((_ TEST-EXPR TRUE-EXPR FALSE-EXPR)
(if (eval #'TEST-EXPR)
#'TRUE-EXPR
#'FALSE-EXPR))))
(define PLATFORM "Windows")
(if-for-syntax (string=? PLATFORM "Windows")
(begin
(define Vendor "Microsoft")
(define Color "Blue"))
(begin
(define Vendor "Unknown")
(define Color "Red")))
(display Vendor)
422:デフォルトの名無しさん
05/06/19 01:18:41
>>419
そもそも、言語処理系のユーザが考えるべき問題じゃないし、
ユーザレベルで解決できる問題じゃないってこと。
マクロがどう展開されるか、関数がどう最適化されるかって問題だろ?
部分評価とかする処理系なら、>>412みたいな心配はないかもしれない
わけだし。
423:デフォルトの名無しさん
05/06/19 01:26:12
>>419
414 で解決したと思ってたんだけど
424:デフォルトの名無しさん
05/06/19 01:32:31
それもありだけど。
425:デフォルトの名無しさん
05/06/19 01:59:01
SRFI 0 の feature にプラットフォームも入れてくれる処理系なら
(cond-expand
(win32 ...)
((or unix macosx) ...)
(else ...))
とか
426:デフォルトの名無しさん
05/06/19 18:16:57
前も書いた気がするが、おれの処理系は#if #else #endif をreadに入れたよ。
>>425みたいに無駄にS式縛りにするのは面倒だし
読みにくいと思ってる。
S式に縛られてないから任意の箇所で
(func
#if (defined 'platform-win32)
1 2 3)
#else
#if #t
4 5 6)
#else
7 8 9)
#endif
#endif
みたいなことができる。
まあSRFIレベルの定義じゃ無理だな。
427:デフォルトの名無しさん
05/06/19 18:42:54
>>426 エディタはちゃんとインデントしてくれるの?
428:デフォルトの名無しさん
05/06/19 18:44:20
ちなみにCommon Lispだと#+, #-でやるよね.
CL風の#+ #-が使えるScheme処理系ってないの?
429:デフォルトの名無しさん
05/06/19 19:00:36
プラットフォームで分けたい場合って、関数の中身の処理だけ違っていてインターフェースは同一なはずだから
scheme だと単純に変数へ束縛する関数オブジェクトを変えればいいだけになる。
だから scheme ではわざわざ新しい構文を導入するまでもなく
(define hoge
(if (eq? 'platform win32)
(lambda (arg) ...)
(lambda (arg) ...)))
とかすればいい。
そしてなにより美しい。 ← 一番重要w
430:デフォルトの名無しさん
05/06/19 19:07:30
実行時に (if (eq? ... したくないって流れだと オモテタ けど...
431:デフォルトの名無しさん
05/06/19 19:11:00
>>430
マクロ展開されるのだって1回だけと期待できるにせよ実行時だし、
>>429のifだってよほどnaiveな実装でない限り、1回しか実行されない。
わかってる?
432:デフォルトの名無しさん
05/06/19 19:25:25
>>431
コンパイルが別パスの処理系ならマクロ展開はコンパイル時が普通じゃない?
そしたら実行イメージに余分なコードは入らない.
433:デフォルトの名無しさん
05/06/19 19:27:49
>>432
別パスなコンパイラ使うなら、それこそ適当なプリプロセッサでも使えば
良いじゃん
434:デフォルトの名無しさん
05/06/19 19:28:48
>>431
あらかじめコンパイルしたファイルをダンプしておいた場合も
if は評価されない?
435:デフォルトの名無しさん
05/06/19 20:10:04
>>434
あらかじめコンパイルしたファイルをダンプするって意味が良くわからないが、
>>429の例を借りると、hogeの束縛時つまり(define hoge ...)の実行時に1回if
は評価されるし、されないと困る。が、これによって定義されたhogeを評価
する時には(if (eq? 'platform win32) ...)部分のifを評価するような処理系は
存在しない。
436:デフォルトの名無しさん
05/06/19 21:18:53
ごめん・・・俺の作った処理系・・・評価しちゃう・・・
437:デフォルトの名無しさん
05/06/19 22:07:44
>>429
言いたいことはわかるが、別に美しくない。
使う側はそんな事のためにlambdaに分離してまでやりたくないんだよ。
使う側の気持ちを素直に酌めば、S式縛りでやるなら
(if (eq? 'platform win32)
(define (arg)...)
(define (arg)...))
と書いた方が自然なのでは。
おれの処理系では書けるし、実装するためのトリックみたいなものもない。
逆にscheme的には書けないのはおかしい気がする。
マクロで(begin (define ~)(define ~))と書きたい場合もあるし。
まあ、#if~#endifを作るまではおれもこういう方法を仕方なくとってたけど、
条件毎に余計な部分まで定義をまるごと書かないとダメな点が
どうにも我慢ならなくて切捨てた。
438:デフォルトの名無しさん
05/06/19 22:13:37
>>437
おまいの処理系自慢はいいよ。Schemeの話してるんだから。
439:デフォルトの名無しさん
05/06/19 22:28:16
悪かったよ。
おれも散々悩んだ部分だし。
schemeの中だけでやるなら429みたいな方法しかない。
あとは処理系依存だろ。
440:デフォルトの名無しさん
05/06/19 22:34:13
つか、こういう時のための SRFI-0 だろ
441:デフォルトの名無しさん
05/06/19 22:37:55
R5RS見るとトップレベルのbeginだけ例外になってるのな。
萎え。
442:デフォルトの名無しさん
05/06/19 22:39:37
SRFIのせいでどんどんschemeが変な言語になって行くと思うのは俺だけですか。
443:デフォルトの名無しさん
05/06/19 22:44:54
>>442
でも無いといろいろと再発明する羽目になるからなぁ。
きれいで使えないよりは変で使えるほうがいい。
444:デフォルトの名無しさん
05/06/19 22:47:00
SRFIとR6RSの関係ってどうなるの?
445:デフォルトの名無しさん
05/06/19 23:20:01
>>436
評価するとなると、ifの中に副作用の有る式が書かれていたらプログラムの意味が変わるでしょ。それじゃ全然Schemeじゃないじゃん。
それとも、副作用がないということがプログラム解析で証明できたときだけ評価するの?
446:デフォルトの名無しさん
05/06/19 23:30:07
「処理系が存在しない」
「naiveな実装でない限り、1回しか実行されない」
「それじゃ全然Schemeじゃない」
どれが正しいのか教えてください。
447:デフォルトの名無しさん
05/06/19 23:44:06
Scheme ってリーダーマクロ使わないの?
448:デフォルトの名無しさん
05/06/20 00:05:30
今はSchemeの話をしてるのだから、
上の「処理系が存在しない」と俺の処理系は評価するが?に対する
「それじゃ全然Schemeじゃない」ってのは同じことじゃね?
449:3才児
05/06/20 00:23:04
チンカスの匂いがしてきまちた
450:デフォルトの名無しさん
05/06/20 00:41:53
>>444
SRFI でも obsolete 扱いのやつはあるんじゃなかったっけ?
順次、事実上の格下げされていくんじゃないかな。R6RS と
コンフリクトしそうな物とかも。
R6RS が出来ても、実装が普及するまで時間が掛かるだろうから、
しばらくはそのままなんだろうけど。
451:デフォルトの名無しさん
05/06/20 07:29:45
car cdr atom eq cons は、LISP の5つの基本関数である。それ以外の関数は、
全てこれらを使って合成できるとされる。数学で言う公理に当たる。
car 板 URLリンク(hobby7.2ch.net)
cdr 板 URLリンク(pc8.2ch.net)
atom 板 URLリンク(society3.2ch.net)
eq 板 URLリンク(live18.2ch.net)
cons 板はまだない。速やかな板新設が必要ではないだろうか。
452:デフォルトの名無しさん
05/06/20 07:31:29
WindowsXP 上で CLISP を実行すると
WARNING: locale: no encoding CP932, using UTF-8
WARNING: *TERMINAL-ENCODING*: no encoding CP932, using UTF-8
WARNING: *FOREIGN-ENCODING*: reset to ASCII
といった具合に文字コード関連の警告が出ますが
これを解決する方法をご存知でしたらご教示ください。
453:デフォルトの名無しさん
05/06/20 07:49:45
>>400
今意味が分かったw
>>381 には悪いがちょっと ワラタ
454:デフォルトの名無しさん
05/06/20 09:16:09
(if (eq? platform 'win32)
(define hoge ...)
(define hoge ...))
とかが許されないのは、プログラム全体をCやネイティブに変換するコンパイラーとかで面倒だからでないかい?
例えば、同じコンパイルユニットの中でplatformが定義されていれば、コンパイラーはどっちのdefineをコンパイルして書き出すか判断できるけど、
platformが独立にコンパイルされる別のユニット内で定義されている場合には、特別な仕組みが必要に思える。
そういった足枷をつけるより、ライブラリーレベル(srfi-0)で対応した方が良いということで現行のようになったんだと思ってるんだけど。
どう思う?
455:デフォルトの名無しさん
05/06/20 20:57:56
>>454
すまんが言ってることがわからん。
>platformが独立にコンパイルされる別のユニット内で定義されている場合
この辺をもう少し説明してほしい。
platformが未定義の場合ということ?
定数畳み込みで消えずに未定義でコンパイル通ったとしても、
一度はどっかで実行されるわけだから
最悪ランタイムエラーになったり、
コンパイルの段階で未定義エラーで検出するで良いんじゃないの?
さっぱりわからん。
>特別な仕組み
特別な仕組みとは?
>ライブラリーレベル(srfi-0)
cond-expandという名前が気に食わん。
適当としか思えない・・
456:デフォルトの名無しさん
05/06/20 21:10:30
未定義エラーはリンクの段階かもしれん。
457:デフォルトの名無しさん
05/06/20 23:35:56
>>443
CL使っとけ。
458:デフォルトの名無しさん
05/06/21 01:27:02
cmucl とかアセンブラ(に変換するlisp)で書かれているし。
459:デフォルトの名無しさん
05/06/21 01:35:40
>>457
再発明なんて高々一回程度だよ。
古臭いCL使うぐらいなら再発明も悪くないだろう。
460:デフォルトの名無しさん
05/06/21 02:49:08
CommonLispもSchemeもそうやって作られてきた。
461:デフォルトの名無しさん
05/06/21 06:49:58
>>452 コマンドラインで、clisp -E ASCII とかどう?
462:デフォルトの名無しさん
05/06/22 16:59:02
schemeを始めたんですけどリストを逆順にする関数がわかりません。
(define (reverse lst)
(if (null? lst)
'()
(cons (reverse (cdr lst)) (car lst))))
こうやるとペアになってしまいます。
(reverse '(1 2 3))
((3 2) . 1)
(3 2 1)となるやつをおしえてください。
463:デフォルトの名無しさん
05/06/22 17:29:15
(define (reverse lst) (if (null? lst) '() (append (reverse (cdr lst)) (cons (car lst) '()))))
464:デフォルトの名無しさん
05/06/22 17:42:55
>>462
↓わかりやすい例
(define (my-reverse lst)
(if (null? lst)
'()
(append (my-reverse (cdr lst)) (list (car lst)))))
↓より効率の良い例
(define (my2-reverse lst)
(my2-reverse-1 lst '()))
(define (my2-reverse-1 lst done)
(if (null? lst)
done
(my2-reverse-1 (cdr lst) (cons (car lst) done))))
465:デフォルトの名無しさん
05/06/22 17:48:54
>>463
そりゃ効率が悪いよ。append で同じリストを何回もコピーしてしまう。
こっちの方がいいと思う。
(define (my-reverse list0)
(let loop ((list0 list0)
(result '()))
(if (null? list0)
result
(loop (cdr list0)
(cons (car list0) result)))))
466:465
05/06/22 17:50:23
あ、やっぱりかぶっちゃった。
私のはローカル関数を使って一つにまとめたバージョンということで。
467:デフォルトの名無しさん
05/06/22 18:41:55
こういう片方向のリスト演算って、
他の言語だとしょーもないライブラリ関数や自作関数で
限定的にやるしかないんだよね。
やっぱ年季が違うなあ。
LISPすごい。
468:デフォルトの名無しさん
05/06/22 19:39:23
(define my-reverse reverse)
469:デフォルトの名無しさん
05/06/22 19:54:52
ワラタ。
(setf (symbol-function 'my-reverse) #'reverse)
470:デフォルトの名無しさん
05/06/22 20:01:19
無知丸出しw
471:デフォルトの名無しさん
05/06/22 20:04:33
えー、どうやるの?
472:デフォルトの名無しさん
05/06/22 20:07:53
>>470-471 え、なんかあったの?
473:デフォルトの名無しさん
05/06/22 20:17:37
無知ですいません。
これって Common Lisp だとどう書くのがスマートなんでしょうか?
474:462
05/06/22 21:09:29
理解できました。ありがとう。
475:デフォルトの名無しさん
05/06/23 06:31:50
(define (my-reverse! list0)
(let loop ((list0 list0)
(result0 '()))
(if (null? list0)
result0
(let ((result1 (loop (cdr list0) list0)))
(set-cdr! list0 result0)
result1))))
476:デフォルトの名無しさん
05/06/23 06:49:08
!イラネ!!
477:デフォルトの名無しさん
05/06/23 07:32:30
効率命の破壊的リスト操作なのに、スタックを消費するのがつらいところだのう。
478:デフォルトの名無しさん
05/06/23 08:15:37
(define (my-reverse! lst)
(let loop ((l lst) (r '()))
(if (null? l)
r
(let ((l1 (cdr l)))
(set-cdr! l r)
(loop l1 l)))))
479:デフォルトの名無しさん
05/06/23 19:25:49
(define my-reverse! reverse!)
480:デフォルトの名無しさん
05/06/25 06:39:47
>>165 に書かれてるイベント行った方います?
481:デフォルトの名無しさん
05/06/27 04:36:05
この板にちょくちょく出没している様子のtabesugiのひとが行ったんじゃないか?
482:デフォルトの名無しさん
05/06/27 22:50:00
Scheme のレキシカルスコープは Algol 60 の影響なのでしょうか?
私はラムダ計算の変数の、自由変数と束縛変数による影響だと思った
のですが。
483:デフォルトの名無しさん
05/06/27 22:58:18
1970年代のLispは動的スコープが主流でFUNARG問題に悩んでいた。
それに対するアンチテーゼというか実験としてSchemeという言語が作ら
れたような節はあるね。その後Common Lispにも採用されてLisp界全体
でもレキシカルスコープが主流になるわけだが。
484:482
05/06/27 23:10:36
>>483
もっと計算機よりの実装を知らなければならなかったのですね。
Lisp の歴史を勉強してみてよくわかりました。m(_ _)m
485:デフォルトの名無しさん
05/06/28 08:54:21
Emacsが動的スコープなんで、何でレキシカルスコープじゃないの?とRMSに
尋ねた人によると、「レキシカルスコープは実行速度が遅い」といったそうな。
昔の話。
486:デフォルトの名無しさん
05/06/28 09:22:24
International Lisp Conferenceに参加した人に聞いたんだけど、結構を盛り上がってたって聞いた。
結構人も集まってて、熱心な若者Lisperも結構いたのに驚いたとか。
bioinformatics系のアプリが結構多くて、時代の流れを感じたとか。
当日proceedingsが配布されたけど、後日、
URLリンク(www.international-lisp-conference.org)
から販売するそうな。
487:デフォルトの名無しさん
05/06/28 12:56:20
理解に苦しんでいるstatic scopeの話がちょうど出たようですので、
質問させてください。
;;; 例-A ----------------------------------------
A1> (define foo begin)
A2> (define bar (lambda (a b c) (foo a b c)))
A3> (bar #t 0 1)
;;==> 1
A4> (define foo list)
A5> (bar #t 0 1)
;;==> 1
;;; 例-B ----------------------------------------
B1> (define foo (lambda (m) (- m 3)))
B2> (define bar (lambda (n) (foo n)))
B3> (bar 10)
;;==> 7
B4> (define foo (lambda (m) (+ m 3)))
B5> (bar 10)
;;==> 13
例-Aのほうは、fooをtop-levelで再定義(A4)しても、
barを呼び出したとき(A5)には、手続き定義時(A2)の
環境が使われています。
これはstatic scopeの考え方からすると当然だと
思えるようになりました。
ところが、例-Bのほうは、
fooを再定義(B4)すると、手続き呼び出し時(B5)には
手続き定義時(B2)のfooではなく、再定義されたfooが
使われています。
この違いは何でしょうか?
488:487
05/06/28 13:00:37
失礼。
static scopeではなくて、lexical scopeでした。
489:デフォルトの名無しさん
05/06/28 13:20:54
>>487
変数が既に束縛されている場合の top level での define は set! と同等な
ので例-B が妥当。例-A は A1 で変数に syntax を代入してるけど、変数経由
で syntax を使用した場合の動作は未定義のはず。たぶんその処理系では foo
も syntactic keyword になって、かつ A2 の段階で展開されてしまってるん
じゃないかと思う。
490:487
05/06/28 13:52:58
>>489
ありがとうございます。
> 変数経由で syntax を使用した場合の動作は未定義のはず。
これって、どこかに書いてありますか?
書いてないから未定義なのかな?
ここらへんのことをよく知りたいと思っているのですが、よい
資料はありますでしょうか?
491:デフォルトの名無しさん
05/06/28 17:17:51
>>490
>これって、どこかに書いてありますか?
>書いてないから未定義なのかな?
おれは489ではないのだがちょっと失礼する
R5RSの5.2 Definitionsによれば、定義は
(define <variable> <expression>)
でもって7.1.3. Expressionsにはsyntactic keywordが<expression>になる記述は無い。
だから、(define foo begin)はR5RS的には有効ではないと思われる(例えばPLTとかchezとかはシンタックスエラーとなる)
しかし1.3.2 Error situations and unspecified behaviorによれば処理系にそのエラーの報告義務は無い。
つまり動作は未定義で処理系依存でよいということであり、(define foo begin)などが通る場合は処理系独自の拡張の結果という事だと考えて良いと思うんだけど.......これでいいのかな?皆の衆
492:487
05/06/28 20:17:38
>>491
なるほどR5RSはそういう読み方をしなければいけないんですね。
私が試した処理系のほとんど(kawa,guile,gosh)では
>>487例-Aのようになったので、そうあるべきなのかと思いこんでいました。
唯一biglooと個人的に使っているマイナーな処理系では
同様のコードを読ませると、手続き定義後の変更も反映されて
A3>==> 1
A5>==> (#t 0 1)
となります。
厳密にはエラーなんですね。
489さん、491さん、ありがとうございました。
493:デフォルトの名無しさん
05/06/30 05:47:08
かっちょえー
URLリンク(lemonodor.com)
494:デフォルトの名無しさん
05/07/02 08:50:26
>>486
日本人もたくさん参加してたのかな?
495:デフォルトの名無しさん
05/07/03 21:51:02
すいません
入れ子のリストの中身を調べて
最も大きい値を返す関数の定義という問題なのですが、
例えば(al-max'((1 3)((9)4)))を与えた時9を返すような
定義を教えて頂きたいのですが。
どのようにすれば良いのでしょうか?
入れ子を考えなければ
(defun max1(x)(cond((null (cdr x))(car x))((<= (max1(cdr x))(car x))(car x))(t(max1(cdr x)))))
このようになるんですけど。入れ子だと良く分かりません。
496:デフォルトの名無しさん
05/07/03 22:13:31
>>495
scheme だけど。
URLリンク(www.geocities.co.jp)
fold-tree っぽいものは標準であってもいいような気がするんだけどなあ。
497:495
05/07/03 22:32:44
>>496
ありがとうございます。
サイト見ましたが高級関数を定義とか
ユーティリティ関数とかさっぱり分かりません。
具体的にはどうすればいいですかね?
498:デフォルトの名無しさん
05/07/03 22:45:38
(defun al-max (lst)
(cond ((numberp lst) lst)
((null (cdr lst))
(al-max (car lst)))
(t (max (al-max (car lst))
(al-max (cdr lst))))))
499:495
05/07/03 22:48:47
>>498
ありがとうございます!
感謝です。
500:デフォルトの名無しさん
05/07/03 23:01:11
(defun al-max (x)
(if (listp x) (apply #'max (mapcar #'al-max x)) x))
501:495
05/07/03 23:05:49
すいませんmax使わないで作ることって事出来ますかね?
502:デフォルトの名無しさん
05/07/03 23:08:35
max
503:デフォルトの名無しさん
05/07/03 23:09:26
max を使いたくないなら、自分で max を書けばいいじゃない。
504:デフォルトの名無しさん
05/07/04 00:03:01
>>503
そうですね、ありがとうございました。
505:デフォルトの名無しさん
05/07/04 00:55:21
こっそりGauche 0.8.5が来てた。
506:デフォルトの名無しさん
05/07/04 06:08:07
(al-max '()) の時はエラーですね。
507:デフォルトの名無しさん
05/07/04 22:26:42
cmuclはまだwindowsでは動かんのか?
508:デフォルトの名無しさん
05/07/04 22:59:59
何の為に?
509:デフォルトの名無しさん
05/07/05 00:24:57
>>508
何のためにって・・・Lispがネイティブに落ちるなら色々使えるじゃん。
いつまでもウニ系しか使えないからLispはマイナーなんだよ
510:デフォルトの名無しさん
05/07/05 00:59:05
テツ&銀行・リスプを使えって、外国のおにいちゃんがゆってた
511:デフォルトの名無しさん
05/07/05 01:05:16
鉄銀行もWindows版はまだじゃなかったっけか
512:デフォルトの名無しさん
05/07/05 04:50:41
なんでお前の話はすぐループするのか?一ヶ月前の有意義な話を、単に煽りの材料に転用しただけ。
お前の頭のねじれ具合は笑えるな。すげーおもしれえ。ちょーうけた。さいこー。
513:デフォルトの名無しさん
05/07/05 04:54:27
KCLは20年前からネイティブコードで走ってるけど、何か?
514:デフォルトの名無しさん
05/07/05 17:23:06
長くなってすみません。
Schemeの手続きとそのスコープについて教えてください。
たとえば
[ソースコード]------------------------------------------------------------
.1: (define a_proc
.2: (lambda (n k)
.3: (if (null? n)
.4: ; true-clause
.5: (begin
.6: (newline)
.7: (write 'true-clause) (newline)
.8: (write 'n=) (write n) (newline)
.9: (write 'k=) (write k) (newline)
10: (k '()))
11: ; false-clause
12: (begin
13: (newline)
14: (write 'false-clause) (newline)
15: (write 'n=) (write n) (newline)
16: (write 'k=) (write k) (newline)
17: (a_proc (cdr n)
18: (lambda (u)
19: (write 'n=) (write n) (newline)
20: (write 'k=) (write k) (newline)
21: (write 'u=) (write u) (newline)
22: (k (append n u))))))))
23: (a_proc '(a) (lambda (x) x))
というコードを処理系に読ませると、
515:デフォルトの名無しさん
05/07/05 17:24:47
>>514の続き
[出力結果]----------------------------------------------------------------
.1> false-clause
.2> n=(a)
.3> k=#<closure (x) x>
..>
.4> true-clause
.5> n=()
.6> k=#<closure (u)
..> (write (quote sub-clause)) (newline) \
..> (write (quote k=)) (write k) (newline) \
..> (write (quote n=)) (write n) (newline) \
..> (write (quote u=)) (write u) (newline) \
..> (k (append n u))>
..>
.7> n=(a)
.8> k=#<closure (x) x>
.9> u=()
10> (a)
のような結果が得られます。
516:デフォルトの名無しさん
05/07/05 17:26:14
>>514の続き(ここまで)
ソースコードは末尾再帰になっているので、
a_procのスコープは呼び出しにかかわらず単一であると考えると、そのスコープ内で
2>~3>で表示されている最初の束縛関係が、一度5>~6>のように変更されています。
ところが、18:~22:で内部手続きを作成すると、そこでは、
変更されたの束縛関係(5>~6>)ではなく最初の束縛関係(7>~8>)に戻っています。
R5RS 4.1.4 Procedures には
The environment in effect when the lambda expression was evaluated is
REMEMBERED as part of the procedure.
とあります。
この「REMEMBER」という語は「そのScopeへの参照を記憶する」ことを意味すると
理解していたのですが、上の実験結果を見る限り
「そのScopeを元に作成した複製を保持する」と解釈すべきなのでしょうか?
全く思い違いをしているかもしれません。ご指摘ください。
517:デフォルトの名無しさん
05/07/05 18:23:24
まあ、一般論だが「考えると」いう条件つきで考えると、前提が間違っている
せいで予想と違ってしまうようだ。
518:デフォルトの名無しさん
05/07/05 19:25:05
>>517
間違えている前提を指摘してください。
お願いします。
519:デフォルトの名無しさん
05/07/05 19:54:14
自分で書いた文章の読解もできないの?
520:デフォルトの名無しさん
05/07/05 19:58:53
「a_procが末尾再帰になってない」ということでしょうか。
それとも「a_procのスコープは単一ではない」ということでしょうか。
521:デフォルトの名無しさん
05/07/05 20:16:38
dynamic scope と lexical scope との違いを理解しましょう
522:デフォルトの名無しさん
05/07/05 21:52:01
>>520
末尾再帰とスコープを関連づけているのはなぜですか
523:本田
05/07/05 22:54:51
>>513 :デフォルトの名無しさん :2005/07/05(火) 04:54:27
> KCLは20年前からネイティブコードで走ってるけど、何か?
KCLのコンパイラはC言語にコンパイルするはず。
524:デフォルトの名無しさん
05/07/05 22:58:46
C 言語は ASM にコンパイルされるし、ASM は機械語に変換される。
C にしない処理系でも IL に変換されたりするし、C にコンパイルしていても
最終的にネイティブコードになる事には変わりない。
525:デフォルトの名無しさん
05/07/05 23:34:23
>>522
疑問に思ったのがこのコードを実行してみてだったので、
そのまま質問してしまいました。
末尾再帰は直接関係ありません。
手続きを定義するときにその手続きは定義時の環境を「覚えて」いて、
手続きを呼び出したときにはその環境内で手続きが評価される、と
理解しています。
514の質問の意図は、作られた手続きが保持しているものが
(1)手続き作成時の環境そのもの(シンボルテーブルなど環境内の要素を含む)
なのか、
(2)手続き作成時の環境への参照またはポインタ
でよいのか、についての答えをいただきたいということでした。
(2)でよいと思っていたのですが、もしそうだとすると、>>514の例では
手続き18:の環境は手続き2:と共有されるために、束縛関係が書き換えらてしまい、
実際の結果の説明ができません。
ということは、手続き定義時には、そのときの環境が複製され、
定義された手続き固有の(他の手続きなどからアクセスできない)
環境となって保持される、ということでよいのでしょうか。
526:デフォルトの名無しさん
05/07/05 23:42:52
根本的に変な固定概念に取り憑かれているようだな。憑き落とししなきゃ。w
527:デフォルトの名無しさん
05/07/06 00:20:41
>>525
参照とかポインタとか複製とか実装の観点から考えないほうがいいですよ
文字通り「字面上の」スコープに縛られるんです
; それをどう実装するかは別の話
528:デフォルトの名無しさん
05/07/06 02:35:31
>>523
それが何か?
529:デフォルトの名無しさん
05/07/06 02:37:20
>>525
>>521 を勉強汁
530:デフォルトの名無しさん
05/07/06 02:43:08
SICPに載ってる環境モデルでええやん
531:デフォルトの名無しさん
05/07/06 03:33:24
必要以上に深く考え過ぎ。しかも間違った方向に。
532:デフォルトの名無しさん
05/07/06 04:58:04
學而不思則罔、思而不學則殆 ってやつだな。あやうくてしかたない。
533:デフォルトの名無しさん
05/07/06 09:02:31
>>530
>SICPに載ってる環境モデルでええやん
知りたかったのはまさにこれです。
ありがとうございました。
534:デフォルトの名無しさん
05/07/06 17:37:37
SICPが名著だと言われるゆえんを実感しました。
535:デフォルトの名無しさん
05/07/06 18:22:40
油煙
536:デフォルトの名無しさん
05/07/06 18:25:04
SICPって何ですか?
537:536
05/07/06 18:26:01
って >>6 に書いてあったですね スマン
538:デフォルトの名無しさん
05/07/07 20:09:49
いや、普通わからんて
Structure And Interpretation Of Computer Programs
すとらくちゃーあんどいんたーぷりてーしょんおぶこんぴゅーたぷろぐらむす
コンピュータープログラムの構造と解釈
略してSICPという。
え?
SAIOCPじゃないの?
AとOはどこいったよ?
なあ?
普通わかんねーよなあ
ところで
SICPって何て読むか知ってるか?
俺は知らないが
しくぷとか発音すると馬鹿にされそうで
恐い
539:デフォルトの名無しさん
05/07/07 20:17:20
ここは Lisp/Scheme スレだから SICP で十分通じる。
俺の脳内ではシックピーって読んでるよ。
540:デフォルトの名無しさん
05/07/07 20:19:36
お前の脳内の事なんか聞いてない
541:デフォルトの名無しさん
05/07/07 20:22:23
あ、ごめん
間違えて書き込むボタン押しちゃったよ
こういうのは本来書き込むべき内容ではなかったが、
名無しだからいいやと思ってしまうな
匿名って恐いな
2chにいるとどんどんクズ人間になっていく気がする
おれのこと軽蔑した?
悪かったよごめんな
542:デフォルトの名無しさん
05/07/07 20:49:05
接続詞は頭文字に含めないことくらい普通は知ってる
543:デフォルトの名無しさん
05/07/07 20:50:13
>>541 ドンマイ、しかし、貢献するべし
544:デフォルトの名無しさん
05/07/07 20:59:23
さて、そろそろ LISP の話 キボンヌ
545:デフォルトの名無しさん
05/07/08 13:25:12
>>542
前置詞もな
あと冠詞
他に何かあったっけ?
SICPよりも LISP の方がわかりにくい。
LISt Processor
546:デフォルトの名無しさん
05/07/08 14:30:34
LITHP (LITHtth Prothethor)
John Unger Zussman が冗談で作った架空言語。
1982年Infoworldが出した「あまりよく知られていない言語」という書籍の面白言語リストに掲載され、
後にUsenetに投稿された。この架空言語の本質は、「もしLisperのキーボードに"S"が無かった」という発想である
547:デフォルトの名無しさん
05/07/08 14:34:42
S式はTH式になるのか?
まあ算盤も広い意味では計算機だがな
548:デフォルトの名無しさん
05/07/08 23:38:15
すいません、質問なのですが、
(p'((1)2 3))
とすると
1 2 3
と表示する、括弧を取り除いて表示するような
関数pはどのように定義すればよいのでしょう?
549:デフォルトの名無しさん
05/07/08 23:38:45
↑は(1 2 3)と表示する、の間違いでした。
550:デフォルトの名無しさん
05/07/08 23:46:19
>>548
(defun p (x)
(if (listp x)
(mapcan #'p x)
(list x)))
551:デフォルトの名無しさん
05/07/08 23:54:24
>>550
ありがとうございます!
mapcanと#の意味がわからないんですけど
これはどういうことですか?
552:デフォルトの名無しさん
05/07/08 23:58:27
>>551
Common Lisp 勉強汁
553:デフォルトの名無しさん
05/07/08 23:59:42
>>551
mapcanはmapcarと同じ動作をした後に各館数の返り血をappendで連結した物を返す関数。
#`はそのシンボルを関数として扱うという意味。
554:デフォルトの名無しさん
05/07/09 00:04:19
>>552-553
よくわかりました。
本当にありがとうございました。
555:デフォルトの名無しさん
05/07/09 00:06:49
>>553
重箱の隅ですまんが append ではなく nconc、#` ではなく #' だね。
556:デフォルトの名無しさん
05/07/09 02:43:36
素人質問への解答乙。
つか、明らかに荒らしだよなこいつの質問は。
557:デフォルトの名無しさん
05/07/09 02:44:24
基本的な関数のみで書いた、初心者向け版。
(defun p (x)
(if (null x) '()
(if (consp (car x))
(append (p (car x))
(p (cdr x)))
(cons (car x)
(p (cdr x))))))
558:デフォルトの名無しさん
05/07/09 03:01:55
Scheme には mapcan が無いとお嘆きの貴兄に、Scheme 版。
(define (p x)
(if (list? x)
(apply append (map p x))
(list x)))
559:デフォルトの名無しさん
05/07/09 03:49:56
nconc や append! を使う自信が無くて、つい append を使ってしまう自分。
560:デフォルトの名無しさん
05/07/09 09:51:51
(defun p (x)
(cond ((null x) '())
((consp x)
(nconc (p (car x))
(p (cdr x))))
(t (cons x '()))))
(p '((x . y) (x)))
561:デフォルトの名無しさん
05/07/09 16:49:29
>>559
静的関数型言語方面じゃ型推論と同じなノリで、
破壊しても問題ないと推論される場合には破壊的にやっちゃうようなコードを吐かせよう、
みたいなことやってるみたいね。
URLリンク(sky.zero.ad.jp)
562:デフォルトの名無しさん
05/07/09 19:21:50
>>548
うまいこと宿題やってもらえて良かったね。
563:デフォルトの名無しさん
05/07/09 21:46:39
最近に処理系では破壊的な方が速いとは限らない
みたいなことがANSI Common Lisp(P. Graham)に書いてあったんだけど、そんなもんなのかね。
どうしたらそうなるのか見当もつかないんだが。
564:デフォルトの名無しさん
05/07/09 22:03:44
gcがめちゃくちゃ速いから?
565:デフォルトの名無しさん
05/07/09 22:15:14
Write Barrier のコストとか。
566:デフォルトの名無しさん
05/07/10 00:09:20
copy on write とか?
567:デフォルトの名無しさん
05/07/10 00:14:17
URLリンク(www.ai.mit.edu)からcl-http-70-190a.tar.gz落として
cmuclで動かそうとしたんだけどパッチすらあたらなかった。
うまく動作してる人いない?
568:デフォルトの名無しさん
05/07/10 02:21:43
>>561
ああっ、それいいなあ。
LISP と関数型言語の差って、何でも自分でいじれるオフロード車と、外装内
装に便利なものが作り込まれたタウンカーの差みたいなものかな。
569:デフォルトの名無しさん
05/07/11 22:48:53
総称関数モデルがメッセージ駆動モデルよりも強力だといえるのは何故?
メリットとかデメリットとか教えて欲しい。
570:デフォルトの名無しさん
05/07/11 23:08:22
>>569
メッセージ駆動モデルって何?
571:デフォルトの名無しさん
05/07/12 00:21:25
>>570
メソッドはオブジェクトに属していて、オブジェクトにメッセージを送ることでメソッドが活性化される。
メソッドはデータと一緒に継承される。
SmalltalkとかJavaとかはメッセージ駆動モデルなんだって。
572:デフォルトの名無しさん
05/07/12 00:29:57
それって総称関数のサブセットじゃないか
573:デフォルトの名無しさん
05/07/12 02:54:29
Lisp 関係の古典がオンラインで読めるようになったので一応アドレス貼っておきますね。
John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart and Michael I. Levin.
LISP 1.5 Programmer’s Manual.
The M.I.T. Press, 1962, second edition.
URLリンク(community.computerhistory.org)
Berkeley and Bobrow, editors.
The Programming Language LISP: Its Operation and Applications.
Information International, Inc., March 1964 and The MIT Press, April 1966.
URLリンク(community.computerhistory.org)
574:デフォルトの名無しさん
05/07/12 03:50:45
>>571
そういう話は無益だから止めれ
Java にメッセージ式は無い
Smalltalk のメソッドはクラスに属している(クラスもオブジェクトだけど)
575:デフォルトの名無しさん
05/07/12 09:17:12
Rubyyyyyyyyyyyyyyyyyyyyyyyy
576:デフォルトの名無しさん
05/07/12 17:19:47
とりあえず総称関数だとマルチメソッドが考えやすい。レシーバーだけでなく、複数の引数のクラスで処理を分けたいときに便利。
その分、メソッドが特定のクラス(やオブジェクト)に属さないのでオブジェクト指向モデリングとやや相性が悪い。
総称関数の方ができることが多い(いや、究極的にはできることは同じだけどやり易さとして)けど、オブジェクト指向とはちょっと考え方が違う感じ。メッセージモデルの方がオブジェクト指向らしい。
もっと計算理論的な話は別の人に任す。
577:デフォルトの名無しさん
05/07/12 21:51:56
複数引数の型を見て処理を割り振る話(メソッド・ディスパッチだっけ?)について。
多くのOO言語では、静的な解決しかできない。
総称関数ベースなら、呼び出された時の型を見て動的に処理を割り振ることができる。
これがメリット?
578:デフォルトの名無しさん
05/07/12 22:15:42
>>577
マルチディスパッチと動的ディスパッチは一応別の問題だよね。
Smalltalkなんかはシングルの動的ディスパッチじゃないかな。
静的なマルチディスパッチの例としてはC++の関数や演算子ね。
579:デフォルトの名無しさん
05/07/12 22:20:22
えぇ~とLispのは、具体的なメソッド選択を明示的に書く仕組みだったと思います。(実使用体験0、80年代のbit記事受け売り)
ってな話だと、>>578とは違うんじゃないかなぁ~。
580:デフォルトの名無しさん
05/07/12 22:39:20
>>577
>多くのOO言語では、静的な解決しかできない。
んな事は無い
581:577
05/07/12 22:42:26
>>580
そのとおり。
でも、引数を親クラスにキャストしてメソッド呼出したら、、、
582:デフォルトの名無しさん
05/07/12 22:53:23
何でキャストの話が出て来るんだよ
OO のモデルなんか趣味の世界だから、自分で使って勝手に判断すれば良い
583:577
05/07/13 00:00:29
なんだぁ?ヴァカか。
584:デフォルトの名無しさん
05/07/13 01:03:28
では、そろそろ LISP の話に戻りましょうか
585:デフォルトの名無しさん
05/07/13 02:14:15
まとめると
総称関数だといくつかのクラスにまたがった複数引数をとるメソッドがかける
ってことか
586:デフォルトの名無しさん
05/07/14 15:03:45
SICPの5.4 The Explicit-Control Evaluatorで、
> Our Scheme evaluator register machine includes a stack and
> seven registers: exp, env, val, continue, proc, argl, and unev.
とあるのですが、unevという名前の意味や由来は何なのでしょうか?
他のものは一目瞭然なのですが、unevだけ全く見当がつきません。
587:デフォルトの名無しさん
05/07/14 15:09:51
>>586
unevaluated (未評価)かな?
588:586
05/07/14 19:58:40
>>587
なるほど!
確かに「後で評価する式を格納しておく」という使い方をされてますから、
それで正解だと思います。ありがとうございました。
ああすっきりした! 今日は気持ちよく眠れる!
589:デフォルトの名無しさん
05/07/22 14:37:51
xn(n ∈ N)は,次のように再帰的に定義することができる.
xn = xm×xm (n = 2m,m >= 1)
= x×xm×xm (n = 2m+1,m >= 0)
= 1 (n = 0)
これを利用して,xnを計算する2引数関数pow2を定義せよ.なお,再帰呼び出しの回数をできるだけ減らすようにすること.
これ教えてもらえませんでしょうか…
解答例をお願いします。。。
590:589
05/07/22 14:41:15
あぁ、書き忘れ。schemeです。
591:デフォルトの名無しさん
05/07/22 15:03:50
夏休みの宿題くらい自分でやれ
592:デフォルトの名無しさん
05/07/22 15:27:50
「できるだけ」ってのがひっかかるな。
593:デフォルトの名無しさん
05/07/22 15:39:49
どうしてもループに直せないおバカ救済用じゃね?
594:デフォルトの名無しさん
05/07/22 15:55:59
Lispもschemeもうぜえええええええええ
595:589
05/07/22 16:02:10
出来ないからこうして書いてるんです( ´,_ゝ`)
596:デフォルトの名無しさん
05/07/22 16:14:52
出来ないなら教官に質問しにいくとかすれば?
出来ないことを色々考えて出来るようになるのが学生の仕事だろ?
ロクに考えもせずに答教えろとか言う奴は単位なぞ落としてしまえ。
597:デフォルトの名無しさん
05/07/22 16:36:44
最近の小学校はScheme教えてるのか。すごいな。
598:デフォルトの名無しさん
05/07/22 18:16:05
※しょうがくせいのみんなへ
・なつやすみのしゅくだいは、じぶんでやりましょう。
599:?デフォルトの名無しさん
05/07/22 22:03:21
Schemeの問題で
>再帰呼び出しの回数をできるだけ減らすようにすること
ってのはどんなんだろうね?
再帰をなるべく末尾再帰にしろってんならいいんだけど。
600:デフォルトの名無しさん
05/07/22 23:29:41
x は関数または演算子なんだよね?x×(xm×xm)って、演算子と整数の
積なの?意味がわからない。
601:デフォルトの名無しさん
05/07/22 23:43:50
頭悪いのを披露するためだけにわざわざ横から出てきてごくろうさん。
602:600
05/07/22 23:45:57
あ、問題を読み間違えていた。
603:ビッケ ◆Jyl0Z1ahKc
05/07/22 23:52:54
xnなどと書かれているのはベキ乗 x^n のことでしょう。
「再帰呼び出しの回数」については、設問中のベキ乗の定義を見ると
再帰呼び出しのネスティングの深さのことを言ってるのかも知れませんね。
その授業(?)でそういうことを扱った直後の演習問題とか。
「できるだけ」なんていわれても困るけど、設問中の定義に従って
ネスティングの深さがO(log n)となる定義を書けばOKということなのかも。
604:デフォルトの名無しさん
05/07/23 00:02:33
ちゃんと自分の頭で噛み砕いて質問すれば親切な香具師は答えてくれる
かもしれんが、ここまで露骨に「宿題やって」だと誰も答えてくれんわな。
605:デフォルトの名無しさん
05/07/23 00:12:28
これ、ループに直せるの?定義が再帰的だから、どうしてもループには出来ないや。
末尾再帰も無理っぽい。
結局、let (let*) で途中経過をまとめるぐらいしかできないよ。こまった。
606:デフォルトの名無しさん
05/07/23 00:19:22
これ定義どおり実装するなら幼稚園児向けの問題で面白くもなんともないじゃん。
おまいら小学生ならもっと頭を使おうぜ。w
607:デフォルトの名無しさん
05/07/23 00:19:34
(define (pow2 x n)
(let loop ((x x) (n n) (r 1))
(if (= n 0) r
(loop (* x x) (quotient n 2) (if (even? n) r (* r x))))))
608:デフォルトの名無しさん
05/07/23 00:33:24
>>607
きれいだけど、定義から離れすぎてない?
漏れの頭では、>>589 の定義からは、これを自明には導き出せない…。
609:デフォルトの名無しさん
05/07/23 00:47:05
>>607 が >>589 の定義と同値かどうかは興味深い問題だね。
"1" が "×" の単位元でない場合とか "×" が可換でない
場合とかを考えるとちゃんとした証明が必要かも。
610:デフォルトの名無しさん
05/07/23 01:58:59
(define (pow2 x n) (apply * (vector->list (make-vector n x))))
611:デフォルトの名無しさん
05/07/23 02:10:26
>>608
>>589 をそのまま実装すると
(define (pow2 x n)
(if (= n 0) 1
(let ((x1 (pow2 x (quotient n 2))))
(* x1 x1 (if (even? n) 1 x)))))
x^n * x^n = (x * x)^n だから
(define (pow2 x n)
(if (= n 0) 1
(* (pow2 (* x x) (quotient n 2)) (if (even? n) 1 x))))
末尾再帰に変換して >>607
612:デフォルトの名無しさん
05/07/23 02:30:33
>>611
ありがとう。おかげで疑問点がはっきりしてきました。
x^n * x^n = (x * x)^n って、使っていいの?
我々は pow2 が累乗を返す関数だと知っているから、この変形は自然に見えるけど、
この問題で使っていいのは、あくまで
pow2(x, 2n) = pow2(x, n) * pow2(x, n)
pow2(x, 2n + 1) = x * pow2(x, n) * pow2(x, n)
pow2(x, 0) = 1
の3式だけではないんだろうか?
613:デフォルトの名無しさん
05/07/23 02:53:57
なるほど、確かに
pow2(x * x, n) = pow2(x, n) * pow2(x, n) は自明ではないな。
614:デフォルトの名無しさん
05/07/23 03:24:59
(define pow2 expt)
615:デフォルトの名無しさん
05/07/23 03:43:39
>>612-613
pow2(x, 0) * pow2(x, 0) = pow2(x * x, 0) = 1
pow2(x, n) * pow2(x, n) = pow2(x * x, n) とすると
定義より pow2(x, n + 1) = x * pow2(x, n) (これも証明する?) なので
pow2(x, n + 1) * pow2(x, n + 1) = x * pow2(x, n) * x * pow2(x, n)
= (x * x) * (pow2(x, n) * pow2(x, n)) = (x * x) * pow2(x * x, n)
= pow2(x * x, n + 1)
以上から数学的帰納法により pow2(x, n) * pow2(x, n) = pow2(x * x, n)
616:デフォルトの名無しさん
05/07/23 05:11:48
>>615
数学的帰納法を使ったら pow2 の一般項 =x^n だって証明できてしまうと思われ。
そもそも関数の再帰的定義とは数学的帰納法を機械にやらせることなのに、
それを人間がやってしまったら本末転倒ではないかと。
617:デフォルトの名無しさん
05/07/23 06:39:58
ん? 元々 x^n を求める pow2(x, n) を定義せよって話でしょ。
x^2n = x^n * x^n
x^(2n+1) = x * x^n * x^n
x^0 = 1
となる性質を使えって条件があるだけで。
618:デフォルトの名無しさん
05/07/23 10:34:49
求める関数を pow2(x,n), s(x,n)=log_x pow2(x,n) とおくと、pow2 漸化式は次のようになる。
s(0,x)=0
s(2n,x)=2*s(n,x)
s(2n+1,x)=2*s(n,x)+1
ここまで見ると何となく s(n,x)=n になりそうな事が見えて来るが、
帰納法を使わず直観的に考えてみる。
s(n,x)の",x"を以後省略することとし、
nの2進表記を b_n...b_1b_0 とすると
s(b_n...b_1b_0)
=2*s(b_n...b_1)+b_0
=4*s(b_n...b_2)+2*b_1+b_0
...
=2^n*b_n+...+2*b_1+b_0
すなわち s(n)=n となる。
よって pow2(x,n)=x^n である。
故に>>614
619:デフォルトの名無しさん
05/07/24 19:52:58
でもってexptを高速化する手法の一つが今回の問題だったんでないかい?
620:デフォルトの名無しさん
05/07/24 20:17:31
ヒント:exptは浮動小数でも(略)
621:デフォルトの名無しさん
05/07/24 21:58:13
R5RS には (expt EXACT INTEGER) => EXACT とは書いてないから
(define (expt x n) (exp (* (log x) n))) な実装もアリ。
だから処理系に依存せずに EXACT ^ INTEGER => EXACT が欲しければ
自前で書くしかない。
Common Lisp だと (expt RATIONAL INTEGER) => RATIONAL が保証
されてるのに……
622:デフォルトの名無しさん
05/07/25 08:43:33
>>621
ふが~ おれ (expt 2 128) とかがEXACT INTEGERで正確に得られることを期待してコード書いてたけど、これ処理系依存になっちまうのか....いたいぜ。
623:デフォルトの名無しさん
05/07/25 08:53:40
>>620
意味不明。(略)が(おれは無知です)の意味ならどうでもいいけど。
624:デフォルトの名無しさん
05/07/25 09:04:10
expt は "Finally, the procedures listed below will always return
an exact integer result provided all their arguments are exact
integers and the mathematically expected result is representable
as an exact integer within the implementation:" の中にある。
625:デフォルトの名無しさん
05/07/25 10:30:53
>>624 THX!
626:デフォルトの名無しさん
05/07/25 17:31:11
エキスパートシステムで、たとえば「stop」と入力した場合、
強制終了させるにはどうしたらいいんですか?
627:デフォルトの名無しさん
05/07/25 17:32:57
「stop」と入力されたときに強制終了すれば良いと思う。
628:デフォルトの名無しさん
05/07/25 17:37:21
>>627
強制終了の仕方を教えてください
629:デフォルトの名無しさん
05/07/25 18:03:19
>>628 期待した答えが返って来ないときは、質問のしかたが
間違ってる可能性が高いよ。
開発者なら、どういう言語のどういう処理系を使っていて、
どういう風に大域脱出したいのかを説明しないと。
けど、その前に近くにいる人に聞きなさい。それができない
なら電源をいきなり切ってボスに辞表を叩きつければ、仕事を
強制終了できるよ。
630:デフォルトの名無しさん
05/07/25 20:12:54
人生を強s(ry
631:デフォルトの名無しさん
05/07/25 20:15:08
人生を強すぎる精神力で乗り切る。
632:デフォルトの名無しさん
05/07/26 23:14:30
>>623
exptは浮動小数でも動くから、pow2がexptを高速化するという命題は
常に成り立たないということだよカス。
633:デフォルトの名無しさん
05/07/27 01:54:37
ところでpow2って掛け算の回数最小になるんだろうか?
証明できるor反例ある?
634:デフォルトの名無しさん
05/07/27 02:15:48
3つ以上の項を一度に乗算する命令でも想定しない限りは自明だろう。
それくらい瞬間的にわからないというのはちょっとヤバイのでは。
pow2(x, n)=x^nについて考える。末端リーフがn個の二分木を考えてみろ。
二分木で高さが最小になるのはなるべく均等な木のときであることはわかるだろう。
その二分木の高さイコール乗算の回数だ。
635:デフォルトの名無しさん
05/07/27 02:42:10
ごめん、大嘘でした。
>>634はnが奇数のときは2を掛けるから偶数のときで乗算の数が違う
ということを見落としてた。
(^ x 9) = (* x (let ((y (^ x 4))) (* y y))) => 6回
(^ x 4) = (let ((y (^ x 2))) (* y y))) => 4回
(^ x 2) = (let ((y (^ x 1))) (* y y))) => 3回
(^ x 1) = (* x (let ((y (^ x 0))) (* y y))) = x ;; ちょっと省略 => 2回
(^ x 7) = (* x (let ((y (^ x 3))) (* y y))) => 6回
(^ x 3) = (* x (let ((y (^ x 1))) (* y y))) => 4回
(^ x 1) = x => 2回
636:デフォルトの名無しさん
05/07/27 04:38:27
>>633 乗算回数最小はこれでどうだろう? 最速かどうかは知らない。
(define (pow2 x n)
(define (pow2-sub l m r)
(if (= m 0) r
(let loop ((l l))
(if (> (caar l) m) (loop (cdr l))
(pow2-sub (cdr l) (- m (caar l)) (* (cdar l) r))))))
(if (= n 0) 1
(let loop ((m 1) (two^prevm 1) (two^m 2) (r x) (l (list (cons 1 x))))
(if (<= two^m n)
(let ((rr (* r r)))
(loop (+ m 1) two^m (+ two^m two^m) rr (cons (cons two^m rr) l)))
(pow2-sub l (- n two^prevm) r)))))
637:デフォルトの名無しさん
05/07/27 04:45:26
回数はこんな感じ。左から指数n、r=3^n、(expt 3 n)と比較しての検証、乗算の回数。
n=0 r=1 [OK] *-count=0
n=1 r=3 [OK] *-count=0
n=2 r=9 [OK] *-count=1
n=3 r=27 [OK] *-count=2
n=4 r=81 [OK] *-count=2
n=5 r=243 [OK] *-count=3
n=6 r=729 [OK] *-count=3
n=7 r=2187 [OK] *-count=4
n=8 r=6561 [OK] *-count=3
n=9 r=19683 [OK] *-count=4
n=10 r=59049 [OK] *-count=4
n=11 r=177147 [OK] *-count=5
n=12 r=531441 [OK] *-count=4
n=13 r=1594323 [OK] *-count=5
n=14 r=4782969 [OK] *-count=5
n=15 r=14348907 [OK] *-count=6
n=16 r=43046721 [OK] *-count=4
n=17 r=129140163 [OK] *-count=5
n=18 r=387420489 [OK] *-count=5
n=19 r=1162261467 [OK] *-count=6
n=20 r=3486784401 [OK] *-count=5
638:デフォルトの名無しさん
05/07/27 13:21:00
いきなり横レスですみません、超初心者です。こことSICPのスレは
とても勉強になるので感謝してます。上のアイデアというか原理は
たとえば 3^20 = (3^4)^5 = ((3^2)^2)^(2*2+1) で5回って意味でしょうか?
……うぅぅ凄すぎて式が追えないorz
639:デフォルトの名無しさん
05/07/27 20:58:21
順番が前後するが
3^20=3^16*3^4 ... 1回
3^16=3^(2^4)=(((3^2)^2)^2)^2 ... 4回
3^4は3^16を求める途中で得られているので0回
合計5回
640:デフォルトの名無しさん
05/07/27 23:36:31
s/順番が前後するが/話が前後するが/
641:デフォルトの名無しさん
05/07/28 00:25:58
あほ
642:デフォルトの名無しさん
05/07/28 22:57:26
>>632
最初からそう書けよ。
相手する価値もないヤシだってすぐわかるからさ。
643:638
05/07/29 04:53:54
>>639 レスありがとうございます。やっと SICP の1.2.4節に辿り着きました
URLリンク(mitpress.mit.edu)
後半の改善策が >>589 と同じ例題で、
;nが偶数なら b^n = (b^(n/2))^2
;nが奇数なら b^n = b*b^(n-1)
解答も >>607 と似てました。これを使った乗算回数は、たとえば
3^20 = (3^10)^2 = ((3^5)^2)^2 = ((3*3^4)^2)^2 = ((3*((3^2)^2))^2)^2
で理屈上は>>636と同じ5回(でも実は末尾で余計に1掛けたりとかで、少し多そう)。
オーダーとしてはどちらも log2(n) で、>>634の話が実は正しいような気がしました
Orders of Growth を理解するための頭の体操とはいえ、疲れた…
まだ木構造リストの演算をきちんと勉強してないので、勘違いしてたらすみません
644:デフォルトの名無しさん
05/07/29 23:03:59
age
645:デフォルトの名無しさん
05/08/08 17:23:07
a
b
c
d
dd
e
f
g
h
i
j
k
というインデント付きのテキストから
(a b (c (d (dd) e) f g (h (i)) j) k)
というリストを得たいのですが、
どうやったらうまく書けるかいまいちよくわかりません。
再帰を使えばよさそうというのはわかるんですが。
スタックみたいなバッファが必要でしょうか?
ちなみにテキストデータの仕様は
半角2文字インデントで1階層を表現して、
ddみたいな数階層上のインデントがあっても直前の階層の1つ上とみなす。
a, b, c ・・・はシンボルです。
646:デフォルトの名無しさん
05/08/08 17:35:29
入力の話を簡単にするために、
((a 0)
(b 0)
(c 2)
(d 4)
(dd 12)
(e 4)
(f 2)
(g 2)
(h 4)
(i 6)
(j 2)
(k 0))
という(シンボル インデント文字数)という組のリストから
(a b (c (d (dd) e) f g (h (i)) j) k)
という形に直すにはどうしたらいい?
ということでお願いします。
逆の変換は簡単にできそうなんですが・・・。
647:デフォルトの名無しさん
05/08/08 18:28:54
どっかの宿題?
648:デフォルトの名無しさん
05/08/08 18:34:19
いいえ、思いつきです。。
ちなみに25過ぎのおっさんですよ。。
649:デフォルトの名無しさん
05/08/08 18:46:54
つーか久しぶりにSchemeやってんだけど
頭固くなってるというか、頭悪くなってる。
仮にeまでだとして、
スタックで持ちまわって
((a))
↓
((b a)) ;; 同一インデントはそのままスタック先頭にcons
↓
((c) (b a))
↓
((d) (c) (b a))
↓
((dd) (d) (c) (b a))
↓
((d (dd) e) (c) (b a))
((c (d (dd) e)) (b a))
((a b (c (d (dd) e))))
=> (a b (c (d (dd) e)))
みたいな感じで並べ替えればいいのはなんとなくわかるんだけどね。
肝心のコード思いつかない。
650:デフォルトの名無しさん
05/08/08 20:39:31
汚く、token がchar の、indent(space)-num conscious な gauche 版ならできた。
(define (port->sp/char/nls iport)
(reverse
(fold
(lambda (x y)
(cond ((eq? x #\newline) (cons '() y))
((null? y) `((,x)))
(else (cons `(,@(car y) ,x) (cdr y)))))
'()
(port->list read-char iport))))
(define (proc arg)
(let lp ((rest arg)
(temp '())
(result '()))
(if (null? rest)
(reverse (if (null? temp) result `(,(proc temp) ,@result)))
(let ((node (car rest)))
(case (length node)
((0) (if (null? temp)
(lp (cdr rest) '() result)
(lp (cdr rest) '() `(,(proc (reverse temp)) ,@result))))
((1) (if (null? temp)
(lp (cdr rest) '() `(,(car node) ,@result))
(lp (cdr rest) '() `(,(car node) ,(proc (reverse (cons (cdr node) temp))) ,@result))))
(else
(lp (cdr rest) `(,(cdr node) ,@temp) result)))))))
651:デフォルトの名無しさん
05/08/08 20:40:04
(proc (port->sp/char/nls (open-input-string "a
b
c
d
dd
e
f
g
h
i
j
k")))
=>
(#\a #\b (#\c (#\d (((((#\d))))) #\e) #\f #\g (#\h (#\i)) #\j) #\k)
652:デフォルトの名無しさん
05/08/08 21:04:45
むっ! Pythonのトランスレータを書こうとしているな。
653:デフォルトの名無しさん
05/08/08 21:07:47
> ((dd) (d) (c) (b a))
> ↓
> ((d (dd) e) (c) (b a))
ここがよく分からない.eを新たにプッシュするときに,どうしてdはeと同じ
リストに含めて,ddは1つネストしたリストに入っているの? もっと言えば,
(c)や(a b)はd,ddと全く別の扱いを受ける必然性もないように見える.
要するに,リストのネストの深さを保存してないよ,ってこと.
654:デフォルトの名無しさん
05/08/08 21:59:58
a
b
c
d
dd
ee
e
f
g
h
i
j
k
とかなってたらeeはどうするのか? ということを考えると
>ddみたいな数階層上のインデントがあっても直前の階層の1つ上とみなす。
はよろしくないんじゃないかな。それとも構文エラー?
655:デフォルトの名無しさん
05/08/08 22:16:21
>>653
インデントの情報も付加して説明すると、
(((a) 0)) ;; インデント0の組
↓
(((b a) 0)) ;; 同一インデントはそのままスタック先頭にcons
↓
(((c) 2) ((b a) 0)) ;; インデント2>0なので新規にスタック追加
↓
(((d) 4) ((c) 2) ((b a) 0)) ;; インデント4>2なので新規にスタック追加
↓
(((dd) 12) ((d) 4) ((c) 2) ((b a) 0)) ;; インデント12>4なので新規にスタック追加
ここで(e 4)がくると(d 4)までスタックを撒き戻すという意味です。
撒き戻すついでにreverseして整える。
↓
(((d (dd) e) 4) ((c) 2) ((b a) 0))
さらにeが終端なので連鎖して撒き戻し&reverseが発生する
(((c (d (dd) e)) 2) ((b a) 0))
↓
(((a b (c (d (dd) e))) 0))
=> (a b (c (d (dd) e)))
それで結果がこうなればいいんじゃないか、ということです。
でも 2 -> 12 -> 4とかのパターンだと
12を4とみなすとか例外作らないとだめかなあ。
>>650
早速ありがとうございます。
コード研究してみます。
656:デフォルトの名無しさん
05/08/08 22:18:33
>>654
上にも書いたけど、それさっき気づきました。
やっぱ インデント構造はそのまま保持して、
後から遊びを修正するようにした方が利口かもしれない。
657:デフォルトの名無しさん
05/08/08 22:37:15
あー、>>654の場合は構文エラーというのも悪くないですね。
「ぶら下がる親があいまい」とかで。
様式的に654の様なケースはありえなさそうだし。
658:デフォルトの名無しさん
05/08/10 22:19:54
>>650氏のコードを自分の想定した入力形式に書き換えてみました。
(define (proc arg)
(let loop ((rest arg) (temp '()) (result '()))
(if (null? rest)
(reverse (if (null? temp) result `(,(proc (reverse temp)) ,@result)))
(let ((node (car rest)))
(if (< (car node) 2)
(loop (cdr rest) '()
(if (null? temp)
`(,(cadr node) ,@result)
`(,(cadr node) ,(proc (reverse temp)) ,@result)))
(loop (cdr rest)
`(,(cons (- (car node) 2) (cdr node)) ,@temp) result))))))
(proc '((0 a) (0 b) (2 c) (4 d) (12 dd) (4 e) (2 f) (2 g) (4 h) (6 i) (2 j) (0 k) (2 m)))
=>(a b (c (d ((((dd)))) e) f g (h (i)) j) k (m))
(< (car node) 2)の箇所はインデント幅が奇数だったら小さい側へ切捨てる処置です。
659:デフォルトの名無しさん
05/08/10 22:28:19
それと入力を作って、
(define (read-indent-text)
(define (space-count str)
(let ((len (string-length str)))
(let loop ((i 0))
(if (and (< i len) (char=? (string-ref str i) #\space))
(loop (+ i 1))
i))))
(let loop ((str (read-line)) (r '()))
(if (eof-object? str)
(reverse r)
(let ((pos (space-count str)))
(loop (read-line)
(cons (list pos (substring str pos)) r))))))
----ind.txt----
root1
abc
def
gef
aaa
bbb
ccc
root2
aaa
----ind.txt----
(proc (with-input-from-file "ind.txt" (read-indent-text)))
=>("root1" ("abc" "def" ("gef") "aaa" ("bbb") "ccc") "root2" ("aaa"))
こんな感じになりました。
660:デフォルトの名無しさん
05/08/10 22:48:55
ついでに逆変換も作りました。(これは1分でできた。)
(define (ind-pp s . indent)
(define (spaces n)
(if (zero? n) #t (begin (write-char #\space) (spaces (- n 1)))))
(set! indent (if (pair? indent) (car indent) 0))
(let loop ((x s))
(if (pair? x)
(if (pair? (car x))
(begin
(indent-pp (car x) (+ indent 2))
(loop (cdr x)))
(begin
(spaces indent) (display (car x)) (newline)
(loop (cdr x))))
#t)))
(ind-pp '("root1" ("abc" "def" ("gef") "aaa" ("bbb") "ccc") "root2" ("aaa")))
root1
abc
def
gef
aaa
bbb
ccc
root2
aaa
=>#t
結構手間掛かりましたね。。
661:デフォルトの名無しさん
05/08/10 23:16:41
URLリンク(fun.sci.fukuoka-u.ac.jp)
のscheme-modeをgaucheのgoshをインタプリタとして使ってみたいのですが、
そういう使い方してる人います?
できれば教えて下さい。
またこれ以外でも、xyzzyで使えるscheme-modeがあれば紹介してください。
662:デフォルトの名無しさん
05/08/10 23:37:10
リストに入れた関数を一つの引数に次々に適用するにはどうするのがよいのでしょうか?
状況としてはユーザからの入力値をチェックすることを考えています。
例えばチェック用関数 func_a, func_b, func_c, func_d と入力値 x, y, z があり
x については func_a と func_b,
y については func_a と func_c,
z については func_a と func_d,
によるチェックを行いたいわけなんです。
そこで x の場合
(func_a, func_b) と x を引数にとってリスト ((func_a x) (func_b x)) を
返すようにしたいのですが map のような便利な関数はないのでしょうか?
あるいはリストに入れた関数を一つの引数に次々に適用するよりも
適切な方法はありませんでしょうか?
663:デフォルトの名無しさん
05/08/11 00:26:44
(define (hoge func-list x)
(map (lambda (f) (f x)) func-list))
(hoge (list (lambda (x) (+ x x)) (lambda (x) (* x x))) 10)
=> (20 100)
664:デフォルトの名無しさん
05/08/11 01:08:58
お約束キタ━━━(゚∀゚)━━━!!!
665:デフォルトの名無しさん
05/08/11 01:30:32
おおぅ、こんなところに誤爆してたのか orz
666:デフォルトの名無しさん
05/08/11 23:41:25
>>661
どっかでgoshの-iオプションを使うとか聞いたことがあるようなないような。
667:デフォルトの名無しさん
05/08/12 08:36:46
>>645
亀だけど Gauche で書いてみた.
入力は ((シンボル . インデント数) ...) みたいな感じ.
(use srfi-1)
(define (iexpr->list xs)
(define (f xs level rs)
(if (null? xs)
(values xs (reverse! rs))
(receive (sym l) (car+cdr (car xs))
(cond ((= l level)
(f (cdr xs) l (cons sym rs)))
((< l level)
(values xs (reverse! rs)))
(else
(receive (rest res) (f xs l '())
(f rest level (cons res rs))))))))
(values-ref (f xs 0 '()) 1))
668:デフォルトの名無しさん
05/08/15 23:19:44
>>667からvalues関係を取っ払ってみた。
そんだけ。
(define (iexpr->list xs)
(define (f xs level rs)
(if (null? xs)
(cons xs (reverse! rs))
(let ((sym (caar xs)) (l (cdar xs)))
(cond ((= l level)
(f (cdr xs) l (cons sym rs)))
((< l level)
(cons xs (reverse! rs)))
(else
(let ((x (f xs l '())))
(f (car x) level (cons (cdr x) rs))))))))
(cdr (f xs 0 '())))
>(iexpr->list '((a . 0)(b . 1)(c . 4)(d . 5)(d . 2)(e . 3)(f . 0)))
=>(a (b (c (d)) (d (e))) f)
なかなか面白いですな。
これ使って何かに繋がらないかな。
すぐ思いつくのはGUIコントロールの階層表現ぐらいだけど。
669:デフォルトの名無しさん
05/08/21 22:40:48
Schemeのコンパイラなどで使うというCPSについてわかりやすく
解説してるページはありますか?
コンパイラとかの中間言語としてのCPSとか、CPSへ/からの変換が
知りたいといいますか。英語でもいいです。
継続とは何ぞやとか、
普通の場合に戻ってから実行する処理をクロージャとして渡せば
一般の言語で継続渡し形式で書ける、という程度の継続渡しの
理解はしてるつもりです。
670:デフォルトの名無しさん
05/08/21 23:13:14
>>669
とりあえずSICP嫁。英語ならWebで読める。
671:デフォルトの名無しさん
05/08/21 23:37:09
SICPは読みかけの途中で止まってます。どのへんに書いてありますか?
672:デフォルトの名無しさん
05/08/21 23:44:38
あとは、東大のコンパイラ演習のレジュメとか
URLリンク(www.is.s.u-tokyo.ac.jp)
673:デフォルトの名無しさん
05/08/22 00:11:36
Scheme用のRSS解析ライブラリってないの?
perlのXML::RSSみたいなの.
674:デフォルトの名無しさん
05/08/22 00:38:14
SXMLとSXPATHでは足りない?
675:643
05/08/22 00:47:55
よりらくちんにやりたいのです.
676:デフォルトの名無しさん
05/08/22 02:56:42
>>673
LISPはクローズドな開発が多いから
ここで「~ない?」系の質問しても答えはほとんど「無い」が返ってくると思っていい。
どうしても必要なら自分で書け。
そしてコミュニティに還元しろ。
677:643
05/08/22 09:31:13
>>676
なるほど!
じゃあ,がんばって書くよ.
678:デフォルトの名無しさん
05/08/22 10:58:41
LISPだと簡単に書けちゃうから、逆にあまり再利用を考えずに自分専用のを
作って使い捨てしちゃうってことはあるね。
>>677 がんがれ
679:デフォルトの名無しさん
05/08/30 13:54:52
Lisp に少し興味を感じています。
あまりにも他の言語と異質な感じをうけるため、心理的な抵抗感も実はあります。
Scheme は Lisp の派生あるいは方言である、と入門サイトに記述されています。
両言語の特性の違いについて、実際にプログラムを組んでいる方の感覚とご理解から
意見を伺いたいです。Lispが優れている言語ならば、それをもとにしたSchemeを
学習する方が良いのだろうか、と悩んでいます。
経済的な理由からLinuxマシンを新規に構成するのではなく、現在使用中の
Windowsマシンで Lisp/Scheme を学びたいと思っています。
680:デフォルトの名無しさん
05/08/30 19:51:41
>>679
CommonLispならcoLinux(ただしXP/2000限定)を入れてcmucl、
Windows単体で動かしたいならclisp使うとか。
Schemeなら日本語リソースではgauche、
とにかく速いのがいいならbiglooかな。
681:デフォルトの名無しさん
05/08/30 20:01:43
お勉強目的なら xyzzy でいいんじゃね?
エディタとしてもよく出来てるし。
682:デフォルトの名無しさん
05/08/30 20:07:21
>>681
xyzzyはかなり方言だし、ちゃんとしたclispあたりのほうが良いと思う。
Scheme系ならgaucheかな。
683:デフォルトの名無しさん
05/08/30 21:34:10
>>680 >>681 >>682
皆様のおかげで、5つの実装・環境について特徴を知ることができました。
奥深いのですね。ありがとうございます。
調べたところ、エディタ xyzzy には熱心な愛好者が多そうですね。
Lispの言語としての魅力と関係があるように印象を受けました。
お勧めのgaucheを少し検索しました。
Kahuaというウェブアプリケーション作成の仕組みがあるとか・・
時間をつくってお勧めを参考に Lisp/Scheme を勉強してみます。
684:デフォルトの名無しさん
05/08/30 21:52:14
>>683
あんまし色々言うと混乱させてしまうかもしれないけれど、
とりあえず動かしたいということだったら IDE もついてくる PLT Scheme が楽かも。
xyzzy がとっつきやすいのと同じ理由で。
一応日本語方面も外国ものとしてはそれなりだし。
でも、教科書とにらめっこして勉強するんじゃなく、
実際自分で使う小物スクリプトを色々書きながら勉強するというスタンスだったら
gauche が一番向いてるのかな。
そもそもスクリプティングに使いやすいものを、という開発方針だった気がするし。
何にせよ、Scheme は善かれ悪しかれ処理系ごとの個性が強いので
色々な処理系を試してみて、一旦これ、と決めたら、
それの使い方を詳しくつっこんでみるのがいいと思う。
685:デフォルトの名無しさん
05/08/30 22:35:37
結局、Schemeはスマートだけどライブラリが不足している現状があり、
それが処理系ごとの違いに繋がってるんだと思う。
Gaucheくらい充実してればSchemeも楽しい。
686:デフォルトの名無しさん
05/08/30 23:14:12
日本語を扱いに長けているcommon lispの処理系には何がありますか?
schemeだったらgaucheで決まりなんだけど、common lispは良さそうなのが
見当たりません。
687:デフォルトの名無しさん
05/08/30 23:20:45
>>686
最近のclispはSJIS/JIS/EUC/Unicode自由自在だよ。
URLリンク(clisp.cons.org)
688:デフォルトの名無しさん
05/08/31 00:12:43
Petite Chez Scheme というのを ChezEdit-NT というエディタで動作させるのも楽しそう。
689:デフォルトの名無しさん
05/09/01 13:15:57
スレ違いならすんませんが、Scheme勉強しようと思って、
OSX TigerにGauche 0.8.5インストールしたところリンクが通らず、
Finkでdlcompat入れろつーことらしいから(10.2だけど)、
Fink入れてみたんだけどdlcompatとかなさそうで、
ほんじゃってんで、ports入れてみて、
dlcompat落としてみたら、コンパイルできんって感じでげす...orz
どげにしたらインストでけるんでがしょ?
690:デフォルトの名無しさん
05/09/01 13:35:34
しかるべき場所でちゃんとした言葉遣いで相談したほうが良いと思います。
691:デフォルトの名無しさん
05/09/01 14:06:18
port install gauche
692:デフォルトの名無しさん
05/09/01 21:30:54
gaucheの特徴
・define-macroがある
・マニュアルが日本語(ライブラリも)
・ライブラリが豊富
・Cで簡単に拡張できる。
693:デフォルトの名無しさん
05/09/02 04:52:45
>>686
SBCL は最近、日本語通る様になった
694:686
05/09/03 01:42:43
>>687>>693
おまいら、ありがとうございます。
>>950は次スレのテンプレに日本語使える処理系情報を追加しておくように。
695:デフォルトの名無しさん
05/09/03 05:56:43
gaucheでhttpクライアントを作ろうとしています。
このとき http-get 関数に :Accept-Encoding "gzip, compress" を
指定して圧縮されて受け取ったデータを展開するにはどうすればよいでしょうか?
javaみたいにgzipのストリームがあれば便利なんですが、ストリームどころか
素のgzipのユーティリティも見当たらないようです。
知ってる方お知恵をお貸し下さい、おながいします。
696:デフォルトの名無しさん
05/09/03 16:34:33
とりあえず何とかしたいなら、プロセスポートを
使ってgzipを呼ぶようにすれば?
rfc.mimeも使うよね。