Built-in Modules

Maksim I

Built-in Modules

First of all, I will mention it one more time — there is NO module system in Shik. I use the word “modules” to tie different functions together under one specialization, it is just a convention. There is no module file, there are just a bunch of functions with the file. prefix.

All modules are available without imports. Use help module. in the REPL to explore.


number. — Arithmetic & math

FunctionArgsDescription
+a bAddition (also: string concatenation when both strings)
-mod baseSubtraction: base - mod. (- 1) = “subtract 1”
*mod baseMultiplication
/mod baseDivision: base / mod. (/ 2) = “divide by 2”
%mod baseModulo: base % mod
^exp baseExponentiation: base ^ exp. (^ 2) = “square”
number.absnAbsolute value
number.floornRound down
number.ceilnRound up
number.roundnRound to nearest integer
number.sqrtnSquare root
number.sinnSine (radians)
number.cosnCosine (radians)
number.tannTangent (radians)
number.lognNatural logarithm
number.log10nBase-10 logarithm
number.mina bSmaller of two numbers
number.maxa bLarger of two numbers
number.rand[max] or [min max]Random number (0 args: float 0–1; 1 arg: int 0–max; 2 args: int min–max)
- 1 5        ; 4  (5 - 1)
/ 2 10       ; 5  (10 / 2)
^ 3 5        ; 125 (5^3)
[1 2 3 4] $> list.map (* 2)     ; [2 4 6 8]
[1 2 3 4] $> list.map (^ 2)     ; [1 4 9 16]
number.rand 1 7                  ; random integer 1–6

string. — String manipulation

FunctionArgsDescription
stringvalConvert any value to string
string.lensCharacter count
string.uppersConvert to uppercase
string.lowersConvert to lowercase
string.trimsRemove leading and trailing whitespace
string.trim-startsRemove leading whitespace
string.trim-endsRemove trailing whitespace
string.splitsep sSplit s by sep, return list
string.linessSplit into lines (equivalent to string.split "\n")
string.joinsep lstJoin list of strings with sep
string.+a bConcatenate two strings
string.hasneedle haystackTrue if haystack contains needle
string.starts-withprefix sTrue if s starts with prefix
string.ends-withsuffix sTrue if s ends with suffix
string.index-ofneedle haystackIndex of first occurrence, or -1
string.replacefrom to sReplace all occurrences of from with to in s
string.ati sCharacter at index i, or null
string.slicestart end sSubstring from start to end
string.bytesnFormat number of bytes as human-readable (e.g. "1.5 KiB")
string.iteratefn sCall fn for each character (left to right)
string.iterate-backward / string.<iteratefn sCall fn for each character (right to left)
string.push / string.push> / string.push-rights charAppend char to s (mutates s)
string.push-left / string.<pushs charPrepend char to s (mutates s)
string.seti s charReplace character at index i in s with char (mutates)
string.=a bString equality
string.split "," "a,b,c"         ; ["a" "b" "c"]
string.join ", " ["a" "b" "c"]   ; "a, b, c"
string.has :TODO (file.read :main.rs)
"hello" $> string.upper           ; "HELLO"
string.replace "o" "0" "hello"   ; "hell0"

list. — List operations

FunctionArgsDescription
list.lenlstNumber of elements
list.headlstFirst element, or null
list.taillstList without first element (O(1))
list.lastlstLast element, or null
list.initlstList without last element (O(1))
list.ati lstElement at index i, or null
list.empty?lstTrue if list is empty
list.sumlstSum all numbers
list.reverselstReversed list
list.concata bConcatenate two lists
list.taken lstFirst n elements
list.dropn lstAll elements after the first n
list.slicestart end lstSublist from start to end
list.choicelstRandom element, or null
list.range[start] end [step]Create numeric range (see below)
list.mapfn lstApply fn to each element, return new list
list.filterpred lstKeep elements where pred returns true
list.foldinit fn lstReduce list to single value
list.iteratefn lstCall fn for each element (for side effects)
list.iterate-backward / list.<iteratefn lstIterate right to left
list.anypred lstTrue if any element matches pred
list.allpred lstTrue if all elements match pred
list.findpred lstFirst matching element, or null
list.find-indexpred lstIndex of first match, or -1
list.sortcmp lstSort using comparator fn [a b] number (negative = a before b)
list.seti lst valSet element at index i to val (mutates)
list.push / list.push> / list.push-rightlst valAppend val (mutates)
list.push-left / list.<pushlst valPrepend val (mutates)

