Standard Library

These are the functions defined in std, the standard library available upon first running Fexl.

Note that I do not yet have descriptions for all of them, but I'm working on it.

put

Print to standard output without a trailing newline.
put "Hello"
put (* 3 4)
put ["x = "(* 3 4)" y = "(+ 47 56)]

nl

Print a newline to standard output.
nl

say

Print to standard output with a trailing newline.
say "Hello."

fput

Print to a file handle without a trailing newline.
\fh=(fopen "result" "w")
fput fh ["x = "(* 3 4)" y = "(+ 47 56)]

fnl

Print a newline to a file handle.
fnl fh

fsay

Print to a file handle with a trailing newline.

fflush

Flush any pending output on a file handle.
fflush fh

+

(+ x y) is the sum of x and y.

-

(- x y) is x minus y.

*

(* x y) is the product of x and y.

/

(/ x y) is x divided by y.

^

(^ x y) is x raised to the power of y.

xor

(xor x y) is the bitwise exclusive-or of x and y, where x and y are cast as long integer values.

round

(round x) is x rounded to the nearest integer.

ceil

(ceil x) is the smallest integer value not less than x.

trunc

(trunc x) is the integer part of x, with the fractional part dropped.

abs

(abs x) is the absolute value of x.

sqrt

(sqrt x) is the square root of x.

exp

(exp x) is e raised to the power of x.

log

(log x) is the natural logarithm of x (base e).

sin

(sin x) is the trigonometric sine of x.

cos

(cos x) is the cosine of x.

pi

pi is the numeric constant π.

lt

(lt x y) is true if x is less than y. The arguments must be both numbers or both strings.

le

(le x y) is true if x is less than or equal to y.

eq

(eq x y) is true if x is equal to y.

ne

(ne x y) is true if x is not equal to y.

ge

(ge x y) is true if x is greater than or equal to y.

gt

(gt x y) is true if x is greater than y.

I

The identity function. (I x) = x.

T

The boolean value true. (T x y) = x.

F

The boolean value false. (F x y) = y.

@

The fixpoint function, used for looping/recursion. It is defined to satisfy this equivalence:
(@ f) = (f (@ f))
Amazingly, even the fixpoint function can be defined in ordinary lambda calculus as:
\@=(\\f \\Q=(\x f (x x)) Q Q)

void

(void x) = void. This is the value returned by various functions when they cannot return a sensible result because their arguments are of the wrong type or otherwise erroneous.

cons

(cons x xs) is the list consisting of the element x followed by the list xs. It is equivalent to the expression [x;xs].

null

null is the empty list. It is equivalent to the expression [].

eval

(eval x f) = (f y), where y is the value of x. This is used to force the evaluation of x before proceeding. Ordinarily you can avoid the explicit use of eval by using the = syntax, because eval <i>A</i> (\x <i>B</i>) is equivalent to \x=<i>A</i> <i>B</i> .

yield

(yield x f) = (f x) Used for returning an unevaluated function.

is_defined

(is_defined x) is true if x is not void. Does not evaluate x.

is_undef

(is_undef x) is true if x is void. Does not evaluate x.

is_void

(is_void x) is true if the value of x is void.

is_good

(is_good x) is true if the value of x is not void.

is_bool

(is_bool x) is true if the value of x is boolean, either T or F.

is_list

(is_list x) is true if the value of x is a list, either null or (cons A B)

.

(. x y) is the concatenation of strings x and y.

length

(length x) is the length of string x.

slice

(slice str pos len) is the substring of str starting at position pos and proceeding for len characters. Positions start at zero. It clips as necessary to stay within the bounds of str. Returns void if pos or len is negative.

search

(search haystack needle offset) searches the string haystack for the first occurrence of the string needle, starting at the position offset. Returns the position of the first occurrence of needle, or void if not found.

str_num

(str_num x) converts the string x to a number, or void if the string is malformed.

ord

