In using `sum` as in
section 1.3.1, it seems
terribly awkward to have to declare trivial functions such as
`pi_term` and
`pi_next` just so we can use them as
arguments to our higher-order function. Rather than declare
`pi_next` and
`pi_term`, it would be more convenient
to have a way to directly specify the function that returns its
input incremented by 4

and the function that returns the
reciprocal of its input times its input plus 2.

We can do this
by introducing *lambda expressions*, which create functions.
Using lambda expressions, we can describe what we want as

x => x + 4;

x => 1.0 / (x * (x + 2));

Then our
`pi_sum`
function
can be expressed without
declaring any auxiliary functions
as

function pi_sum(a,b) { return sum(x => 1.0 / (x * (x + 2)), a, x => x + 4, b); }

Again using
a lambda expression,
we can write the `integral`
function
without having to
declare the auxiliary function
`add_dx`:

function integral(f, a, b, dx) { return sum(f, a + dx / 2.0, x => x + dx, b) * dx; }

In general, lambda expressions are used to create functions similarly to function declarations, except that no name is specified for the function and the return keyword along with the curly braces can be omitted.[1] \[ \texttt{(} \ \textit{parameters}\ \texttt{) => } \textit{expression} \]

The resulting function is just as much a function as one that is created using a function declaration statement. The only difference is that it has not been associated with any name in the environment. In fact,

function plus4(x) { return x + 4; }

const plus4 = x => x + 4;

We can read a lambda expression as follows:

// read x => x + 4 // as: ^ ^ ^ ^ ^ // function with argument x that results in the value plus 4

Like any expression that has a function as its value, a lambda expression can be used as the function expression in an application such as

((x, y, z) => x + y + square(z))(1, 2, 3);

Another use of lambda expressions is in creating local names. We often need local names in our functions other than those that have been bound as parameters. For example, suppose we wish to compute the function \[ f(x,y)=x(1+xy)^2 +y(1-y)+(1+xy)(1-y)\] which we could also express as \begin{eqnarray*} a &=& 1+xy\\ b &=& 1-y\\ f(x,y) &=& xa^2 +yb +ab \end{eqnarray*} In writing a function to compute $f$, we would like to include as local names not only $x$ and $y$ but also the names of intermediate quantities like $a$ and $b$. One way to accomplish this is to use an auxiliary function to bind the local names:

function f(x, y) { function f_helper(a, b) { return x * square(a) + y * b + a * b; } return f_helper(1 + x * y, 1 - y); }

Of course, we could use a
lambda
expression to specify an anonymous
function for binding our local names.
The body of
`f` then becomes a single call to that
function:

function f(x,y) { return ( (a,b) => x * square(a) + y * b + a * b )(1 + x * y, 1 - y); }

A more convenient way to declare local names is by using constant
declarations within the body of the function. Using
`const`, the function
`f` can be written as

function f(x, y) { const a = 1 + x * y; const b = 1 - y; return x * square(a) + y * b + a * b; }

function expmod(base, exp, m) { return exp === 0 ? 1 : is_even(exp) ? expmod(base, exp / 2, m) * expmod(base, exp / 2, m) % m : base * expmod(base, exp - 1, m) % m; }

expmod(base, exp / 2, m)

function expmod(base, exp, m) { const to_half = expmod(base, exp / 2, m); return exp === 0 ? 1 : is_even(exp) ? to_half * to_half % m : base * expmod(base, exp - 1, m) % m; }

function expmod(base, exp, m) { if (exp === 0) { return 1; } else { if (is_even(exp)) { const to_half = expmod(base, exp / 2, m); return to_half * to_half % m; } else { return base * expmod(base, exp - 1, m) % m; } } }

function f(g) { return g(2); }

f(square);

f(z => z * (z + 1));

[1]
If there is only one parameter, then the
parentheses around the parameter list can be omitted. In
section 2.2.4, we will extend the syntax of
lambda expressions to allow blocks as bodies, as in function declaration
statements.

[2]
It would be clearer and less intimidating to
people learning
JavaScript
if a
term
more obvious than
lambda expression, such as *function definition*
were used. But the convention is
very firmly entrenched, not just for Lisp and Scheme but also for
JavaScript, Java and other languages, no doubt partly due to the
influence of the Scheme editions of this textbook.
The notation is adopted from the
$\lambda$ calculus, a
mathematical formalism introduced by the mathematical logician Alonzo
Church (1941). Church developed the $\lambda$
calculus to provide a rigorous foundation for studying the notions of
function and function application. The $\lambda$
calculus has become a basic tool for mathematical investigations of the
semantics of programming languages.
Note that the JavaScript parser requires parentheses around the lambda
expression in this case.

[3]
Note that a name declared in a function using
`const` cannot be used before the
declaration fully is evaluated, not even in the right-hand expression
of the declaration itself, and regardless whether the same name is
declared outside of the function. Thus the program
leads to an error, because the `x` in
`x + 1` is used before its declaration
is fully evaluated. The `const`
declaration makes sure that the declared name is not used before the
evaluation of the declaration is complete. We will return to this issue in
section 4.1.6, after we learn
more about evaluation.

function h() { const x = 1; function i() { const x = x + 1; return x; } return i(); } h();

1.3.2 Constructing Functions using Lambda Expressions