list.range:

list.range 5        ; [0 1 2 3 4]
list.range 2 5      ; [2 3 4]
list.range 0 10 2   ; [0 2 4 6 8]

list.fold example:

; Sum of squares
list.fold 0 (fn [acc x] + acc (* x x)) [1 2 3 4]   ; 30

; Build a frequency map
list.fold {} (fn [acc item] '(
  let key (string item)
  if (object.has key acc) $
    object.set key acc (+ (object.get key acc) 1) $
    object.set key acc 1
  acc
)) [:a :b :a :c :a :b]
; {:a 3 :b 2 :c 1}

list.sort example:

; Sort numbers ascending
list.sort (fn [a b] - a b) [3 1 4 1 5 9]    ; [1 1 3 4 5 9]

; Sort descending
list.sort (fn [a b] - b a) [3 1 4 1 5 9]    ; [9 5 4 3 1 1]

; Sort pairs by second element
list.sort (fn [[_ a] [_ b]] - a b) [[:x 3] [:y 1] [:z 2]]
; [[:y 1] [:z 2] [:x 3]]

object. — Key-value maps

FunctionArgsDescription
object.getkey objValue for key, or null
object.setkey obj valSet key to val (mutates)
object.haskey objTrue if key exists
object.removekey objRemove key (mutates), returns removed value or null
object.keysobjList of all keys
object.valuesobjList of all values
object.entriesobjList of [key value] pairs
object.lenobjNumber of keys
object.empty?objTrue if no keys
object.mergea bMerge a and b (keys in b override a)
object.cloneobjShallow copy
object.pickkeys objNew object with only the listed keys
object.omitkeys objNew object without the listed keys
object.from-entrieslstCreate object from list of [key value] pairs
object.mapfn objTransform values: fn [key value] → new value
object.map-entriesfn objTransform entries: fn [key value][new-key new-value]
object.filterpred objKeep entries where pred [key value] is true
object.foldinit fn objReduce: fn [acc [key value]]
object.iteratefn objCall fn [key value] for each entry
object.anypred objTrue if any entry matches
object.allpred objTrue if all entries match
object.findpred objFirst matching [key value] pair, or null
object.find-keypred objKey of first matching entry, or null
let config {:host :localhost :port 8080}
object.get :host config          ; "localhost"
object.has :port config          ; true
object.keys config               ; ["host" "port"]

object.fold 0 (fn [acc [_ v]] + acc v) {:a 1 :b 2 :c 3}   ; 6

file. — Filesystem

Reading:

FunctionArgsDescription
file.readpathRead file as string (error on failure)
file.read?pathRead file as string, or null on failure
file.read-linespathRead file as list of lines
file.read-bytespathRead file as list of byte values (0–255)

Writing:

FunctionArgsDescription
file.writepath contentWrite string to file (overwrites)
file.appendpath contentAppend string to file
file.write-bytespath bytesWrite byte list to file

Operations:

FunctionArgsDescription
file.copy / file.cpdst srcCopy file or directory
file.move / file.mvdst srcMove or rename file or directory
file.remove / file.rmpathDelete file or directory recursively
file.rmdirpathRemove empty directory
file.rmdir!pathRemove directory recursively
file.mkdirpathCreate directory
file.mkdir!pathCreate directory and all parent directories
file.symlinklink targetCreate symlink
file.read-linkpathRead symlink target
file.temp-dirReturn system temp directory

Information:

FunctionArgsDescription
file.existspathTrue if path exists
file.is-filepathTrue if path is a file
file.is-dirpathTrue if path is a directory
file.is-symlinkpathTrue if path is a symlink
file.sizepathFile size in bytes
file.size.deeppathTotal size of file or directory (recursive)
file.statpathObject with size, is_file, is_dir, is_symlink, readonly

