勉強ノート - SICP(7):高階手続き

 これは楽しすぎる!
 関数の引数に関数を渡すっていうのが高階手続き。いわゆるコールバック関数みたいなもんだろうと理解。
 以下SICPに載っていたSchemeのコードをJavaScriptに書き換えた版。

<html>
<head>
<script>

var $ = function (id) { return document.getElementById(id); };

var cube = function (a) { return a * a * a; };
var inc  = function (n) { return n+1; };
var identity = function (n) { return n; };

var sum = function (term, a, next, b)
{
  if (a > b) return 0;

  return term(a) + sum(term, next(a), next, b);
};

/*
 * SumCube()
 * aからbまでの整数の三乗の和
 *
 */
var SumCube = function (a,b)
{
  return sum(cube, a, inc, b);
}

/*
 * SumIntegers()
 * aからbの整数の和
 *
 */
var SumIntegers = function(a,b)
{
  return sum(identity, a, inc, b);
}

/*
 * PiSum()
 * πの近似値を求める
 *
 */
var PiSum = function (a, b)
{
  return sum(function(x){ return 1 / ((x + 2) * x);},
             a,
             function(x){ return x + 4; },
             b);
}

</script>
</head>
<body>
<a href="#" onclick="$('disp').textContent = SumCube(1, 10);">1から10までの整数の三乗の和</a><br><br>
<a href="#" onclick="$('disp').textContent = SumIntegers(1, 10);">1から10までの整数の和</a><br><br>
<a href="#" onclick="$('disp').textContent = 8 * PiSum(1, 1000);">πの近似値</a><br><br>

<div id="disp"></div>
</body>
</html>

 ちなみにFirefoxじゃないと動かないのであしからず。
 関数の引数に関数を渡すテクニックは知っていたけれども、こういう使い方は思いつかなかったなぁ。
 SchemeならコレでもOKだけど、JavaScriptC++だったら、これはwhileやforを使って実現すべきなのかもね。しかし sum() がシンプルすぎて何度見ても鼻血が出そう。

余談

 lambdaを激しく「ランバダ」って読んでしまったんだけども、


 どう見てもマイノリティです。本当にありがとうございました。