Programmer guide

This file is for programmers who are reading the Num source code or writing Num functions.

Introduction

A typical awk function looks like this:

function sum(num,  i, x) {
    for (i in num) x += num[i]
    return x
}

A num function is similar, plus has parameters for numbers metadata, and arbitrary options, and a function name:

function sum(num, num_  options,  f, i, x) {  # The num_ underscore array is metadata
    f = "sum"                                 # The function name is the metadata key
    if (!(f in num_)) {                       # Check the metadata cache
        for (i in num) x += num[i]            # Calculate as usual
        num_[f] = x                           # Set the metadata cache
    }
    return num_[f]
}

Each num function also has a corresponding metadata function, that defines help, also-known-as synonyms, and possibly more in the future.

function sum_(  f)
    f = "sum"
    function_[f,"help"] = "Sum all the values."
    function_[f,"aka"] = "total"
}

A metadata varaible always ends with an underscore. This helps us keep track.

Metadata Optimization

A num function may be able to use metadata optimization.

For example, if the min function knows that the numbers are sorted ascending or sorted desending, then the min function can immediately return the first or last item, rather than doing a full array scan.

Example:

function min(num, num_,  options,  f, x, i) {
    f = "min"
    if (!(f in num_)) {
        if (num_["ascending"])
            num_[f] = first(num)
        else if (num_["descending"])
            num_[f] = last(num)
        else {
            for (i in num) if (x == "" || num[i] < x) x = num[i]
            num_[f] = x
        }
    }
    return num_[f]
}

Some of the metadata keys that we're aiming to use:

Function conventions

The project uses these function conventions:

Coding conventions

The project uses these coding conventions:

Rule out for now:

Testing

To run Num for testing and debugging, you can try using gawk with flags:

AWK="gawk --posix --lint" num ...

Building

Num is provided two ways:

There is a one-step build process that makes the multiple files into one file:

cd implementations/num-awk
awk '/^## /{next}; /^#@include/{next}; /^@include ".*"/{ gsub(/"/,""); path = "src/" $2; print ""; while ((getline line < path) > 0) { print line } close(path); next}{print}' src/num.sh > num

The build command does this: