Chapter 12. Example Programs in GEL

Here is a function that calculates factorials:

function f(x) = if x <= 1 then 1 else (f(x-1)*x)

With indentation it becomes:

function f(x) = (
  if x <= 1 then
    1
  else
    (f(x-1)*x)
)

This is a direct port of the factorial function from the bc manpage. The syntax seems similar to bc, but different in that in GEL, the last expression is the one that is returned. Using the return function instead, it would be:

function f(x) = (
  if (x <= 1) then return (1);
  return (f(x-1) * x)
)

By far the easiest way to define a factorial function would be using the product loop as follows. This is not only the shortest and fastest, but also probably the most readable version.

function f(x) = prod k=1 to x do k

Here is a larger example, this basically redefines the internal ref function to calculate the row echelon form of a matrix. The function ref is built in and much faster, but this example demonstrates some of the more complex features of GEL.

# Calculate the row-echelon form of a matrix
function MyOwnREF(m) = (
  if not IsMatrix(m) or not IsValueOnly(m) then
    (error("MyOwnREF: argument not a value only matrix");bailout);
  s := min(rows(m), columns(m));
  i := 1;
  d := 1;
  while d <= s and i <= columns(m) do (

    # This just makes the anchor element non-zero if at
    # all possible
    if m@(d,i) == 0 then (
      j := d+1;
      while j <= rows(m) do (
        if m@(j,i) == 0 then
          (j=j+1;continue);
        a := m@(j,);
        m@(j,) := m@(d,);
        m@(d,) := a;
        j := j+1;
        break
      )
    );
    if m@(d,i) == 0 then
      (i:=i+1;continue);
    
    # Here comes the actual zeroing of all but the anchor
    # element rows
    j := d+1;
    while j <= rows(m)) do (
      if m@(j,i) != 0 then (
        m@(j,) := m@(j,)-(m@(j,i)/m@(d,i))*m@(d,)
      );
      j := j+1
    );
    m@(d,) := m@(d,) * (1/m@(d,i));
    d := d+1;
    i := i+1
  );
  m
)