(ord x) is the ordinal number of the first ASCII character of string x.

chr

(chr x) is the ASCII character whose ordinal number is x.

char_width

(char_width str pos) is the width of the UTF-8 character which starts at the given position within the string.

dirname

(dirname x) strips the last component from file name x. See dirname(1).

basename

(basename x) strips the directory from file name x. See basename(1).

length_common

(length_common x y) Return the number of initial bytes which x and y have in common.

is_str

(is_str x) is true if x is a string.

with

(with key val obj) Returns a function like obj but with key defined as val. Equivalent to:
\with=
    (\key\val\obj
    \obj=obj
    \x
    eq x key val;
    obj x
    )

However, I have optimized this in C code so that it looks up the keys very quickly in a directly linked list. The "with" function is commonly used in "object-oriented functional programming."

fetch

(fetch v k x) This is used for memoized functions. Return the value at key k in index v. If no value found, store the value of x in the index so you get the same value next time. Equivalent to:
\fetch=
    (\v\k\x
    \y=(var_get v k)
    is_defined y y;
    \x=x
    var_put v (with k x; var_get v)
    x
    )

You normally don't call fetch directly, but instead call remember or cache which in turn call fetch.

num_str

(num_str x) converts the number x to a string.

is_num

(is_num x) is true if x is a number.

is_tuple

(is_tuple x) is true if x is a tuple. For example:
(is_tuple {}) = T
(is_tuple {"a"}) = T
(is_tuple {"a" 3.2}) = T
(is_tuple "a") = F

tuple_to_list

Convert a tuple to a list. Examples:
(tuple_to_list {}) ==  []
(tuple_to_list {"a" "b" "c"}) ==  ["a" "b" "c"]

list_to_tuple

Convert a list to a tuple. Examples:
(list_to_tuple []) ==  {}
(list_to_tuple ["a" "b" "c"]) ==  {"a" "b" "c"}

stdin

stdin is the standard input of the current process.

stdout

stdout is the standard output of the current process.

stderr

stderr is the standard error of the current process.

fopen

(fopen path mode) opens a file and returns fh, where fh is the open file handle, or void on failure.

fclose

(fclose fh) closes the file handle fh, and also sets fh to void so it doesn't core dump if you mistakenly try to close it again.

fgetc

(fgetc fh) returns the next single byte from the file, or void if none.

fget

(fget fh) returns the next UTF-8 character from the file, or void if none.

flook

(flook fh) returns the next byte from the file without consuming it.

remove

(remove path) remove path from the file system; return 0 if successful or -1 otherwise.

is_newer

