Lua Standard Library

The tables and functions documented in here should be considered an extension to the standard Lua library, in some cases replacing those implementations with better or more flexible implementations. As such they adhere to the normal Lua naming conventions.

The Lua standard library isn't automatically imported at program startup time any longer, so if you want to use these facilities you'll need to import them. You can either use:

require "std"

to get them all or import the individual modules as needed after loading support for the new std.import module via:

require "std.import"

You must require at least one of these modules or the other standard library modules will fail to load due to the missing import function.

Unfortunately the implementation of require in Strata Design 3D CX version 6.0 and 6.0.1 is broken for file names with dot '.' separators, so the Lua standard library isn't usable until later. Once that's fixed we'll move the following text between double dividers into the reference documentation home page.

Another open source effort which has been integrated into the Strata implementation of the Lua language. Most of its functionality is available immediately at application launch time.

Although there really isn't a Lua standard library per se, this early effort has some nice elements.

Assertions and Warnings

import "std.assert"

assert (v, ...)

Extend to allow formatted arguments

v: value

...: arguments for format

returns

v: value

warn (...)

Give warning with the name of program and file (if any)

...: arguments for format

die (...)

Die with error

...: arguments for format

Base

import "std.base"

metamethod (x, n)

Return given metamethod, if any, or nil

x: object to get metamethod of

n: name of metamethod to get

returns

m: metamethod function or nil if no metamethod or not a function

print (arg)

Make print use tostring, so that improvements to tostring are picked up.

arg: objects to print

tostring (x)

Extend tostring to work better on tables

x: object to convert to string

returns

s: string representation

totable (x)

Turn an object into a table according to __totable metamethod.

x: object to turn into a table

returns

t: table or nil

pickle (x)

Convert a value to a string. The string can be passed to dostring to retrieve the value. Does not work for recursive tables.

x: object to pickle

returns

s: string such that eval (s) is the same value as x

id (...)

Identity, returns exactly what was passed.

...: the arguments to be returned

returns

...: the arguments passed to the function

pack (...)

Turn a tuple into a list

...: tuple

returns

l: list

bind (f, a1 ... an)

Partially apply a function

f: function to apply partially

a1 ... an: arguments to bind

returns

g: function with ai already bound

curry (f, n)

Curry a function

f: function to curry

n: number of arguments

returns

g: curried version of f

compose (f1 ... fn)

Compose functions

f1 ... fn: functions to compose

returns

g: composition of f1 ... fn

With each function taking as an argument the result of the next function,

and with fn taking the arguments passed to the result g

args: arguments

returns

f1 (... fn (args) ...)

eval (s)

Evaluate a string

s: string

returns

v: value of string

listable (f)

Make a function which can take its arguments as a list.

f: function (if it only takes one argument, it must not be a table)

returns

g: function that can take its arguments either as normal or in a list

pathSubscript (t, s)

Subscript a table with a string containing dots.

t: table

s: subscript of the form s1.s2. ... .sn

returns

v: t.s1.s2. ... .sn

lookup (t, l)

Do a late-bound table lookup

t: table to look up in

l: list of indices {l1 ... ln}

returns

u: t[l1] ... [ln]

Bitwise Logic

import "std.bit"

bit.even (n)

Returns true if n is even, false otherwise

n: an integer value

returns

r: the boolean result

bit.odd (n)

Returns true if n is odd, false otherwise

n: an integer value

returns

r: the boolean result

bit.bnot (n)

Computes the bit-wise "not" of n

n: an integer value

returns

r: the integer result

bit.band (n1 ... nn)

Computes the bit-wise "and" of all the integer parameters

n1 ... nn: integer values

returns

r: the integer result

bit.bor (n1 ... nn)

Computes the bit-wise "or" of all the integer parameters

n1 ... nn: integer values

returns

r: the integer result

bit.bxor (n1 ... nn)

Computes the bit-wise "xor" of all the integer parameters

n1 ... nn: integer values

returns

r: the integer result

bit.lshift (n, m)

Computes the left shifted integer value n by m places

n: the integer value to left shift

m: the number of bit positions to shift over

returns

r: the integer result

bit.rshift (n, m)

Computes the right shifted integer value n by m places

n: the integer value to right shift

m: the number of bit positions to shift over

returns

r: the integer result

bit.arshift (n, m)

Computes the arithmetic right shifted integer value n by m places

