CommonLisp Scheme Pa ..
[2ch|▼Menu]
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、#` ではなく #' だね。


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

5278日前に更新/268 KB
担当:undef