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