(is_newer file1 file2 returns true if file1 is newer than file2. If either file is missing, it returns true, which makes the most sense for caching operations.

It currently uses resolution only down to the whole second. I could potentially use nanosecond resolution, but that feature is not available on some older machines I use.

is_file

(is_file path) returns true if path is a regular file. See stat(2).

is_dir

(is_dir path) returns true if path is a directory. See stat(2).

flock_ex

(flock_ex fh) obtains an exclusive lock on the file handle, blocking as long as necessary.

flock_sh

(flock_sh fh) obtains a shared lock on the file handle, blocking as long as necessary.

flock_un

(flock_un fh) releases any locks on the file handle.

readlink

(readlink file) calls readlink on the file name. See readlink(2).

mkdir

(mkdir path mode) Attempt to create a directory named path. See mkdir(2). Example:
\code=(mkdir "docs" (oct "775"))

rmdir

(rmdir path) Attempt to delete the directory named path. See rmdir(2). Example:
\code=(rmdir "docs")

ftruncate

fseek_set

fseek_cur

fseek_end

ftell

fread

mkfile

dir_names

mod_time

file_size

symlink

rename

time

localtime

gmtime

timelocal

timegm

microtime

die

die exits immediately with exit code 1.

argv

(argv n) returns the command line argument at position n, starting at 0. Returns void if n is less than 0 or greater than or equal to argc (the argument count).

sleep

(sleep n) Sleep for n seconds.

usleep

(usleep n) Sleep for n microseconds.

run_process

spawn

exec

fexl_benchmark

seed_rand

(seed_rand x) seeds the pseudo-random number generator with a number x between 0 and 1. It multiplies x by RAND_MAX and calls srand(3).

rand

rand returns a pseudo-random number in the range 0 through 1. It calls rand(3) and divides by RAND_MAX. Note that these numbers are not cryptographically strong.

parse

(parse source label) parse the source, using the given label for any syntax error messages, and return the resulting form. The source may be a file handle, a string, or an istr (string iterator).

use_file

(use_file name) parse the named file and return the resulting form.

is_closed

(is_closed form) Return true if the form has no undefined symbols.

def

(def key val form) Define key as val in a form. Example:
value;
std;
def "fred" (say "I am Fred.");
def "wilma" (say "I am Wilma.");
\;
say "Meet the Flintstones."
fred wilma

std

This is the standard context which defines all the symbols described here.

value

(value form) Evaluate the form if all symbols are defined, otherwise report the undefined symbols and die.

resolve

(resolve form) Like value, except it yields the form value to the caller without evaluating it. Example:
resolve (std \; say "hello") \hello
hello
hello

buf_new

buf_new returns a new empty character buffer. Example:
\buf=buf_new

buf_put

(buf_put buf str) appends the string to the buffer.
buf_put buf "abcdef"

buf_get

(buf_get buf) clear the buffer and return str, where str is the current content of the buffer.
\str=(buf_get buf)

readstr

sgetc

sget

slook

var_new

Return a new mutable variable. Example:
\v=var_new

Mutable variables should be used sparingly. I tend to use them only for (1) memoized functions (see "remember"), and (2) simulating mutable data stores such as a database, file system, or remote API. Aside from very well defined scenarios like that, you are advised not to use variables. Fexl is a functional programming language and you should learn the ways of functions.

Using a variable, you can deliberately create a circular structure in memory which is not reclaimed by the reference counting mechanism. Unless you explicitly clear the top variable by setting it to void for example, you will see a "LEAK" error message when your program terminates. This is the only way Fexl can ever produce a memory leak, and it will be all your fault. Needless to say, none of this is recommended and it is highly dubious that creating a circular structure is ever useful.

var_get

(var_get v) Return the current value of variable v.

var_put

(var_put v x) Set the current value of variable v to x.

is_var

(is_var x) is true if x is a var.

limit_time

(limit_time N) Set the CPU time limit in seconds. Calls setrlimit(2) with RLIMIT_CPU.

limit_memory

(limit_memory N) Set the maximum size of the process' virtual memory (address space) in bytes. Calls setrlimit(2) with RLIMIT_AS.

limit_stack

(limit_stack N) Set the maximum size of the process stack in bytes. Calls setrlimit(2) with RLIMIT_STACK.

unpack

(unpack str) Unpack raw bytes into hexadecimal format.

pack

(pack str) Pack hexadecimal format into raw bytes.

random_bytes

(random_bytes n) Returns a string of n random bytes read from /dev/urandom.

random_nonce

random_nonce is equivalent to (random_bytes 24). Used in conjunction with the nacl crypto functions.

random_secret_key

random_secret_key is equivalent to (random_bytes 32). Used in conjunction with the nacl crypto functions.

nacl_box_public

nacl_box_prepare

nacl_box_seal

nacl_box_open

nacl_sign_public

nacl_sign_open

sha256

(sha256 str) Compute the SHA-256 hash of the string.

sha512

(sha512 str) Compute the SHA-512 hash of the string.

pack64

(pack64 str) Pack base 64 format string into raw bytes.

unpack64

(unpack64 str) Unpack raw bytes into base 64 format string.

hmac_sha512

hmac_sha256

set_alarm

start_server

kill

connect

receive_keystrokes

defc

if

(if x y) is y if the condition x is true, otherwise I (the identity function). It is used to evaluate y for its side-effects if the condition is true, otherwise do nothing and proceed. It is defined as:
\if=(\x\y x y I)

::

use

check

default

path_under

dir_base

dir_local

trace

error

TAB

NL

CR

LF

QU

remember

cache

do_benchmark

show_benchmark

and

(and x y) is the logical and (conjunction) of boolean values x and y.

not

(not x) is the logical negation of the boolean value x.

or

(or x y) is the logical or (disjunction) of boolean values x and y.

neg

(neg x) is the negative of number x.

max

(max x y) is the maximum of numbers x and y.

min

(min x y) is the minimum of numbers x and y.

mod

(mod x n) is x modulo n. It is defined as:
\mod=(\x\n - x; * n; trunc; / x n)

tau

tau is the numeric constant 2*π.

round2

(round2 x) is x rounded to two decimal places.

append

(append x y) is the list consisting of the elements of list x followed by the elements of list y.

flatten

(flatten xs) Flatten a nested list into a list of scalars. Example:
(flatten ["abc" ["de" [T F] 3.2 [] []] "fg"]) == ["abc" "de" T F 3.2 "fg"]

each

map

map_good

filter

reverse

(reverse x) is the list consisting of the elements of list x in reverse order.

append_all

(append_all xs) Flatten a list of lists together. Example:
(append_all [["a" "b"] [] ["c" ["d" "e"] "f"] ["g"]]) ==
["a" "b" "c" ["d" "e"] "f" "g"]

shift

(shift xs) Return the head and tail of list xs to the caller. If the list is null, return void and null. It is defined as:
\shift=(\xs xs {void []} \x\xs {x xs})
Example:
\xs=["a" "b" "c"]
shift xs \x\xt

say ["xs = "(as_str xs)]
say ["x  = "(as_str x)]
say ["xt = "(as_str xt)]
That prints:
xs = ["a" "b" "c"]
x  = "a"
xt = ["b" "c"]
If you set \xs=[] in that example, the result would be:
xs = []
x  = void
xt = []
Note that you can do the same sort of thing by just using the list xs as a function, passing in handlers for the null and non-null case:
xs (say "It's null") \x\xt
say ["xs = "(as_str xs)]
say ["x  = "(as_str x)]
say ["xt = "(as_str xt)]
However, shift makes it so you don't have to handle the null case explicitly, instead simply returning void as the head of the list.

combine_keys

merge_keys

group_items

get_keys

get_values

sort_all

(sort_all extract xs) Sort all items in list xs with the given key extraction function. This uses a merge sort which gives good performance even in special cases where the keys are already sorted.

Example:

\xs=
(
sort_all
(\row row \key\val key)
[
{"b" 2}
{"d" 4}
{"b" 2.2}
{"a" 1}
{"c" 3}
]
)

say_data xs
The output is:
[
{"a" 1}
{"b" 2}
{"b" 2.2}
{"c" 3}
{"d" 4}
]

sort_unique

(sort_unique extract xs) Same as sort_all except that it keeps only unique items.

Example:

\xs=
(
sort_unique
(\row row \key\val key)
[
{"b" 2}
{"d" 4}
{"b" 2.2}
{"a" 1}
{"c" 3}
]
)

say_data xs
The output is:
[
{"a" 1}
{"b" 2}
{"c" 3}
{"d" 4}
]

sort

(sort xs) Sort a simple list whose elements are all either strings or numbers. Defined as:
\sort=(sort_all I)

unique

(unique xs) Uniquely sort a simple list whose elements are all either strings or numbers. Defined as:
\unique=(sort_unique I)

fold

(fold f z xs) Using function f and starting value z, run the function forward for each element in the list. Defined as:
\fold=
    (\f @\\loop \z\xs
    xs z \x
    \z=(f z x)
    loop z
    )
Example:
\x=(fold + 0 [1 2 3 4])
say x
The output is:
10

first

drop

list_sum

(list_sum xs) Return the sum of a list of numbers. Defined as:
\list_sum=(fold + 0)

list_length

(list_length xs) Return the length of an arbitrary list.

is_null

(is_null xs) Return true if the list is null (empty). Defined as:
\is_null=(\xs xs T \_\_ F)

range

(range x y) Produce the list of numbers in the range x through y. Works either forward or backward. Example:
say_data (range 10 14)
say_data (range 14 10)
The output is:
[10 11 12 13 14]
[14 13 12 11 10]

list_at

(list_at xs n) Return the item at position n in list xs, counting from 0.

list_combine

(list_combine f xs ys) Combine the elements of two lists pairwise, using function f to combine the respective elements.

column

(column n xs) Get the nth column of a table, numbered from 0. Defined as:
\column=(\n map (\row list_at row n))
Example:
\table=
[
[1 2 3 4]
[5 6 7 8]
[9 10 11 12]
[13 14 15 16]
]

\xs=(column 2 table)
say_data xs
Output:
[3 7 11 15]

match_column

stream_values

get_list

to_str

(to_str x) Flatten a piece of data (string, number, boolean, or list) into a string. Works on arbitrarily nested lists. Example:
(to_str ["abc" ["de" T F 3.2] "fg"]) == "abcdeTF3.2fg"

get_str

list_str

str_bytes

str_chars

str_map

join

join_path

split

file_bytes

file_content

starts_with

ends_with

map_bytes_to_double

random_double

eq_data

repeat_str

format_num

format_money

fexl_quote

uc

(uc x) is string x converted to all upper-case.

lc

(lc x) is string x converted to all lower-case.

render_data

put_data

fput_data

as_str

str_to_data

count_match

str_trim

trim_spaces

trim_beg_spaces

trim_end_spaces

i_render_data

say_data

fsay_data

trace_data

i_as_str

:

Synonym for get_key

get_key

(get_key key xs) Get the value associated with key in a list of pairs xs. Return void if not found. Example:
(get_key "b" [{"a" 1} {"c" 3} {"b" 2} {"d" 4}]) == 2

del_key

put_key

(put_key key val xs) Associate key with val in a list of pairs xs. Example:
\xs1=[{"a" 1} {"c" 3} {"b" 2} {"d" 4}]
\xs2=(put_key "b" 2.1 xs1)

say ["xs1 = "(as_str xs1)]
say ["xs2 = "(as_str xs2)]
The output is:
xs1 = [{"a" 1} {"c" 3} {"b" 2} {"d" 4}]
xs2 = [{"a" 1} {"c" 3} {"b" 2.1} {"d" 4}]

push_key

update_key

add_key

update_values

sort_pairs

(sort_pairs xs) Special case of sort_all for a list of pairs. Defined as:
\sort_pairs=(sort_all (\p p \k\_ k))

put_default

name_columns

make_assoc

hex_digit

hex_byte

hex_digit_to_dec

xor_hex

oct

(oct x) Convert octal string to a number.

hex

(hex x) Convert hexadecimal string to a number.

quote_ch

quote

colgroup

_tag

tag

tr

put_quote_data

uri_escape

uri_unescape

make_url

split_microtime

subtract_microtime

show_microtime

trace_elapsed

long_month_names

short_month_names

long_month_name

short_month_name

date_year

date_month

date_ymd

split_date

date_normal

date_quarter

month_ym

ym_month

ymd_date

month_before

month_after

ym_num_days

fill_day

day_after

date_end_prev_month

date_end_prev_quarter

date_end_prev_year

same_quarter

year_num_days

day_in_year

count_days

day_of_week

add_days

add_year

run_function

run_program

run_function_filter

run_filter

grab_output

stop_server

run_server

read_csv_string

read_csv_chars

read_csv_file

read_ssv_string

read_ssv_chars

read_ssv_file