Listing:

FunctionArgsDescription
file.listpathList directory contents (names only)
file.list!pathList directory contents (full paths)
file.globpatternFind files matching glob pattern (full paths)

path. — Path manipulation

FunctionArgsDescription
path.namepathFile name with extension
path.stempathFile name without extension
path.extpathFile extension
path.parentpathParent directory
path.joinbase componentJoin two path components
path.absolutepathConvert to absolute path
path.name :/home/user/file.txt    ; "file.txt"
path.stem :/home/user/file.txt    ; "file"
path.ext  :/home/user/file.txt    ; "txt"
path.parent :/home/user/file.txt  ; "/home/user"
path.join :./src :main.rs         ; "./src/main.rs"

shell. — Shell commands & environment

Execution:

FunctionArgsDescription
shellcmdRun command, return stdout as string. Error on non-zero exit.
shell!cmdRun command with output shown, return exit code
shell.codecmdRun silently, return exit code
shell.fullcmdRun, return object {stdout stderr code ok}
shell?cmdRun, return stdout or null on failure
shell.ok?cmdTrue if command exits with code 0
shell.linescmdRun, return stdout as list of lines
shell "git status"                ; stdout string
shell.lines "git branch"          ; ["  main" "* feature"]
shell? "ls /nonexistent"          ; null (no error thrown)
shell.full "make test"            ; {:stdout "..." :stderr "..." :code 0 :ok true}

Environment:

FunctionArgsDescription
shell.envnameGet environment variable, or null
shell.env.setname valSet environment variable
shell.env.removenameRemove environment variable
shell.env.allAll environment variables as object
shell.homeHome directory path
shell.cwdCurrent working directory
shell.cdpathChange current working directory
shell.osOS name: "linux", "macos", "windows"
shell.archCPU architecture: "x86_64", "aarch64", etc.
shell.hascmdTrue if command exists in PATH
shell.whichcmdFull path to command, or null
shell.ask[prompt]Read a line from stdin (optional prompt)
shell.argsAll command-line arguments as list

Process:

FunctionArgsDescription
process.pidCurrent process ID
process.fileName of executing script file, or null in REPL
process.argsCommand-line arguments (without shik and filename)
process.sleepmsSleep for ms milliseconds
process.abortAbnormal process termination
exitcodeExit with given code
exit!Exit with code 0

bool. — Comparisons & logic

FunctionArgsDescription
=a bEquality (numbers, bools, strings, null)
!=a bInequality
>a bb > a — “is b greater than a?”
>=a bb >= a
<a bb < a — “is b less than a?”
<=a bb <= a
anda bLogical AND (short-circuit)
ora bLogical OR (short-circuit)
notaLogical negation
boolvalConvert to bool (0, null, "", [], {} = false)

Note the argument order for comparisons: > a b asks “is b greater than a?” This is consistent with the modifier-first convention.

> 5 10        ; true  (is 10 > 5?)
< 10 5        ; true  (is 5 < 10?)
>= 3 3        ; true

; Curried predicates
[1 5 3 8 2] $> list.filter (> 4)     ; [5 8] (elements > 4)
[1 5 3 8 2] $> list.filter (<= 3)    ; [1 3 2] (elements <= 3)

fn. — Function utilities

FunctionArgsDescription
fn.invoke / invokefnCall fn with no arguments
fn.idvalIdentity function — returns val
[(fn [] print :a) (fn [] print :b)] $> list.iterate fn.invoke
; a
; b

var. — Dynamic variable access

FunctionArgsDescription
var.getnameLook up variable by string name, or null

Polymorphic functions

These functions work across multiple types:

FunctionTypesDescription
+Number+Number, String+String, String+otherAddition or concatenation
at(index, String) or (index, List)Get element at index
iterate(fn, String) or (fn, List)Iterate over characters or elements
iterate-backward / <iterate(fn, String) or (fn, List)Iterate in reverse
printanyPrint value to stdout

Utilities

FunctionArgsDescription
printvalPrint value with newline
help[topic]Show help (no args: overview; "module.": module list; "fn.name": function info)
or?val defaultReturn default if val is null