n: the integer value to arithmetically right shift

m: the number of bit positions to shift over

returns

r: the integer result

bit.mod (n, m)

Computes the modulo remainder of the integer value n divided by m

n: the integer value numerator

m: the integer value denominator

returns

r: the integer result

Debugging

import "std.debug"

debug.say ([n], ...)

Print a debugging message

[n]: debugging level [1]

...: objects to print (as for print)

debug.traceCall (event)

Trace function calls

event: event causing the call

Use debug.sethook (debug.traceCall, "cr") before a function call to trace the execution of that call.

The debug table also has a metatable entry __call set to debug.say so that calling debug() is the same as calling debug.say()

Files

import "std.io"

or

import "std.io.file"

io.length (f)

Find the length of a file

f: file name

returns

len: length of file

io.exists (f)

Finds whether a file exists

f: file name

returns

r: non-nil if f exists, nil otherwise

Input/Output

import "std.io"

or

import "std.io.io"

io.readLines ([h])

Read a file into a list of lines and close it

[h]: file handle or name [io.input ()]

returns

l: list of lines

io.writeLine ([h], ...)

Write values adding a newline after each line

[h]: file handle [io.output ()]

...: values to write (as for write)

io.changeSuffix (from, to, name)

Change the suffix of a filename

from: suffix to change (".-" for any suffix)

to: suffix to replace with

name: file name to change

returns

name_: file name with new suffix

io.addSuffix (suff, name)

Add a suffix to a filename if not already present

suff: suffix to add

name: file name to change

returns

name_: file name with new suffix

LCS Algorithm

After pseudo-code in http://www.ics.uci.edu/~eppstein/161/960229.html Lecture notes by David Eppstein, eppstein@ics.uci.edu

The interface provided by this module is a little unwieldy at first glance, but is quite easy to use: the best way is probably to define a wrapper for lcs.longestCommonSubseq for each type on which you wish to use it.

I used function parameters rather than metamethods because strings don't have metamethods and there is no standard length metamethod.

import "std.algorithm"

or

import "std.algorithm.lcs"

lcs.commonSubseqs (a, b, sub, len)

find common subsequences

a, b: two sequences of type T

sub (s, i):

subscription operator on T

s: a sequence of type T

i: a number

returns

e: the ith element of s

len (s):

length operator on T

s: a sequence of type T

returns

l: the length of s

returns

l_: list of common subsequences

m: the length of a

n: the length of b

lcs.longestCommonSubseq (a, b, sub, len, concat, s)

find the LCS of two sequences

a, b: two sequences of some type T

sub (s, i):

subscription operator on T

s: a sequence of type T

i: a number

returns

e: the ith element of s

len (s):

length operator on T

s: a sequence of type T

returns

l: the length of s

concat (s, t):

concatenation operator on T

s, t: two sequences of type T

returns

u: t appended to s

s: an empty sequence of type T

returns

s_: the LCS of a and b

Lists

import "std.list"

list.cons (x, l)

Prepend an item to a list

x: item

l: list

returns

r: {x, unpack (l)}

list.append (x, l)

Append an item to a list

x: item

l: list

returns

r: {unpack (l), x}

list.map (f, l)

Map a function over a list

f: function

l: list

returns

m: result list {f (l[1]) ... f (l[table.getn (l)])}

list.mapWith (f, ls)

Map a function over a list of lists

f: function

ls: list of lists

returns

m: result list {f (unpack (ls[1]))) ... f (unpack (ls[table.getn (ls)]))}

list.filter (p, l)

Filter a list according to a predicate

p (a):

Predicate function

a: argument

returns

f: flag

l: list

returns

m: result list containing elements e of l for which p (e) is true

list.slice (l, [from], [to])

Slice a list

l: list

[from], [to]: start and end of slice from defaults to 1 and to to table.getn (l); negative values count from the end

returns

m: {l[from] ... l[to]}

list.tail (l)

Return a list with its first element removed

l: list

returns

m: {l[2] ... l[table.getn (l)]}

list.foldl (f, e, l)

Fold a binary function through a list left associatively

f: function

e: element to place in left-most position

l: list

returns

r: result

list.foldr (f, e, l)

Fold a binary function through a list right associatively

f: function

e: element to place in right-most position

l: list

returns

r: result

list.concat (l1, l2, ... ln)

Concatenate lists

l1, l2, ... ln: lists

returns

