Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Grammar

KRL supports functions as first-class objects. KRL supports only anonymous functions, but they can be given names by binding them to a variable in a declaration. Here's an example:

Code Block
languagejavascript
themeConfluencelanguagejavascript
add5 = function(x) {
         x + 5
       };

...

Functions are statically executed (i.e., free variables are bound in the environment in which they are defined, not the environment in which they are executed) and can be recursive. KRE limits the number of times a function can be called in any given ruleset evaluation to protect against runaway code. The value of the recursion threshold is installation specific. Here's an example of a recursive function in KRL:

Code Block
languagejavascript
themeConfluencelanguagejavascript
fact = function(n) {
         (n <= 0) => 1
                   | n * fact(n-1)
       }

This example also shows the syntax for function application (e.g., fact(n-1)). An expression resulting in a function is followed by a possibly empty, parentheses-delimited, comma-separated list of expressions. Function application is applicative-order; the expressions representing the function and the arguments are evaluated and the result of executing the function expression (the operator, or rator) is then applied to the results of the evaluation of the arguments (the operands, or rands). Obviously, the rator operator must be a function.

To see how declarations appear in the body of a function, consider the following example, which uses Newton's method to calculate square roots (Adapted from section 1.1.8 of Structure and Interpretation of Computer Programs.):

Code Block
language
languagejavascript
themeConfluencejavascript
sqrt = function(x) {
  average = function(x,y) { (x + y) / 2 };
  good_enough = function(guess, x) {
                  v = (guess * guess) - x;
                  v < 0.01 && v > -0.01
                };
  improve = function(guess, x) {
              average(guess, (x / guess))
            };
  sqrt_iter = function(guess, x) {
                good_enough(guess, x) => guess
                                       | sqrt_iter(improve(guess,x), x)
              };
  sqrt_iter(1.0, x)
}

Functions can return functions as values and functions can be passed as the arguments to other functions and operators in KRL. The following example defines a generalized summation function called sum that sums the numbers from a to b, incrementing using the function inc and applying the function f to each term:

Code Block
languagejavascript
themeConfluencelanguagejavascript
sum = function(f, a, inc, b) {
  (a > b) => 0
           | f(a) + sum(f, inc(a), inc, b)
};

You can use sum to define a function that sums the cubes from a to b:

Code Block
language
languagejavascript
themeConfluencejavascript
plus1 = function(x) { x + 1 }; 
cube = function(x) { x * x * x }; 
sum_cubes = function(a, b) { sum(cube, a, plus1, b) }

As another example, you can define a function that creates incrementor functions. When given a number, it returns a function that increments by that value:

Code Block
languagejavascript
themeConfluencelanguagejavascript
inc_gen = function(x) { function{ x + n } };

Now you use inc_gen to generate other functions:

Code Block
languagejavascript
themeConfluencelanguagejavascript
plus1 = inc_gen(1);
plus25 = inc_gen(25);

...