Lisp Scheme Part40 [転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
>>530
素敵です! ありがとうございます! これが探し求めていたものです。より良いものがあることを願っていました。 ((a b c) d)の評価順序は
a b cの順序は決まってなくて(a b c)の後にdが評価されるのだけは保証されている。で合ってるよね?
もちろんマクロや特殊形式の引数は除外だけど>>527の展開結果は(a b c)と同じことになってる
さらに(or a b c)ならaがtrueの時点で評価打ち切りでb cは評価されない(短絡評価)
(or a b c)がマクロなら以下のように展開されないといけない
((lambda(x k) (if x x (k))) a (lambda() ((lambda(x k) (if x x (k))) b (lambda() c)))) >a b cの順序は決まってなくて(a b c)の後にdが評価されるのだけは保証されている。で合ってるよね?
これ合ってないわ。評価されるからそれを見越して>>534の最後のように遅延評価を入れとくって話
もういいです。 評価されるから、じゃなくて評価の順序が決まってないから
それを見越して無引数lambdaを1つ挟む必要があるだった。 気持ち悪いからまとめると、
((a b c) d)のa b c dの評価順序は何も決まってないから気をつけてねって事。 最初の要素を最初に評価しないとマクロかどうか分からないかと思ってたが、その前の段階でマクロかどうかを判断することができるらしいんで、仕様では決まってないのか
((begin (display "1st\n") +) (begin (display "2nd\n") 2) (begin (display "3rd\n") 3))
をchezとgaucheで評価したら
2nd
3rd
1st
5
って順番だった。guileやchickenだと
1st
2nd
3rd
5
って順番になる。 最適化や諸々の都合で、同じ処理系でも順序が変わることはあるので、
単純な事例だけでは処理系の性質を推し量ることは出来ない。 (define-macro (my-once-only1 x . body)
(let1 tmp (gensym)
`(glet1 ,tmp ,x
(let1 ,x ,tmp ,@body) )))
(use srfi-1)
(define-macro (my-once-only vars . body)
(let ((names (map (lambda (_) (gensym)) vars)) )
`(glet* ,(zip names vars)
(let ,(zip vars names) ,@body)
) ))
念願のものが作れました…。これで心残りはありません。 Scheme でやるなら syntax-rules でやったほうが楽だと思うが。 >>533
> >>531
> 確か評価順が未定義なだけ。
少なくともSchemeではandやorでの式の評価順序は未定義でなくは左から順番に評価すると一意的に規定されているぞ
CLはどうだが知らんが >>542
そうだった。間違えた。
未定義なのは関数呼び出しの引数の評価順だね。 やっとリスト処理に慣れてgensymであーだこーだしてる人にsyntax-rulesは敷居高いと思う syntax-rulesはR7RS眺めてもよくわからんかった むしろSchemeから学ぶとマクロ入門にはsyntax-rulesしか書いてなくてdefine-macro&gensym触る機会が無かった 伝統的マクロの方が動作モデルを想像しやすくはあるかもね。 >>546
> むしろSchemeから学ぶとマクロ入門にはsyntax-rulesしか書いてなくてdefine-macro&gensym触る機会が無かった
>>547
> 伝統的マクロの方が動作モデルを想像しやすくはあるかもね。
Schemeの場合、何でもありのマクロを排除して意味や動作を形式的に定義でき、
展開結果の正しさ(変数が展開したとたんに突然バインドされたりしない等)を保証できる範囲に留めたいという発想が
根底にあるからね
だからsyntax-rulesなどSchemeでの「マクロ」はあくまでも構文の拡張(カスタマイズ)のためなんだよね
つまり字句レベルを勝手に弄らせるとどんなトラブルでも起こし得るから勝手に弄らせたくたくない、
プログラマがお好みの構文を既存構文を使って定義して追加したいというならそれは許してあげよう
(例えばCみたいにwhile文…ループ条件の判定が最初に行われる構文…がある言語にrepeat〜until文を追加したいなら
許してあげように相当)というのがSchemeの基本的なスタンス
つまり、Schemeの場合はソースレベル(テキストレベルと言っても良い)で好き勝手な操作を許す本来のマクロ
(ソースコードレベルのメタプログラミング手段)でなくて、抽象構文レベルでの変換規則を定義し使用する範囲だけに
限定しているんだと考えれば良いと個人的には思ってるけどね
だから(メタ)プログラムの動きで理解するタイプの人(プログラマには多い、特に優秀な人ほど)にとっては
古典的なマクロのほうが却って理解しやすく、逆に理屈が好きで系統的に理解したがる(代わりにプログラムの腕は
さほどでないのが多い)人間にはSchemeの構文拡張のほうが理解しやすくそちらを好む人が多い
もっともsyntax-rulesとかを提案して実現した向うの連中はプログラミングの腕力も上級者以上ばかりだけどね
(でも殆どの凡人は、プログラミングの腕か理屈かの高々どちらかしか得意でない、まあだからこそ凡人なわけでして
どっちも両立できちゃったらGuy Steele, Jr.みたいになれちゃうよね) syntax-rulesの動きがよくわからなくて理解できなかったけど古典的マクロなら単純で理解しやすかったな、準クォート使えば面倒でもなかったし(プログラムの腕はだめです) >>549 あくまでも構文の拡張のため
他のlispでもそうでしょ.具体的にそれ以外の他になにがある? >>551
他のLispに限らずマクロは構文の拡張と言えるほどの系統的な代物にはなってないでしょ
だからマクロを展開した途端にグローバルだったはずの変数が束縛されてローカルな変数に化けたりする(変数のキャプチャね)
つまり通常のマクロは(必要に応じて実行時と同じ計算も許して)ソーステキストという文字列データを処理しているだけ
それに対してsyntax-rulesなどに代表されるSchemeのは抽象構文上での操作とすることでテキストという文字でなく構文の句構造のレベルで扱い
変数のキャプチャなどを起こさないように保証するわけだ
ソースコードを文字データとして処理するのか句構造として処理するのかでは考え方も保証できる正しさや展開の安全性も全く違う >>552
> lispマクロは構文の拡張と言えるほどの系統的な代物にはなってない.
そんなお前定義しらんし,そんならsyntax-rulesも違う.
はなしが無限退行しそうだからもういいわ. Common lispにschemeのmatchマクロを移植したのないのでしょうか? さあ、わかんなくなってきました。
とにかくsyntax-rulesの方が高級で、実装がめんどくさくて、低機能で、とりあえずほとんどの用はたりる。 そのめんどくさいの一点だけでLISP系にsyntax-を導入する価値は微妙
パターンマッチだからLISPじゃなくていいわけよね
syntax-rule/caseを日本語で詳細解説した本とかWebページってない? なんだっけsyntax-rule/caseの他にもう2つぐらい別種があるんだよね
重複しないシンボル名の管理の観点では手間は同じだけど概念的にはより簡単な感じだったと思う case は削除されなかった?他の2つも結局どうなったんだか >>556
> そのめんどくさいの一点だけでLISP系にsyntax-を導入する価値は微妙
一概には言えない。
たとえば letrec のようなものをマクロで書こうとするとフォームを分解したり
衛生的にしたりする処理はいずれにしても必要なことで、
それを自動的にやってくれる syntax-rules だと簡単に書ける。
syntax-rules や syntax-case は言語のプリミティブな機能としては高級すぎるのは確かで、
これは低水準の部分でどのパラダイムを採用するかで意見が一致しなかった末の妥協案として
いきなり高級な機能を持ち込んだ結果。
参考: http://blog.practical-scheme.net/shiro?20100425-scheme-macro
実際の処理系では explicit renaming や syntactic closure を基礎に据えてその上に
syntax-rules や syntax-case のインターフェイスを実装している場合もよくある。 schemeだとread macroの定義ってどないなっとるん?
自分common lispとバージョンが上がるといつ消えるか解らないclojureのしか知らんのだけど。 >>560
リードマクロについては Scheme の仕様には含まれないし SRFI にもないし、デファクトスタンダードといえるものもない。
処理系が独自にやっている場合はあるけど。
私見だが、 Common Lisp に比べて Scheme はモジュール化を強く意識していると思う。
R6RS でフェイズの制御について一応の考え方が確立したものの、
リーダの適用範囲をうまく制御するにはまた別の軸を持ち込む必要があるので厄介なのだと思う。 >>561
あ、やっぱりなかったのか探しても定義みつらんわけだ
DSL書きたいので処理系の小さい実装のschemeでやろうとおもったのだけど駄目か orz
ありがとね schemeのリードマクロってCL踏襲じゃまずい理由でもあるの?
健全とか関係なくね? >>562
それはいっそプリプロセッサ的なものを書いてしまえばいいんでないかい? Lispの論文で英語表現とか定理の書き方みたいので参考になる論文ってどこらへんみればいいでしょう >>566
定理はともかく英語表現はRnRSの原本読んどけばいいんじゃないかな
後はこんなのとか
http://repository.readscheme.org/ftp/papers/ai-lab-pubs/AIM-353.pdf
wikipediaのScheme系の記事の参照元を読み漁るといいと思う RnRS は仕様書っぽい言い回しだけど論文と同じかなぁ、論文読む方に賛成 >>564
リードテーブルの状態によってプログラムの意味が変わってしまうのは不健全さを嫌うScheme的にはだめでしょ >>569 の主観なのかそれとも論文にまとまってたりするのか.
racket#!langはどうなる. >>570
そもそもRacketはScheme的にだめでしょ Chez Schemeの日本語ドキュメントないの〜? Chez Scheme について具体的に知りたいことがあればここで質問すれば簡単な回答くらいはつくかも? 最近のlisp webフレームワークで良いのって何でしょうか Kahuaなら知ってるが更新されてないっぽいし使ったことないからよくわからん 逆転ポインタなつい
ttp://qiita.com/kingshine/items/d74576886c067737ad18 Common lispのnilとfalse区別しないの気持ち悪いけど
Schemeでまともな処理系もう残ってない感じして
Common Lisp に移住するしかない 何をもってまともと言うのか、Gauche使ってるけど普通に安定してるぞ >>577-578
Kahua ほどダイナミックな運用はできないが Gauche-makiki は簡単に使えるし
活発に更新されているのでいいかも。 picrin使ってたのにgitのtipがビルド通らん…巻き戻すしか >>587
そんなスピードで何するの?
速いに越したことはないけどさ。 速いに越したことはないなら一番速いやつを選ぶじゃん >>592
picrin のどういうところが好き? >>594
他の条件が同じなら速いやつを選ぶけどさぁ、
そんなの用途によるだろ。 実際のところSchemeでどんなプログラム書いてる?
具体的に晒せるものがある人いる? 晒せないが、S式で書いたテンプレートからHTMLに変換してた
CSSで過去の技術となったが
あとはC++に組み込みスクリプト >>594
schemeと俺を比べたら俺が遅いからあんまり意味無いんだよトホホ >>599
そもそも盛り上ってないこのスレを盛り上げるにはお前が身を削ってネタ投下するしかないだろ biwascheme http://www.biwascheme.org/ はページ上にREPLあるから遊べるかも >>444
実際の時間差はあまりないな
順位はかなり後ろだけど picrin のコア機能では unicode サポートなしで、後付けは可能なようにするという方針も提示されている
ので、コアだけのスピードで評価するのもアンフェアな気がする。
https://twitter.com/___yuni/status/504240324831477760 Python ってプログラマでない人にも使いやすいデザインなんだとさ。
数学屋や物理屋もプログラムを書くことはあるけど、専門家じゃないからな。
言語に関わってばかりはいられん。
綺麗な抽象化とか考えずに愚直に書いて動くってのはそれはそれで良い言語なんだよ。
VB とかな。
AI の核になるライブラリが出そろってきていろんな応用をする段階になると
Python の方が色んな人に使ってもらえるという意味で良いんじゃないか?
それに今の AI ってのは記号処理するのに柔軟なデータ構造が必要って感じじゃないだろ。
計算量を投入しまくって結果を出す機械学習とかじゃん。
広い意味では AI つってもやってることは違うよ。 Schemeが本当に美しさと強さを両立させようと思うんなら
速さを二の次にして仮想機械の仕様も標準に入れてしまえばよかった
Smalltalk-80のVMは美しかったが
RnRSのdenotational semanticsの記述はCOBOLのコードみたいで正直読みたくない Scheme の仕様ってのは業務マニュアルみたいなもんだよ。
たとえば「誰にハンコをもらえば進めていいのか?」みたいな手順は組織の秩序としてやらなきゃならないことだから
個人の創造性で決めれることじゃないし、仮にそれぞれの場面で最高の才能を発揮して根回ししたところで
正事の成果が良いものになるわけじゃない。
どうでもいいことはマニュアル通りにやってもっと大したことに力を入れようってのが業務マニュアルだろ。
逆に言えば創造の余地がある部分は決めつけてしまいたくないんだ。 lispworks 32bitを使ってて、fliを使ってwindowsのdllから関数を呼ぼうとするのだけど、
一部の関数だけがunresolved symbolだと言われて呼び出せない。
dll exported functipn viewerとかでみてみると、
ちゃんと関数を確認できるのに。
何でかわかる人いる?
おいどん、初心者やからわけわかめなのよ。
とりあえず、cffiでもできないかどうかと、ほかの処理系ではどうかを試そうとは思うのだけど、
なんか知ってる人いたら助けてー >>609
呼び出せなかったのは具体的にどの関数?
確認した範囲で呼び出せている関数も書いてもらえれば
何か違いを見出せるかも >>610
windowsのdllってのは適切な言い方じゃなかったかも。
具体的には、趣味で下記のライブラリをlispworks上で使いたいと思っているんです。
ttp://www.astro.com/swisseph/swephinfo_e.htm
ttp://www.astro.com/ftp/swisseph/
ここのsweph.zipにWindows 32bit用のdllがあるのですが(swedll32.dll)、
lispworksのfliを使って呼び出そうとすと、呼び出せる関数と呼び出せないのがあるんです。
ただ、私、lispもcもwindowsプログラミングも素人なので、何が問題なのかもよくわかってません。
後ほど、呼び出せる、呼び出せない関数の例や、その定義等含め書いてみます。
なにかアドバイスありましたらいただけますと幸いです。 609です。
うまくいく例とダメな例を挙げてみます。おそらく皆さんは全く興味のないライブラリだと思うので、質問するのも恐縮ですが。
問題なく呼び出せる例:
CL-USER 1 > (fli:register-module "swedll32.dll")
"swedll32.dll"
CL-USER 2 > (fli:define-foreign-function (swe_julday "_swe_julday@24" :source) ((year :int) (month :int) (day :int) (hour :double) (gregflag :int)) :result-type :double)
SWE_JULDAY
CL-USER 3 > (swe_julday 2001 1 1 0d0 1)
2451910.5D0
CL-USER 4 > (fli:define-foreign-function (swe_calc_ut "_swe_calc_ut@24" :source)
??? ((tjd_et :double) (ipl :int) (iflag :long) (xx (:reference-return (:c-array :double 6))) (serr? (:reference-return (:ef-mb-string :limit 256))) ) :result-type :int :lambda-list (tjd_et ipl iflag &aux? xx? serr))
SWE_CALC_UT
CL-USER 5 > (swe_calc_ut (swe_julday 2001 1 1 0d0 1) 0 0)
4
#<Foreign-Array :DOUBLE (6): addr #x02189F08>
"SwissEph file 'sepl_18.se1' not found in PATH '\\sweph\\ephe\\'
using Moshier eph.; " 今度はダメな例です。
CL-USER 6 > (fli:define-foreign-function (swe_version "_swe_version@4" :source) ((sver (:reference-return (:ef-mb-string :limit 256)))) :result-type :pointer :lambda-list (&aux sver))
SWE_VERSION
CL-USER 7 > (swe_version)
Error: Foreign function SWE_VERSION trying to call to unresolved external function "_swe_version@4".
? 1 (abort) Return to level 0.
? 2 Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
CL-USER 8 : 1 > :c 1
CL-USER 9 >
一応、自分なりに調べてソースファイルからdefファイル使ってコンパイルしなおしたりもしたのですが、
やはりだめでした。もっとも素人なので意図していることができているかどうかも怪しいのですが。。。
もし何かアドバイスありましたらお願いします。 612訂正
誤:
>CL-USER 4 > (fli:define-foreign-function (swe_calc_ut "_swe_calc_ut@24" :source)
>??? ((tjd_et :double) (ipl :int) (iflag :long) (xx (:reference-return (:c-array :double 6))) (serr? (:reference-return (:ef-mb-string :limit 256))) ) :result-type :int :lambda-list (tjd_et ipl iflag &aux? xx? serr))
>SWE_CALC_UT
不要な?がはいっちゃいました。
正:
CL-USER 4 > (fli:define-foreign-function (swe_calc_ut "_swe_calc_ut@24" :source)
((tjd_et :double) (ipl :int) (iflag :long) (xx (:reference-return (:c-array :double 6))) (serr (:reference-return (:ef-mb-string :limit 256))) ) :result-type :int :lambda-list (tjd_et ipl iflag &aux xx serr))
SWE_CALC_UT >>609です。自己解決しました。
defファイルを使ってソースファイルからコンパイルしなおしたら
問題なく呼び出せるようになりました。汗
これまでも何度かVisual Studioからコンパイルを試していて、
dllは問題なく作成されるものの、一部呼び出せない関数があり、問題は解決しませんでした。
しかし、今回コマンドラインからコンパイル、リンクすると、なぜかうまくいきました。
結局、何が問題だったのかはわからないのですが、
とりあえず利用で来るようになりましたので、ご報告です。
お騒がせしました。。 そういやピンボールゲームSchemeの人、ピンボールも放置してるし死んだのかと思ったら
Twitter社に入ってたんだよな。 >>605
今のAIはPythonが完全に主流だね
>>606
そりゃ大多数にはLispより
Pythonの方が使いやすいだろう >>617
ISLispの話ぜんぜん聞かないけど
Clojureとかの方が圧倒的に普及してるんじゃね そもそも本質的にLISPはAIとは関係がないぞ。
未だにAI=LISPなどと言っている輩はだめだと最近まで言われていたのにな。
Pythonだってライブラリがあるかないかというだけの理由であって
AIはスクリプト言語とは無関係だから。みんな誤解している。
AI言われる以前からPythonはあっただろ(w マッカーシが AI 研究者だったこともあって、
実際に AI 研究に使われたのと、
その流れで AI 分野での利用実績は有るけど、
言語仕様的に特別 AI に向いてるってことはない。
ただ、当時のプログラミング言語っていうと Fortran とかの時代だから、
それで柔軟なデータ構造を必要とする記号処理をするのはつらかっただろうし、
その中で選ぶなら LISP は圧倒的に AI 研究に向いてたとは思う。 >>622
本質的に関係ないとまで言いきっちゃうと
それはそれで違う
Lisp(とProlog)は記号処理に向いてたから
一昔前のAIブームで利用された
>>623
記号処理がしやすいんだから
結局向いてたんだよ >>624
あ、 >>623 の「特別 AI に向いてるってことはない」の前に「今では他と比べて」 を付け加えといて。
今なら Ruby や Python くらいでも記号処理をする上で LISP よりすごく不利ってことはないと思うって話。
まあ不向きの部分もあるかもしれないけど、それ以上のメリットがある部分もあるし、それはバランスの問題ってことで。
逆に 今じゃ LISP も普通に汎用プログラミング言語として使いうるわけだし、
あまり AI を強調して LISP を紹介するようなのがあってもなんかもにょっとすることあるよね。 書籍や情報が多い少ないだけでも、向いてる向いてないと言われるだろう AI 分野であろうとなかろうと言語の盛衰があったっていう単純な話かもね。 そのAIってのが曲者で、単なる構文解析やエキスパートシステムじゃん。
それは単なる文字処理と機械のモノマネでAIじゃないですよ。
上の人も書いているけど、今だからスクリプト言語がある。当時はそれがなかったから
LISPが応用分野の開発の道具として開発され選択されたというだけ。
世界初の難解言語であるが、関数型のLISPはAIとは本質的に関係はないですから。
Prologも関数型のように基本となる仕組みが手続き型と違うのであってそれが評価されるのであり
本質的にはAIとは関係が無い。 LISPに限らず定義が曖昧なAIなどという話を持ち出すことがいかにデタラメで間違いであるかに気付くべき。
AIという呼称で、いかにLISPが誤解され続けて来たのかを問題視するべき。
失敗事例も多く、何十年も前から存在している技術なのに今更AIなど言うのもおかしい訳。 >>628
>>629
いや一般的なジャンル区分では
エキスパートシステムはAIでしょ
強いAIは実現できてないけど
弱いAIをエキスパートシステムと呼んでる
定義が曖昧とか言っておいて
自分でオレ定義使ってる気がする MITの人工知能研=Lisperの巣というイメージはもう古いのかな ■ このスレッドは過去ログ倉庫に格納されています