読者です 読者をやめる 読者になる 読者になる

(define -ayalog '())

括弧に魅せられて道を外した名前のないプログラマ

Scheme可愛いよって話をしていたら、「括弧が多い」って言われたので

Scheme Gauche

今日は昼間、会社の同僚と久しぶりに会って話していました。

そして、話しているうちにSchemeかわいいという話を僕がしていて、実際にFizzBuzzのコードを書いてみせて、その後Project-Eulerの問題を解いてみせたんですが、「でも、括弧が多いし…」と言われたのでちょっと括弧とか"lambda"というのを極力書かない書き方をしてみせてみた。

お題はProjectEuler Problem 2より"Even Fibonacci numbers"。

フィボナッチ数列の項は前の2つの項の和である. 最初の2項を 1, 2 とすれば, 最初の10項は以下の通りである.

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
数列の項の値が400万より小さい, 偶数値の項の総和を求めよ.

普通に解いてみる。
とりあえず、手続きfib*1があるとして、(fib n)が400万を超える適当なnを決めている状態で解く。

(fold + 0
      (filter even?
	      (filter (lambda (x) (>= 4000000 x))
		      (map fib
			   (iota 100 1)))))

これで答えが出ます。短い!素敵!
実際には400万を超えるのは(fib 34)のときなので、100はふっかけすぎだけどまぁいいや。
で、これを見た同僚が「括弧多い」っていうので、括弧を減らしてみた。

($ fold + 0
   $ filter even?
   $ filter (^n (>= 4000000 n))
   $ map fib
   $ iota 100 1)

括弧が少ない!lambdaっていう文字列もない!素敵!

まぁGaucheだから出来たんですが、こんな感じでどうでしょう。
ただ、

これはあくまで好みの問題ですし、こういった構文糖衣は濫用されがちなので 気をつけてください。けれどもスパイスのように、控えめな隠し味として使うと、 しばしばとても有用です。
Gauche ユーザーリファレンスより

ということですので、ほどほどにしませう。。

Problem2について

どうでもいいことだけど問題の雰囲気だと、どちらかというと下のように解くほうが良い気がするんだけど、あくまでも上のは例として書いたので適当で。

(define (fib n)
  (define (iter a b max-value)
    (if (< max-value a)
	()
	(cons a (iter (+ a b) a max-value))))
  (iter 1 0 n))

(define (even-sum li)
  (apply + (filter even? li)))

(even-sum (fib 4000000))

*1:割りと高速な奴じゃないと時間かかるので注意