* Menu
- 2010-01-20
- 実践CLを読了
- Common Lisp : 関数とマクロとスペシャルフォームの違い
- memo : xyzzy lisp FFI
- 2008-03-13 :
- 2008-03-05 :
- 2008-03-04 :
- 2008-02-25 :
- lisp : 破壊とか非破壊とかの話
- 2007-02-24
- 「入門 Common Lisp - 関数型4つの特徴とλ計算」の著者のページを見た
- 「入門Common Lisp〜関数型4つの特徴とλ計算」感想
- 素数を求める
- Scrapbook : LispUser.net : 最高にキモい Lisp コードを書いてみよう with 100 行リーダーマクロ
- clispでcgi
page 0 - << : 0 : >>
* 2010-01-20
- Scheme コードバトン (CL fork)
- やったことは以下の通り。
- untabify
- format指示子を大文字に揃える
- インデントを調整
- 辞書が存在しない時の動作を修正
- package-nameがprintされないようにして、オリジナルの辞書と似た感じの出力を目指した
- asdfのパッケージ化
- lispの関数は10行越えると、理解が大変になってくる。修行が足りないなぁ
- xyzzy lispでforkしようかと思っていたけれど、ABCLの動作と似た感じになるだろうから、微妙。
diff --git a/package.lisp b/package.lisp new file mode 100644 index 0000000..3667c7a --- /dev/null +++ b/package.lisp @@ -0,0 +1,13 @@ +;; -*- Mode: Lisp; Syntax: Common-Lisp -*- + +;;; Package Management +(in-package :cl-user) + +(defpackage :hige + (:use :cl) + #+ABCL (:shadow :y-or-n-p) + (:export #:pin + #:pon + #:pun + #:pan + #:pen)) diff --git a/scheme_baton.asd b/scheme_baton.asd new file mode 100644 index 0000000..b2d9ce6 --- /dev/null +++ b/scheme_baton.asd @@ -0,0 +1,4 @@ +(defsystem :scheme_baton + :serial t + :components ((:file "package") (:file "scheme_baton")) + ) diff --git a/scheme_baton.lisp b/scheme_baton.lisp index 27713dc..fc50ad7 100644 --- a/scheme_baton.lisp +++ b/scheme_baton.lisp @@ -53,6 +53,7 @@ ;; 8. masatoi (http://d.hatena.ne.jp/masatoi/): n択問題(hige:pen)を実装.英単語から意味を問うのと意味から英単語を問うのと選べる.named-let使いまくり. ;; 9. cranebird (http://d.hatena.ne.jp/cranebird/): CL と言えばマルチパラダイムなので CLOS を。with-系のマクロを追加。 ;; 10. smeghead (http://d.hatena.ne.jp/smeghead/): 単語のスコアを導入した。問題の単語表示時にスコアを表示するようにした。単語の一覧表示(hige:pun)にキーワード引数 score-thresholdを追加。 +;; 11. NANRI (http://raido.sakura.ne.jp/southly/rn/): デバッグとちょっとした整理。あと (asdf:oos 'asdf:load-op :scheme_baton) でロードできるようにした。 ;; ;; ================================================================================================================================================= ;; これより下がコードとその説明 - 変更・削除歓迎 @@ -79,18 +80,6 @@ ;; ■辞書ファイルの例 ;; http://gist.github.com/273424 -;;; Package Management -(in-package :cl-user) - -(defpackage :hige - (:use :cl) - #+ABCL (:shadow :y-or-n-p) - (:export #:pin - #:pon - #:pun - #:pan - #:pen)) - (in-package :hige) ;;quek-san's http://read-eval-print.blogspot.com/2009/04/abcl-java.html without cl-ppcre @@ -177,25 +166,25 @@ (format *debug-io* "done~%")) *dict*)) -(defmacro with-entries ((entry) &rest body) +(defmacro do-entries ((entry) &rest body) `(dolist (,entry (entries-of *dict*)) ,@body)) ;;; Top-Level Functions (defun pin () "Register new entries to the dictionary." - (unless *dict-file* - (ensure-directories-exist *dict-file*)) (with-dict () - (loop (add-entry (prompt-for-entry)) - (if (not (y-or-n-p "Another words to register? [yn]: ")) (return))))) + (loop + (add-entry (prompt-for-entry)) + (unless (y-or-n-p "Another words to register? [yn]: ") + (return))))) (defun pon () "Start self-study english vocabulary quiz." (with-dict () - (with-entries (e) + (do-entries (e) (p "~&~A (score: ~D): " (read-aloud (entry-word e)) (entry-score e)) - (ready?) + #-ABCL (ready?) #-ABCL (p "~&~A [Ynq]: " (entry-meaning e)) :again (case (query #+ABCL (entry-meaning e)) @@ -209,12 +198,12 @@ (defun pan () "Search the word user has input from the dictionary" (with-dict (:read-only t) - (let ((word (intern (prompt-read "Word to search") :hige))) + (let ((word (intern (prompt-read "Word to search") #.*package*))) (format t "~A" (or (search-dict word) "Not found."))))) (defun pun (&key score-threshold) - (if (and score-threshold - (not (numberp score-threshold))) + (when (and score-threshold + (not (numberp score-threshold))) (error "pun: score-threshold must be number.")) (setup-dict) (dump-dict :score-threshold score-threshold)) @@ -226,7 +215,7 @@ (with-dict () (when (> n-choice (length (entries-of *dict*))) ; 辞書の長さチェック (error "Dictionary size is too small .~%")) - (with-entries (e) + (do-entries (e) (p "~&~A (score: ~D): " (if meaning? (entry-meaning e) (read-aloud (entry-word e))) (entry-score e)) @@ -239,13 +228,15 @@ :do (p "~A.~A " i (if meaning? (entry-word item) (entry-meaning item)))) (p " [1-~Aq]: " n-choice) (nlet itr ((query (read *query-io* nil nil))) - (cond ((and (numberp query) (> query 0) (> (1+ n-choice) query)) + (cond ((and (numberp query) (< 0 query (1+ n-choice))) (if (= query correct-answer) (incf (entry-ok-count e)) (incf (entry-ng-count e)))) - ((and (symbolp query) (string= (symbol-name query) "Q")) (return)) - (t (p "~&Please type number of the choice or Q for quit.~%[1-3q]: ") - (itr (read *query-io* nil nil))))))))) + ((and (symbolp query) (string= (symbol-name query) "Q")) + (return)) + (t + (p "~&Please type number of the choice or Q for quit.~%[1-3q]: ") + (itr (read *query-io* nil nil))))))))) ;;; Auxiliary Functions (defun setup-dict (&key (fn #'sort-dict-standard) (file *dict-file*)) @@ -261,36 +252,51 @@ (mapcar #'(lambda (e) (make-entry :word (entry-word e) :meaning (entry-meaning e) - :ok-count (or (entry-ok-count e) 0) - :ng-count (or (entry-ng-count e) 0))) + :ok-count (or (ignore-errors (entry-ok-count e)) 0) + :ng-count (or (ignore-errors (entry-ng-count e)) 0))) entries)) +(defmacro with-dictionary-io-syntax (&body body) + `(with-standard-io-syntax + (let ((*readtable* (copy-readtable nil)) + (*package* #.*package*) ; 単語Symbolのホームは:higeパッケージです。 + (*read-eval* nil)) + (setf (readtable-case *readtable*) :preserve) ; 単語Symbolは大文字小文字を区別して扱います。 + ,@body))) + (defun read-dict (file) "Read dictionary data from a file." - (let ((*readtable* (copy-readtable nil)) - (*package* #.*package*)) ; 単語Symbolのホームは:higeパッケージです。 - (setf (readtable-case *readtable*) :preserve) ; 単語Symbolは大文字小文字を区別して扱います。 - (with-open-file (in file) - (normalize-dict - (loop :for word := (read in nil in) :until (eq word in) - :collect word))))) + (unless (probe-file file) + (return-from read-dict NIL)) + (with-open-file (in file) + (with-dictionary-io-syntax + (normalize-dict + (loop :for word := (read in nil in) :until (eq word in) + :collect word))))) (defun save-dict (&key (file *dict-file*)) "Save the dictionary data into a file." - (with-open-file (out file :direction :output :if-exists :supersede) - (with-standard-io-syntax - (dolist (word (entries-of *dict*)) (print word out))))) + (unless (probe-file file) + (ensure-directories-exist file)) + (with-open-file (out file + :direction :output + :if-exists :supersede + :if-does-not-exist :create) + (with-dictionary-io-syntax + (let ((*package* #.*package*)) + (dolist (word (entries-of *dict*)) (print word out)))))) (defun dump-dict (&key score-threshold) "Print the dictionary in CSV format." (let ((output (format nil "~{~{~A~^,~}~%~}" (if (null score-threshold) - (entries-of *dict*) ;score-thresholdが指定されない場合は全件 - (remove nil ;score-thresholdが指定された場合は絞り込む - (mapcar (lambda (e) - (if (<= (entry-score e) score-threshold) - e)) - (entries-of *dict*))))))) + (entries-of *dict*) ; score-thresholdが指定されない場合は全件 + (delete NIL ; score-thresholdが指定された場合は絞り込む + (mapcar (lambda (e) + (if (<= (entry-score e) score-threshold) + e + NIL)) + (entries-of *dict*))))))) #-ABCL (format t "~A" output) #+ABCL (|showMessageDialog| |javax.swing.JOptionPane| nil output))) @@ -324,7 +330,6 @@ (1 #\N) (2 #\Q))) - (defun prompt-read (prompt) #-ABCL (progn (p "~A: " prompt)
* 実践CLを読了
一番の収穫はCLOSについての理解が深まったこと。
xyzzyで使えないものだから、ちゃんと勉強したことが無くて:beforeとか:afterとかよく分かってなかったんだけど、やっと分かった。(とりあえず使ってみようと思うくらいには)
メソッド結合かぁ〜 よく考えたもんだなぁ〜
C++やJavaなんかのメソッドがクラスに属しているオブジェクト指向とは全くの別物だ。頭を切り替えて使わないといけない。
帰省中に付箋を付けながら読んでいたので、拾い上げておく。
xyzzyで使えないものだから、ちゃんと勉強したことが無くて:beforeとか:afterとかよく分かってなかったんだけど、やっと分かった。(とりあえず使ってみようと思うくらいには)
メソッド結合かぁ〜 よく考えたもんだなぁ〜
C++やJavaなんかのメソッドがクラスに属しているオブジェクト指向とは全くの別物だ。頭を切り替えて使わないといけない。
帰省中に付箋を付けながら読んでいたので、拾い上げておく。
- p.7 括弧にある「他の本では読者の課題として残してあるもの」というのは中規模のプログラムなのか、言語の説明なのか
- p.10 *5 CMU も略語なんだから「Carnegie Mellon University」とした方がいいような。本文に「カーネギーメロン大学」とあるから英語の方にはいらなかったんだろうけど。
- p.25 if, not 説明なしで登場。(これ以降も関数が説明なしで登場するのがあったな)
- p.26 *5 「これは都合がいいこと」の「これ」が指すものが分かりにくい。たぶんスラッシュを解釈する方。
- p.37 where は短くなってるか? 別関数に処理を追い出しただけのような。コードを見る。
- p.41 *6 浮動小数点の要求精度を確認する。浮動小数点と整数が同じ型になる場合があると読めなくもないとするのは意地が悪いか?
- p.45 special form の一覧を確認する。
- p.47 *7 言われてみればと納得。確かにマクロか関数かで悩んだ覚えが無いけど、無意識にこういう感じで判別していたんだな。
- p.57 &optionalと&keyの組み合わせは注意。
- p.69 *11 スレッドごとにダイナミック変数。
- p.71 「ローカル変数としてtが使えないのは、たまにイラっとくる」←あるある(笑)
- p.78 「構文」は「syntax」の訳じゃないのかな。確認する。
- p.81 ここで気づいたけど「Common Lisp」と言ったり「Lisp」と言ったりしてるな。英語は繰り返しを避けるからか。
- p.81 *5 深いなぁ
- p.91 マクロを書くステップ。
- p.98 マクロを書くときの注意点。
- p.121 バックスラッシュが足りない。正誤表にあったのはここか。
- p.127 「LENGTH、ELT、ELTに対する〜」←eltの連続が気になるなぁ。「そして」とか挟めばよかったかも。
- p.129 関数名は大文字じゃないのだろうか。関数名じゃないということか?確認する。
- p.137 こんな後ろにconsが初出。
- p.143 副作用の結果が規定されている関数もある。
- p.144 非破壊的→共有 破壊的→共有されていないことが前提。
- p.144 イディオム push+nreverse setf+delete
- p.145 mergeも破壊的。
- p.146 (caar (list 1 2 3)) はエラーになるよね。確認する。
- p.147 null は空リストのテスト。
- p.149 「幻想」が気になる。原文を確認。
- p.149 proper listの訳は「真リスト」か。個人的には「純リスト」とか「正リスト」とか「正規リスト」とかのイメージ。
- p.152 「塊を操作する」が気になる。原文を確認。
- p.152 集合論なんだから「和集合」とか「積集合」とかの用語を入れて欲しいなぁ。
- p.153 連想リストって出てきたっけ?
- p.155 plistはeqで比較。
- p.157 *4 分かりにくいけどsetfでsymbol-plistをそっくり置き換える話か。(setf (symbol-plist 'foo) nil)みたいな。
- p.166 文字列→パスネーム pathname、パスネーム→文字列 namestring
- p.170 ディレクトリを作る→ensure-directories-exist
- p.172 「配管」は気になる。原文を確認。
- p.218 パディングに全角文字を指定したらどうなる?
- p.251 「コンパイル時に情報を使って保存して〜」よく分からない表現。原文を確認。「コンパイル時に同じファイルに保存してある情報を使って」ってこと?
- p.253 ここでやっとintern
- p.268 「(CLer)黒帯のためのLOOP」のニュアンスなのか。なるほど。
- p.285 「この場合にはincrement-countの2番目のx引数として渡された〜」変なxが紛れ込んでる。
- p.308 マクロ内で名前を生成しない。
- p.311 「どの型をread-valueに渡xすか〜」変なxが紛れ込んでる。
- p.312 prognメソッド結合
- p.325 「ここでのミソは、それらの数値をxどうやって〜」変なxが紛れ込んでる。
- p.445 「処理系依存のライブラリを使う不利な点は唯一、〜」←「唯一」は前に持ってきて「処理系依存のライブラリを使う唯一の不利な点は、〜」とかの方が自然かも。
* Common Lisp : 関数とマクロとスペシャルフォームの違い
http://d.hatena.ne.jp/pgf2/20080415/1208269126
ざっくりとした違いは関数は全ての引数が評価される、マクロとスペシャルフォームはそうとは限らないという点です。
関数が評価されるときは、まず引数を前から順番に評価し、全部の引数を評価したらその値を用いて関数のフォームを評価するという風に評価順序が決まっています。
マクロやスペシャルフォームは、評価順序が一定でなかったり、全ての引数が評価されなかったりします。
例えばスペシャルフォームの「if」はTHEN節とELSE節のどちらか一方しか評価されません。
評価規則が決まっている関数の枠組みでは「if」は定義できないということになります。
マクロの特徴は展開できるということです。
展開形は macroexpand や macroexpand-1 で確認できます。
スペシャルフォームは「3.1.2.1.2.1 Special Forms」で挙げられているものです。
マクロとスペシャルフォームの関係は排他的ではないので、マクロでありかつスペシャルフォームというものがある実装もあるかもしれません。
まとめとして setq と set と setf の関係
(setq a "value") と (set (quote a) "value") はほぼ等価。(厳密には違います。xyzzyでその差が出るかどうかは不明)
(setq a "value") と (setf a "value") は等価。
なぜなら
ざっくりとした違いは関数は全ての引数が評価される、マクロとスペシャルフォームはそうとは限らないという点です。
関数が評価されるときは、まず引数を前から順番に評価し、全部の引数を評価したらその値を用いて関数のフォームを評価するという風に評価順序が決まっています。
マクロやスペシャルフォームは、評価順序が一定でなかったり、全ての引数が評価されなかったりします。
例えばスペシャルフォームの「if」はTHEN節とELSE節のどちらか一方しか評価されません。
評価規則が決まっている関数の枠組みでは「if」は定義できないということになります。
マクロの特徴は展開できるということです。
展開形は macroexpand や macroexpand-1 で確認できます。
スペシャルフォームは「3.1.2.1.2.1 Special Forms」で挙げられているものです。
マクロとスペシャルフォームの関係は排他的ではないので、マクロでありかつスペシャルフォームというものがある実装もあるかもしれません。
まとめとして setq と set と setf の関係
(setq a "value") と (set (quote a) "value") はほぼ等価。(厳密には違います。xyzzyでその差が出るかどうかは不明)
(setq a "value") と (setf a "value") は等価。
なぜなら
(macroexpand '(setf a "value")) =>(setq a "value")だから。
* memo : xyzzy lisp FFI
いつかちゃんとまとめたい。
- 基本
- データ型関連
- int -> c:int, double -> c:double, ...
- ポインタ型は「(c:char *)」というようなリストの形で表現
- C の構造体は c:define-c-struct で定義
- C の関数を呼ぶ関連
- c:define-dll-entry で C 関数のインターフェースを作る
- c:define-dll-entry RETURN-TYPE NAME (&rest ARGS) DLL-NAME &optional EXPORT-NAME
- RETURN-TYPE 関数の戻り値
- NAME 関数名
- ARGS 関数の引数
- DLL-NAME DLLのパス
- EXPORT-NAME Cの関数名 (DLLでexportされているもの)
- データのやり取りは chunk を介する
- C から呼べる関数(callback関数)を作る関連
- c:defun-c-callable で作る
- c:defun-c-callable RETURN-TYPE NAME (&rest ARGS) &body BODY
- RETURN-TYPE 関数の戻り値の型
- NAME 関数名
- ARGS 関数の引数
- BODY 関数の定義
- データのやり取りは chunk を介する、ということで同上
- 注意点
- 下手をすると簡単に xyzzy が落ちることを頭に入れておく
- gc に注意する
- gc で回収されないオブジェクトを作らない
- C の関数が動いているときに chunk が gc されないように気をつける
- ポインタ型は全部「void *」とみなしても問題ない
- 「void *」は「unsigned long (32bit unsigned integer)」と等価として扱うこともできる
- xyzzy の未実装やバグにも注意
- その他、外部とのやり取り
- dde
- ole
* 2008-03-13 :
- ドキュメントを更新。
- http://raido.sakura.ne.jp/southly/lisp/doc/
- ソースの公開は repository を作ってから。
- 修正の必要な部分だけ再定義して出力を変えようとしたけれどうまくいかなかった。
- 関数定義のタイミングでマクロが展開されているということは、マクロを再定義したらそのマクロを使っている関数も再定義が必要ということですな。
- ソースを書き換えてしまった方が手軽だな。
- Common Lisp に慣れすぎて Scheme は書けそうにないなと思った。
* 2008-03-05 :
- マクロ展開が起こるのは評価時 or コンパイル時という理解でした。
- xyzzy の動作はまさしくこれですよね。
- sbcl はインタプリタがないので定義と同時にコンパイルされて、納得の結果。
- ecl はよく知らない。
- clisp の結果は自分にとってはちょっと不思議。
- 気になったので CLtL2 を確認してみたら、8章の最初のページにありました。
More generally, an implementation of Common Lisp has great latitude in deciding exactly when to expand macro calls within a program. For example, it is acceptable for the defun special form to expand all macro calls within its body at the time the defun form is executed and record the fully expanded body as the body of the function being defined.で、例えば defun での関数定義時にマクロを展開することもOKと書いてありました。
* 2008-03-04 :
- エスケープシーケンスの件は readtable をいじるのが妥当かな。
- cl-interpol の reader を引数をあわせて使うのが一番楽そう。やってみるか。
- cldoc の使い方がなんとなく分かった。けど、使い方を調べた関数 etc のメモを取りたいんだよな〜
- cldoc の出力する html も気に入らないので手を入れたい……
- メモを取るという目的からすると一度 DocBook 形式で出力する Albert の方が向いていそうだけど、DocBook よく分からんし。
- 話は変わって、MediaWiki ですか。実績も十分ですし、日本語の情報も多そうですし、良いんじゃないでしょうか。
- 個人的には MoinMoin はどうなかな〜とか思ってました。
- Colorize code に Lisp syntax があったら絶対こっちを推しましたけど、無いみたいです。残念。
- loop マクロといえば http://homepage1.nifty.com/bmonkey/lisp/index.html にもあったりしますけど、どんな感じなんでしょう。loop マクロは基本的に使わないので、試してないのですが。
* 2008-02-25 :
- Mercurial はなかなかよい感じかも。
- http://raido.sakura.ne.jp/southly/hgrepos/
- svn と干渉しないで使えるのが気楽だ。
- 認証はもう少し調べてからやることに。
- ID と password をどう共有するかも考えないといけないし。
- package の件
- trace マクロ
- Common Lisp いじっていると xyzzy でも欲しくなった。
- kia さんのとこにもあるのだけど encapsulate が関数なのが気になってマクロを書いてみることに。
- 思ってたより何とかなっている感じ。
- TODO : 引数の &optional etc の扱いを何とかする。
- Xyzzy Wiki
- 最近使いにくいッス。
- これを気をつければ spam フィルタに引っかからない、というのを教えていただきたいッス。
- (xyzzy :hack :-) - fixdap
- いい感じ。
- 他の参加者も発言してくれるともっといいのになぁ〜
- はてなダイアリーキーワードを編集できる人にお願い
- xyzzy の「Emacs Lisp ではなく Common Lisp を実装」→「Emacs Lisp ではなく Common Lisp をベースにした独自の Lisp 方言を実装」に変更。
- CommonLisp のフリーの処理系から xyzzy を外す。
- よく知らない人が xyzzy を Common Lisp 処理系として使うのは危ういので修正してもらえないかなと思います。
- いまさら気付いたので反応。> matsuokaさんとこ
- はい。私です。
- ちなみに ctags.l はあの時話題になっていたので調べてみただけで、使っていないんですよね (^^;
- 普段は XTAGS を使ってます。
* lisp : 破壊とか非破壊とかの話
SANOさんとこの補足のつもり。(だけど補足になれているかどうかは不明)
整理し切れていないので箇条書きで。
整理し切れていないので箇条書きで。
- Common Lispのオペレータには関数・マクロ・スペシャルフォームがあるけど、この件が関係するのは関数のみ。
- 純粋な意味での「関数」はいくつかの引数をとり、結果を返すということだけをするもの。(数学における意味での「関数」に近い)
- 「関数」が結果を返すこと以外に他へ影響を与えることを副作用という。引数の破壊は副作用の一種。
- 純粋な意味での「関数」として使っていれば、引数の破壊が起こっていてもいなくても同じ結果が得られる。
- それなのにわざわざ副作用をもつ破壊的な関数を用意するのは効率のため。
- 破壊的な関数は同等の非破壊関数で置き換えられる。置き換えられない使い方は間違い。
- 非破壊関数を同等の破壊的な関数で置き換えられるかどうかは、状況次第。
- どっちを使ったら良いか分からないときは非破壊関数を使うべし。効率が悪いかもしれないけれどxyzzyで使う程度の処理で差が出るなんてことはほとんど無いと思う。
- 副作用が目的の関数(vector-popとかvector-pushとか)は引数が変更されても破壊的と称さないっぽい。
* 2007-02-24
- 邦訳中→Common LISP Hints
- だらだらやっていたら思った以上に時間がかかってしまった。
- 校正→html化の予定。
- マクロに関する説明を追加したいな。
- 今日明日スノボに行って来ます。雪あるかな。
* 「入門 Common Lisp - 関数型4つの特徴とλ計算」の著者のページを見た
http://nlp.dse.ibaraki.ac.jp/~shinnou/books.html
無茶苦茶な制約があったもんだ。
「Lisp の入門書ではない」「xyzzy と関連させる」「xyzzy のマクロを作る本ではない」の3つは同時には成立しないでしょう。
「Lisp の入門書ではない」「xyzzy と関連させる」だったらxyzzyのマクロの話しかないし、
「xyzzy と関連させる」「xyzzy のマクロを作る本ではない」だったらLispの基礎の基礎をやるしかないし、
「Lisp の入門書ではない」「xyzzy のマクロを作る本ではない」だったらxyzzyが絡む余地は無いよ。
なんで無理やりxyzzyを絡めようとしたのか謎。
Common Lispは関数型言語としては泥臭すぎて関数型言語の勉強には向かないと思います。
Lisp系ならSchemeを選ぶべきかと。
末尾再帰の最適化の保証が無いから再帰よりもループを使うでしょうし、
値を返さない関数もあるし、
setfが便利すぎて代入文も普通に使うんじゃないでしょうか。
無茶苦茶な制約があったもんだ。
「Lisp の入門書ではない」「xyzzy と関連させる」「xyzzy のマクロを作る本ではない」の3つは同時には成立しないでしょう。
「Lisp の入門書ではない」「xyzzy と関連させる」だったらxyzzyのマクロの話しかないし、
「xyzzy と関連させる」「xyzzy のマクロを作る本ではない」だったらLispの基礎の基礎をやるしかないし、
「Lisp の入門書ではない」「xyzzy のマクロを作る本ではない」だったらxyzzyが絡む余地は無いよ。
なんで無理やりxyzzyを絡めようとしたのか謎。
Common Lispは関数型言語としては泥臭すぎて関数型言語の勉強には向かないと思います。
Lisp系ならSchemeを選ぶべきかと。
末尾再帰の最適化の保証が無いから再帰よりもループを使うでしょうし、
値を返さない関数もあるし、
setfが便利すぎて代入文も普通に使うんじゃないでしょうか。
* 「入門Common Lisp〜関数型4つの特徴とλ計算」感想
http://book.mycom.co.jp/book/4-8399-2081-8/4-8399-2081-8.shtml
- 関数型プログラミング言語の入門であってCommon Lispの入門ではない。
- マクロ、関数の引数(&optionalとか&keyとか)、スペシャル変数辺りの解説が無いのはCommon Lispの解説書としてありえない。
- そもそもwhile(p.70)なんてCLtL2には無いし。
- 用語や関数の登場とその説明のタイミングが若干不親切。(S式やand)
- function(#')を説明していないものだから全体的にコードがelispっぽい。
- xyzzyとの差である大文字小文字の区別に言及していないのもダメ。
- lisp-modeにならない拡張子で保存させているところもダメ。
- 「8. λ計算」が本題で7章までは全部前置きという印象。
* 素数を求める
素直じゃない再帰・マクロ(ほぼ)無し
(defun generate-primes (limit) (format t "~{ ~D~}~%" (funcall (lambda (f c n &optional (x 3) (prime (list 2))) (funcall f f c n x prime)) (lambda (f c n x prime) (if (> x n) (nreverse prime) (if (funcall c c x prime) (funcall f f c n (+ x 2) (cons x prime)) (funcall f f c n (+ x 2) prime)))) (lambda (c x prime) (if (endp prime) t (if (zerop (rem x (car prime))) nil (funcall c c x (cdr prime))))) limit)))
* Scrapbook : LispUser.net : 最高にキモい Lisp コードを書いてみよう with 100 行リーダーマクロ
* clispでcgi
URIのデコード・エンコードが一応完成。
感想メモ
・whileが無くてびっくり
・xyzzy lispとの微妙な差が気になる
・(alphanumericp #\あ) => T ってなんだよ!?
(ReadMore...)
感想メモ
・whileが無くてびっくり
・xyzzy lispとの微妙な差が気になる
・(alphanumericp #\あ) => T ってなんだよ!?
(ReadMore...)
page 0 - << : 0 : >>