2010/09/30

おめでとうございます!「『Scheme手習い』(The Little Schemer, 4th edition)10月23日発売予定」

めでたい!今年は Lisp 本が豊作ですね!
『Scheme手習い』(The Little Schemer, 4th edition)、印刷所に入稿。10月23日発売予定。 http://bit.ly/bokZZk




追記

MIT の教科書 "計算機プログラムの構造と解釈" (昔は構造と実行) を読む為の本だったそうである。
まじか!

追記2


Scheme手習い

2010/09/27

unfold の cons が指定できても良いような

そんなことを思ったのでメモがてら。


追記

@valvallow (define(accrec-right p f g c s :optional(t'()))(let l((s s)(a t))(if(p s)a(l(g s)(c(f s)a))))) unfoldとunfold-rightの最後の引数は意味が違いますよ
(define (accrec-right p f g c s :optional(t'()))
   (let l ((s s)(a t))
     (if (p s)
         a
         (l(g s)(c (f s) a)))))

(accrec-right null? car cdr cons '(1 2 3 4 5) '(0))
;; (5 4 3 2 1 0)

このオプション引数の指定のやり方、知りませんでした。。
それに、unfold、unfold-right の引数も確認しました。
ありがとうございました!!

追記2

これは Hylomorphism になるのかなあ: 「unfold の cons が指定できても良いような」 http://valvallow.blogspot.com/2010/09/unfold-cons.html
ヒロモーフィズム?ハイロモーフィズム?何と読むんでしょうか。。初めて聞きました。
意味はわかりませんが、
「アナモルフィズム」(anamorphism)
「アポモルフィズム」(apomorphism)
とかいった言葉は srfi-1 のドキュメントで目にしたことがあります。

追記3

leque さんのコメントより。ありがとうございます!
『関数プログラミングの楽しみ』ではリストに対する hylomorphism を次のような感じで定義しています。
(define (hylo f e p g h seed)
  (fold-right f e (unfold p g h seed)))

(define (fact n)
  (hylo * 1 (cut = <> 0) values (cut - <> 1) n))
おお。なんかカッコイイ!

こんな感じでも良いのかな。
(define (fact n)
  (hylo * 1 zero? identity (lambda (n)
                             (- n 1)) n))

(define (fact n)
  (fold * 1 (unfold zero? identity (cut - <> 1) n)))


プログラミングGauche

Re: comp.lang.scheme で簡単なリスト操作のお題が出ておるな。

comp.lang.scheme で簡単なリスト操作のお題が出ておるな。 http://goo.gl/5GAm
ということで、やってみました。Scheme(Gauche)です。

以下コード。


追記

教えて頂きました!いつもありがとうございます!
@valvallow (use gauche.sequence)(use srfi-1)(define(key-sorted-combine lst)(map(pa$ append-map cdr)(group-collection lst :key car)))
(use gauche.sequence)
(use srfi-1)
(define (key-sorted-combine lst)
  (map (pa$ append-map cdr)
       (group-collection lst :key car)))

(define data
  '((0 a b) (1 c d) (2 e f) (3 g h) (1 i j)
    (2 k l) (4 m n) (2 o p) (4 q r) (5 s t)))

(key-sorted-combine data)
;; ((a b) (c d i j) (e f k l o p) (g h) (m n q r) (s t))
group-collection 要チェックや!

そういえば、以前 group-sequence は見た記憶が。。

The Little Schemer, 4th Edition

2010/09/23

番号付き部分適用 cutn

srfi-26 の cut を使ってると (cut list 1 <0> 3 <1> 4) って書けたら・・・なんて思います。衛生的なマクロではありませんが、試しに書いてみました。

使用例はこんな感じ。<...> は考慮していません。あと、(cutn list <0> <1> (* <0> <0>)) のようなネストしたものは cut 同様考慮していません。

(最後の例が微妙な気もする)

cutn のコードはこちら。


うーん。

LET OVER LAMBDA Edition 1.0

ドット対をリストに変換する

基本的には終端を空リストにしたリストを返します。一応 terminal-fun にて終端を指定できるようにしました。
コードは以下の通り。


プログラミングGauche

先日書いた defmacro! がバグっていたので

先日書いたものがバグっていたので、修正しようとしましたが解決できず・・・。
バグは、defmacro! で可変長引数が取れないというものです。
例えば、
(defmacro! (sum . args) ...
とした時に args を filter して o! シンボルを g! シンボルに置き換えようとするところで、args がまだシンボルのままであるためエラーになるというものです。よって、その処理を書く場所に気をつけて評価順序を制御すれば良いだろうと思って修正を試みていたのですが、なかなかうまくいかず。。悔しいれす(^p^)



猫好きながら猫アレルギーにより鼻水ダラダラを理由に今日は一旦諦めます。。

追記

勘違いだったようです。というか見当違いでした。filter の引数に非リストを渡していたからっぽい。全然見当違いの修正を数時間やってました。。ご飯食べてお風呂入って、再度コードを見たらあっけなく・・・。




LET OVER LAMBDA Edition 1.0

2010/09/22

Emacs ポップアップ辞書

何これ便利すぎだろ!!(笑)
単語の上で C-c p




追記

教えてもらいました!ありがとうござます。
sdic-inline.el,sdic-inline-pos-tip.elもいいですよ!
なるほどこれも便利そうだ!

Emacsテクニックバイブル ~作業効率をカイゼンする200の技~

`',hoge は `(quote ,hoge)

実用 Common Lisp (IT Architects’Archive CLASSIC MODER) P.272
イディオム「`',fn-names」はコメントする価値がある。最初は混乱するかもしれないが、よく使用されるイディオムである。等価な形式 `(quote ,fn-names) のほうが、理解しやすいかもしれない。
これはわかりやすい。

実用 Common Lisp (IT Architects’Archive CLASSIC MODER)

PAIP の pipe でエラトステネスの篩(ふるい)

実用 Common Lisp (IT Architects’Archive CLASSIC MODER) 9.3 P.263 ~。
遅延評価による無限集合の例。遅延リストとしてのpipe。Scheme(Gauche)で書いたこともあり、コードは書籍とは若干違います。

pipe を用いたエラトステネスの篩。


delay と force による pipe


クロージャによる pipe



実用 Common Lisp (IT Architects’Archive CLASSIC MODER)

Common Lisp の /=

Common Lisp の /= は、(complement =) ってことですか。
で、これ何て読むのよ・・・。

COMMON LISP 第2版

Emacs 日付の挿入

F5 押したら「2010/09/22 18:29:20」のような日付が挿入されるだけなんだけど、意外と便利かも。
(define-key global-map [f5]
  '(lambda ()
     (interactive)
     (insert (format-time-string "%Y/%m/%d %H:%M:%S"))))

Emacsテクニックバイブル ~作業効率をカイゼンする200の技~

Re: schemeで全dataを+するのを知りたいです、か?

私もやってみました。

mysum

mytrans

myfind


プログラミングGauche

2010/09/17

Gauche の info を anything で引く

まじ便利!!

調べたい語句の前で C-M-;

すると anything のインターフェースで gauche の info が。



こちらを参考にしました。

.emacs に以下を追加しただけですが、これは劇的 before/after 。。
(defvar anything-c-source-info-gauche-refj
   ;; '((info-index . "~/../gauche/share/info/gauche-refj.info")))
  '((info-index . "gauche-refj.info")))
(defun anything-info-ja-at-point ()
  "Preconfigured `anything' for searching info at point."
  (interactive)
  (anything '(anything-c-source-info-gauche-refj)
            (thing-at-point 'symbol) nil nil nil "*anything info*"))
(define-key global-map (kbd "C-M-;") 'anything-info-ja-at-point)

今まではこちらを参考に使ってましたが、結局 Web のリファレンスを引くことが多かったです。

Emacsテクニックバイブル ~作業効率をカイゼンする200の技~

2010/09/15

LOL defmacro!

LET OVER LAMBDA Edition 1.0 の defmacro! を scheme(Gauche)で書きました。
基本的に同じものですが、実験的に g! や o! を変更できるようにしています。
Un-Common Lisp の defmacro* がプレフィックスに g!, o! をつけるのでなく、サフィックスに #, % を付けるスタイルなのを見て、切り替えられるようにしてみても良いかなぁと。切り替え方が不細工ですが、まぁお試しということで。

使用例はこんな感じ。


以下 defmacro! のコード。


追記

defmacro! に可変長引数が受け取れないバグがありました。修正しました。

LET OVER LAMBDA Edition 1.0

2010/09/14

On Lisp のユーティリティをいくつか

いくつか Gauche で書きました。写経がてら。前回読んだ時にあまり書いてないので、揃えておいた方が良いなぁと。
ざっくり書いただけなので、動かないところがあるかもしれません。

LET OVER LAMBDA Edition 1.0On Lisp を再読しているので、こういうのを揃えていこうと考えています。書きたいものがあるときにすぐに書き始められる状態を作っておかないといけないなぁと思った次第です。

以下コード。


On LispLET OVER LAMBDA Edition 1.0

昨日のライフゲームのソース

Scheme(gauche)で書かれています。

UI はまだありません。取り敢えずの使用方法。

10×10 でランダムな配置から始める。
(define lifegame (make-auto-step-lifegame 10 10))
(print-lifegame-table (lifegame :next))

30×30 でランダムな配置から始める。
(define erl (endless-repeat-lifegame (make-auto-step-lifegame 30 30)))
(erl)

データから読込む。読み込むデータが PULSER の場合。
(define pl (endless-repeat-lifegame (const->auto-step-lifegame PULSER)))
(pl)

以下ソース。

取りあえず用意したデータ。


追記

改めて書き直してみました。

プログラミングGauche

ライフゲーム作った


9LISP の宿題。Scheme(Gauche)で作りました。作りかけですが、動くので取りあえず。
行き当たりばったりで作ったこともあり、突っ込みどころ満載でちょっと恥ずかしいですが。。

ライフゲームの動き見てるのって意外と面白いんですね。

例えば、繰り返すパターン。
(load "./lifegame.scm")

(define-constant PULSER
  '((0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)))

(define pl (endless-repeat-lifegame (const->auto-step-lifegame PULSER)))
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ○ ○ ○ ○ ○ ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ● ○ ○ ● ○ ● ○ ● ○ ● ○ ○ ● ○ ○)
;; (○ ○ ● ● ● ○ ● ● ○ ● ● ○ ● ● ● ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ● ● ● ○ ● ● ○ ● ● ○ ● ● ● ○ ○)
;; (○ ○ ● ○ ○ ● ○ ● ○ ● ○ ● ○ ○ ● ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ○ ○ ○ ○ ○ ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)

まだ UI がないので、IronScheme で作ろうかなぁとか考えてます。それか手っ取り早く C# で GUI 作ってデータ読み込むとか。。それなら最初から C# で作れば良いじゃんという話ですね。

プログラミングGauche

2010/09/10

「最も簡単に fib を高速化する方法」を試してみた。

どうしてこれで速くなるの?
二つ値を返せば良いんですよ。メモ化なんてしなくていい。
取りあえず Scheme の多値でやってみました。速い。。どうして?



あとはまぁ、取りあえず参考までに。

メモ化。昨日のメモ化マクロを使ってみました。


遅延ストリーム。


末尾再帰。ようはループですわな。


普通の再帰。これは 10000 なんてとても試す気になれませんね。。


fib-i なぞ・・・。

追記

わかりました!というか教えて頂きました。末尾再帰の例と同じような計算の仕方だからですね。
末尾再帰ではないし、末尾再帰のようにその都度計算を行うのではなく再帰を戻りながら最後にまとめて計算する点は違えども、計算量は末尾再帰の例と同じということですよね。
というか、末尾再帰とか多値とかそういう話じゃないわけですね。。なんか、すいません。

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

追記2

爆速過ぎワロタ



実用 Common Lisp (IT Architects’Archive CLASSIC MODER)

PAIP: メモ化, memo, memoize, define-memo

メモ化。以前もいくつかいい加減な記事を書いています。。


メモ化については On Lisp や SICP(計算機プログラムの構造と解釈)なんかでも出てきますね。

今回はPAIP(実用 Common Lisp (IT Architects’Archive CLASSIC MODER))P.253 第3部 第9章 9.1 より。Common Lisp ではなく Gauche(Scheme)で書いてあるので、コードが多少違います。

以下コード。一つ目がmemo関数のプロトタイプで二つ目が本番 memo, meomize, define-memo, clear-memoize。都合により clear-memo も追加しています。

本番。



実用 Common Lisp (IT Architects’Archive CLASSIC MODER)

2010/09/09

syntax-rules, defmacro: define-cxr, define-cxr*

caaaar とか cadadadar などを定義するマクロ。LET OVER LAMBDA Edition 1.0 にもありました。

取りあえず書いてみました。
組み合わせて作っていく感じ。car + car で caar を作る、みたいな。
以下コード。


自分なりに考えてみたもの。もといし、効率も悪いけど意図通り動きます。
こちらは (define-cxr caar) とされたら a と d を car と cdr として手続きを組み立てる感じ。でも入力を制限していないので、my-caaar が caaar 相当の手続きに、ashitahadounaru? が caaadar 相当の手続きになります。。


追記

下のコード貼り間違えてました。修正。

追記2

map-accum でなくてもよかったですね。fold-right でよさそうです。
(define (cxr->ad-fun-lis sym)
  (fold-right (lambda (e acc)
                (let1 p (coalesce ((eq? e 'a) car)
                                  ((eq? e 'd) cdr))
                  (if p
                      (cons p acc)
                      acc))) '() (symbol->list sym)))

LET OVER LAMBDA Edition 1.0

syntax-rules: coalesce

これの関連で。。


こういうのが
(let1 e 'd
  (if (or (if (eq? e 'a)
              'car)
          (if (eq? e 'd)
              'cdr))
      'found
      'notfound))

こうなる
(let1 e 'd
  (if (coalesce ((eq? e 'a) 'car)
                ((eq? e 'd) 'cdr))
      'found
      'notfound))

cond みたい。inspired by SQL's coalesce.

プログラミングGauche

syntax-rules: if-true

(if (hoge? fuga) 'fuga #f) ってのをどうにかできないかなーと思うんですが良いアイディアがありません。マクロを書いてみましたがいまいち。。


追記

そうか and か!

プログラミングGauche

2010/09/08

Re: syntax-rules: define-overload (match-lambda*)

なるほど match-lambda* ですか!
実は match, match-lambda 辺りはよくわかってなかったので良い機会です。

書いてみました。以下コード。


というかもうマクロにする必要もなさそうですね。。match-lambda* 使えば良いですね・・・。

追記

case-lambda でよかったのかもしれない。。

プログラミングClojure

syntax-rules: define-overload (clojure の defn みたいなもの)

引数の数にマッチして呼び出される本体が変わる clojure の defn を思い出したので書いてみました。
書いてみると別にどうということはありませんね・・・。

なぜ define-overload という名前かというと、始めて defn を見たときの感想が C# のオーバーロードっぽいなぁだったので。。かっこいい名前が思いつきませんでした。そういや syntax-rules にも似てますよね。

まずはマクロを書く前に展開イメージを

以下マクロ本体


プログラミングClojure

読んだ「小さなチーム、大きな仕事」37signals

よく耳にするので気になっていた 小さなチーム、大きな仕事―37シグナルズ成功の法則 (ハヤカワ新書juice) を読みました。

読み始めこそ少し妙な感触でしたが、評判通り面白かったです。
途中で Getting Real の方もつまんでみましたが、雰囲気というかテンポというか、その辺がキモくて読むの止めました。

この 小さなチーム、大きな仕事―37シグナルズ成功の法則 (ハヤカワ新書juice) で述べられているものの中で、ポール・グレアムがよく言っている「早過ぎる最適化」と同様のものが多いなぁーと感じました。

例えば・・・
計画は予想に過ぎない(P.17)
計画は、過去に未来の操縦をさせる。(P.18)
完璧主義なのだと主張するかもしれないが、それは次の仕事にとりかからずに、つまらない細部に執着して時間を無駄にしているにすぎない。(P.23)
初めのうち詳細は気にしない(P.54)
完璧なタイミングは決して到来しない。いつも若すぎたり、年寄りすぎたり、忙しかったり、金がなかったり、その他いろいろだったりする。(P.33)
何が一番よいか想像するのはやめ、現実を見出すのだ。(P.68)
まだ起こっていない問題を作ってはいけない。現実に問題になってから考えれば良いことだ。多くの「もしも」は起こらない。(P.164)

他にも・・・
ポール・グレアム「変人の力」 - らいおんの隠れ家を思い出します。
無名であるのは、すばらしいことだ。日陰にいることを幸せに思おう。(P.118)
無名であれば、プライドを失うことも我を失うこともないだろう。(P.118)
誰もあなたの言うことに腹を立てないのなら、おそらく押しが足りないのだ(多分つまらないのだろう)。(P.34)

scheme みたいですね。サン・テグジュペリの言葉を思い出します。
多くのものは小さくすればするほどよくなる。(P.52) 

言語にこだわったり.emacsをチューニングし過ぎることですね、わかります。
誰にもありがちなことだが、ツールに没頭するあまり、やるべきことを忘れてしまうことがある。(P.62)
変わった書体や高価なフォトショップの特殊効果を駆使しながらも、伝えるものがなにもないデザイナー。(P.62)
銀塩カメラとデジタル機器について延々と議論をするものの、真に写真をすばらしくするものに注目しないアマチュア写真家。(P.63)
ビジネスの世界では、本質的な問題から目をそむけ、ツールや、ソフトウェアの細かなテクニック、スケールの問題、高価なオフィス空間、豪華な備品といったどうでもいいことに心酔する人があまりに多すぎる。(P.63)
実際に形あるものをつくり始めるのだ。それ以外のことはすべて注意をそらすだけだ。(P.70)

この37signalsの本や、いつも楽しく読んでいるポール・グレアムのエッセイなんかと、自己啓発系の書籍の違いが最近よくわかりません。何かが違うような気がしつつ、似てるよなぁーとも思います。何が違うんでしょうか。。それとも同じ類なんでしょうか。わかりません。どちらにしろ煽られ過ぎ、乗せられ過ぎには注意した方が良いのかもしれません。

まぁ、ハッカーと画家 コンピュータ時代の創造者たちを読んで Lisp をはじめたクチなので、なんとも言えませんが(笑)


小さなチーム、大きな仕事―37シグナルズ成功の法則 (ハヤカワ新書juice)

syntax-rules: dlambda

今日は、Twitter のタイムラインで LET OVER LAMBDA Edition 1.0 の話題が出ていました。
私も読みましたが、詳細はすでに記憶の彼方です。。再読したいところです。

記憶に残っている dlambda を scheme の syntax-rules で書いてみました。たぶん同じように動くと思います。

マクロを書く前に・・・
;; image
(define count-test
  (let ((count 0))
    (dlambda
     (:reset ()(set! count 0))
     (:inc (n)(inc! count n))
     (:dec (n)(dec! count n))
     (:bound (lo hi)
             (set! count (min hi (max lo count)))))))

;; expand image
(define count-test
  (let ((count 0))
    (lambda (key . args)
      (case key
        ((:reset)(apply (lambda ()
                          (set! count 0)) args))
        ((:inc)(apply (lambda (n)
                        (inc! count n)) args))
        ((:dec)(apply (lambda (n)
                        (dec! count n)) args))
        ((:bound)(apply (lambda (lo hi)
                          (set! count
                                (min hi (max lo count)))) args))
        (else key)))))

(count-test :reset)
;; 0
(count-test :inc 100)
;; 100
(count-test :inc 1)
;; 101
(count-test :inc 2)
;; 102
(count-test :bound -10 10)
;; 10
(count-test :reset)
;; 0
(count-test :inc 1)
;; 1

以下マクロのコード


LET OVER LAMBDA Edition 1.0

2010/09/06

append

ちゃんと書こうとすると、意外と難しいですね。

これだと (append '() 1) が 1 にならないですね。

こんな感じでしょうか。


最近、諸事情により昼間にパソコンを開く時間があまりありません。。

追記

(use srfi-1)
(define (list-append x . n)
  (if (null? n)
      x
      (unfold null? car cdr x
              (lambda _
                (apply list-append n)))))

なるほど!そういえば・・・

追記2

reduce-right!
(use srfi-1)
(define (list-append . xss)
 (reduce-right append1 '() xss))

The Little Schemer, 4th Edition

2010/09/01

ほんやく


下手は上手の下地なり 下手よりだんだん上手になるなり。(寒河正親)

って言うし。
日本語で読みたいけど、どうやら翻訳されていないっぽい短い文章があった。取りあえずやってみようかなーとか。

翻訳の基本―原文どおりに日本語に