1.3.1 Functions as Arguments

38636 단어 SICPSICP

1 Building Abstractions with Functions


3 Formulating Abstractions with Higher-Order Functions


1 Functions as Arguments


Consider the following three functions.

다음 세 함수를 살펴보자.

The first computes the sum of the integers from a through b:

첫 번째 함수는 두 정수 ab 의 합을 계산한다.

function sum_integers(a, b) {
  return (
    a > b
    ? 0
    : a + sum_integers(a + 1, b)
  );
}
The second computes the sum of the cubes of the integers in the given range:

두 번째 함수는 주어진 범위 안의 정수를 세 제곱해 합한다.

function sum_cubes(a, b) {
  return (
    a > b
    ? 0
    : cube(a) + sum_cubes(a + 1, b)
  );
}
The third computes the sum of a sequence of terms in the series which converages to π/8\pi/8 (very slowly):

세 번째 함수는 π/8\pi/8로 수혐하는 다음 수열 중 일부의 합을 계산한다.

113+157+1911+{1 \over 1 \cdot 3} + {1 \over 5 \cdot 7} + {1 \over 9 \cdot 11} + \cdots
function pi_sum(a, b) {
  return (
    a > b
    ? 0
    : 1 / (a * (a + 2)) + pi_sum(a + 4, b)
  );
}
These three functions clearly share a common underlying pattern.

이 세 함수는 명백하게도 몇 가지 공통 패턴을 공유한다.

They are for the most part identical, differing only in the name of the function, the function of a used to compute the term to be added, and the function that provides the next value of a.

함수의 대부분이 비슷하고, 함수의 이름, a번째 더해질 무언가, 그리고 다음 a값을 구하는 방법만이 조금씩 다르다.

We could generate each of the functions by filling in slots in the same template:

다음 탬플릿의 일부를 수정해서 이러한 함수들을 만들 수 있다:

function something_name(a, b) {
  return (
    a > b
    ? 0
    : term(a) + something_name(next(a), b)
  );
}
The presence of such a common pattern is strong evidence that there is a useful abstraction waiting to be brought to the surface.

이러한 공통 패턴이 보인다는건 수면 위로 드러나기를 기다리는 아주 유용한 추상화가 기다리고 있다는 것을 의미한다.

Indeed, mathematicians long ago identified the abstraction of summation of a series and invented "sigma notation," for example to express this concept.

실제로, 아주 오래 전 수학자들은 이러한 수열의 합시그마 표현법으로 추상화했다.

n=abf(n)=f(a)++f(b)\sum_{n=a}^{b} f(n)=f(a) + \cdots + f(b)
The power of sigma notation is that it allows mathematicians to deal with the concept of summation itself rather than only with particular sums - for example, to formulate general results about sums that are independent of the particular series being summed.

시그마 표현법의 힘은 수학자들에게 부분 합의 나열이 아닌 합 그 자체의 개념을 다룰 수 있게 했습니다. 예를 들어, 특정 수열의 일부분의 합을 수식으로 공식화합니다.

Similarly, as program designers, we would like our language to be powerful enough so that we can write a function that expresses the concept of summation itself rather than only functions that compute particular sums.

프로그램 디자이너들도 마찬가지로, 특정 합을 계산하는 함수만이 아닌 어떤 개념을 요약하는 함수를 작성할 수 있고, 그만큼 프로그래밍 언어는 강력해졌습니다.

We can do so readily in our functional language by taking the common template shown above and transforming the "slots" into parameters:

우리는 함수형 프로그래밍 언어에서 위에서 살펴본 템플릿의 "슬롯"을 매개변수로 받아 가독성을 향상시킬 수 있습니다.

function sum(term, a, next, b) {
  return (
    a > b
    ? 0
    : term(a) + sum(term, next(a), next, b)
  );
}
Notice that sum takes as its arguments the lower and upper bounds a and b together with the functions term and next.

sum이 함수 termnext 을 경계값 a, b 와 함께 받는다는 점을 유의해야 합니다.

We can use sum just as we would any function.

우리는 sum 을 다른 함수와 마찬가지로 사용할 수 있습니다.

For example, we can use it (along with a function inc that increments its argument by 1) to define sum_cubes:

예를 들어, 인자를 1씩 증가시키는 inc 를 매개변수로 사용한 sumsum_cubes 를 정의하는데 사용할 수 있습니다.

function inc(n) {
  return n + 1;
}
function sum_cubes(a, b) {
  return sum(cube, a, inc, b);
}
Using this, we can compute the sum of the cubes of the integers from 1 to 10:

이를 통해, 1과 10 사이에 있는 정수들의 세제곱의 합을 구할 수 있습니다.

sum_cubes(1, 10); // 3025
With the aid of an identity function to compute the term, we can define sum_integers in terms of sum:

그 자체를 반환하는 함수를 정의하므로써, 우리는 sum 을 통해 sum_integers 를 정의할 수 있습니다.

function identity(x) {
  return x;
}
function sum_integers(a, b) {
  return sum(identity, a, inc, b);
}
Then we can add up the integers from 1 to 10:

이를 통해 1과 10 사이에 있는 정수를 더할 수 있습니다.

sum_integers(1, 10); // 55
We can also define pi_sum in the same way:

또한 다음과 같이 pi_sum 을 정의할 수도 있습니다.

function pi_sum(a, b) {
  function pi_term(x) {
    return 1 / (x * (x + 2));
  }
  function pi_next(x) {
    return x + 4;
  }
  return sum(pi_term, a, pi_next, b);
}
Using these functions, we can compute an approximation to π\pi:

이를 통해 π\pi 에 근접한 값을 구할 수 있습니다.

8 * pi_sum(1, 1000); // 3.139592655589783
Once we have sum, we can use it as a building block in formulating further concepts.

sum 을 정의하고 나면, 다른 개념을 정의하는데 이를 벽돌처럼 사용할 수 있습니다.

For instance, the definite integral of a function ff between the limits aa and bb can be approximated numerically using the next formula for small values of dxdx:

예를 들어, ffaa 에서 bb 까지 적분하는 것을 다음 식으로 접근할 수 있습니다.

abf=[f(a+dx2)+f(a+dx+dx2)+f(a+2dx+dx2)+]dx\int_a^b f = \left[ f(a + {dx \over 2}) + f(a + dx + {dx \over 2}) + f(a + 2dx + {dx \over 2}) + \cdots \right] dx
We can express this directly as a function:

이는 다음과 같은 함수로 표현할 수 있습니다.

function integral(f, a, b, dx) {
  function add_dx(x) {
    return x + dx;
  }
  return sum(f, a + dx / 2, add_dx, b) * dx;
}
integral(cube, 0, 1, 0.01); // 0.24998750000000042
integral(cube, 0, 1, 0.001); // 0.249999875000001
(The exact value of the integral of cube between 0 and 1 is 1/4.)

세제곱 함수를 0에서 1까지 적분한 값은 1/4이다.

좋은 웹페이지 즐겨찾기