r: result {l1[1] ... l1[table.getn (l1)], ... , ln[1] ... ln[table.getn (ln)]}

list.reverse (l)

Reverse a list

l: list

returns

m: list {l[table.getn (l)] ... l[1]}

list.transpose (ls)

Transpose a list of lists

ls: {{l11 ... l1c} ... {lr1 ... lrc}}

returns

ms: {{l11 ... lr1} ... {l1c ... lrc}} Also give aliases list.zip and list.unzip

list.zipWith (f, ls)

Zip lists together with a function

f: function

ls: list of lists

returns

m: {f (ls[1][1] ... ls[table.getn (ls)][1]) ... f (ls[1][N] ... ls[table.getn (ls)][N]) where N = max {list.map (table.getn, ls)}

list.project (f, l)

Project a list of fields from a list of tables

f: field to project

l: list of tables

returns

m: list of f fields

list.enpair (t)

Turn a table into a list of pairs

t: table {i1=v1 ... in=vn}

returns

ls: list {{i1, v1} ... {in, vn}}

list.depair (ls)

Turn a list of pairs into a table

ls: list {{i1, v1} ... {in, vn}}

returns

t: table {i1=v1 ... in=vn}

list.indexKey (f, l)

Make an index of a list of tables on a given field

f: field

l: list of tables {t1 ... tn}

returns

ind: index {t1[f]=1 ... tn[f]=n}

list.indexValue (f, l)

Copy a list of tables, indexed on a given field

f: field whose value should be used as index

l: list of tables {i1=t1 ... in=tn}

returns

m: index {t1[f]=t1 ... tn[f]=tn}

list.lcs (a, b)

Find the longest common subsequence of two lists

a, b: lists

returns

l: LCS of a and b

Math

import "std.math"

math._INTEGER_BITS

Calculated number of bits in an integer

math.max (l or v1 ... vn)

Extend to work on lists

l: list

or

v1 ... vn: values

returns

m: max value

math.min (l or v1 ... vn)

Extend to work on lists

l: list

or

v1 ... vn: values

returns

m: min value

math.floor (n, [p])

Extend to take the number of decimal places

n: number

[p]: number of decimal places to truncate to [0]

returns

r: n truncated to p decimal places

math.round (n, [p])

Round a number to p decimal places

n: number

[p]: number of decimal places to truncate to [0]

returns

r: n to p decimal places

math.sqr (n)

Squares the argument

n: number

returns

r: n * n

Prototype-based Objects

For an alternative object oriented programming model you can use:

import "std.object"

This gives you facilities supporting object orientation via prototyping.

Usage:

An object's metatable is itself. In the initializer, unnamed values are assigned to the fields given by _init (assuming the default _clone). Private fields and methods start with an underscore.

Create an object/class:

object/class = parent {value, ...; field = value ...}

Access an object field:

object.field

Call an object method:

object:method (...)

Call a class method:

class.method (self, ...)

Add a field:

object.field = x

Add a method:

function object:method (...) ... end

Root object:

Object:_clone (values, _init)

Object constructor

values: initial values for fields in

_init

returns

object: new object

Object:__call ()

Sugar instance creation

Sets

import "std.set"

set:add (e)

Add item(s) to a set

self: set

e: element(s)

returns

r: self with elements added

set:remove (e)

Remove item(s) from a set

self: set

e: element(s)

returns

r: self with elements removed

set:member (e)

Test whether an item is in a set

self: set

e: element

returns

r: self with elements of t removed

set:elements (e)

Return all of the set elements as results

self: set

e: element(s)

returns

r: all of the unpacked elements

set:minus (t)

Find the difference of two sets. Also available as infix operator -

self: set

t: set

returns

r: self with elements of t removed

set:intersect (t)

Find the intersection of two sets. Also available as infix operator *

self: set

t: set

returns

r: set intersection of self and t

set:union (t)

Find the union of two sets. Also available as infix operator +

self: set

t: set

returns

r: set union of self and t

set:subset (t)

Find whether one set is a subset of another. Also available as infix operator <=

self: set

t: set

returns

r: true if self is a subset of t, false otherwise

set:propersubset (t)

Find whether one set is a proper subset of another. Also available as infix operator <

self: set

t: set

returns

r: true if s is a proper subset of t, false otherwise

set:equal (t)

Find whether two sets are equal. Also available as infix operator ==

self: set

t: set

returns

r: true if sets are equal, false otherwise

Formatting Text

import "std.string"

or

import "std.string.format"

string.format (f, ...)

Extend to work better with one argument. If only one argument is passed, no formatting is attempted.

f: format

...: arguments to format

returns

s: formatted string

string.pad (s, w, [p])

Justify a string. When the string is longer than w, it is truncated (left or right according to the sign of w)

s: string to justify

w: width to justify to (-ve means right-justify; +ve means left-justify)

[p]: string to pad with [" "]

returns

s_: justified string

string.wrap (s, w, ind, ind1)

Wrap a string into a paragraph

s: string to wrap

w: width to wrap to [78]

ind: indent [0]

ind1: indent of first line [ind]

returns

s_: wrapped paragraph

string.numbertosi (n)

Write a number using SI suffixes. The number is always written to 3 s.f.

n: number

returns

n_: string

Regular Expressions

import "std.string"

or

import "std.string.regex"

string.findl (s, p, [init], [plain])

Do string.find, returning captures as a list

s: target string

p: pattern

[init]: start position [1]

[plain]: inhibit magic characters [nil]

returns

from, to: start and finish of match

capt: table of captures

string.finds (s, p, [init], [plain])

Do multiple string.find's on a string

s: target string

p: pattern

[init]: start position [1]

[plain]: inhibit magic characters [nil]

returns

t: table of {from=from, to=to; capt = {captures}}

string.gsubs (s, sub, [n])

Perform multiple calls to string.gsub

s: string to call string.gsub on

sub: {pattern1=replacement1 ...}

[n]: upper limit on replacements [infinite]

returns

s_: result string

r: number of replacements made

string.split ([sep], s)

Split a string at a given separator

[sep]: separator regex ["%s+"]

s: string to split

returns

l: list of strings

string.ltrim ([r], s)

Remove leading matter from a string

[r]: leading regex ["%s+"]

s: string

returns

s_: string without leading r

string.rtrim ([r], s)

Remove trailing matter from a string

[r]: trailing regex ["%s+"]

s: string

returns

s_: string without trailing r

string.trim ([r], s)

Remove leading and trailing matter from a string.

[r]: leading/trailing regex ["%s+"]

s: string

returns

s_: string without leading/trailing r

Strings

import "std.string"

or

import "std.string.string"

string.concat (s1, s2, ..., sn)

Give a name to .. for strings

s1, s2, ..., sn: strings

returns

s_: s1 .. s2 .. ... .. sn

string.caps (s)

Capitalize each word in a string

s: string

returns

s_: capitalized string

string.chomp (s)

Remove any final newline from a string

s: string to process

returns

s_: processed string

string.escapePattern (s)

Escape a string to be used as a pattern

s: string to process

returns

s_: processed string

string.escapeShell (s)

Escape a string to be used as a shell token. Quotes spaces, parentheses and \\s

s: string to process

returns

s_: processed string

string.ordinalSuffix (n)

Return the English suffix for an ordinal

n: number of the day

returns

s: suffix

string.lcs (a, b)

Find the longest common subsequence of two strings.

a, b: strings

returns

s: longest common subsequence

Tables

import "std.table"

table.sort (t, c)

Make table.sort return its result

t: table

c: comparator function

returns

t: sorted table

table.subscript (t, s)

Expose [] as a function

t: table

s: subscript

returns

v: t[s]

table.empty (t)

Say whether table is empty

t: table

returns

f: true if empty or false otherwise

table.size (t)

Find the number of elements in a table

t: table

returns

n: number of elements in t

table.indices (t)

Make the list of indices of a table

t: table

returns

u: list of indices

table.values (t)

Make the list of values of a table

t: table

returns

u: list of values

table.invert (t)

Invert a table

t: table {i=v ...}

returns

u: inverted table {v=i ...}

table.permute (p, t)

Permute some indices of a table

p: table {oldindex=newindex ...}

t: table to permute

returns

u: permuted table

table.clone (t)

Make a shallow copy of a table, including any metatable.

t: table

returns

u: copy of table

table.merge (t, u)

Merge two tables. If there are duplicate fields, u's will be used. The metatable of the returned table is that of t.

t, u: tables

returns

r: the merged table

table.newDefault (x, [t])

Make a table with a default value

x: default value

[t]: initial table [{}]

returns

u: table for which u[i] is x if u[i] does not exist