Sl-sh
Documentation structure for each form
form name | type (see: Type forms) |
namespace (fully qualified names are of format namespace::symbol) | usage |
example code if exists
Table of Contents
Char forms
char-lower
, char-upper
, char-whitespace?
Conditional forms
<
, <=
, =
, >
, >=
, and
, cond
, if
, match
, not
, null
, or
, when
Core forms
*collection-src*
, *core-src*
, *getopts-src*
, *iterator-src*
, *lib-src*
, *seq-src*
, *shell-read-src*
, *shell-src*
, *slsh-std-src*
, *slshrc-src*
, *struct-src*
, *test-src*
, and-let*
, apply
, back-quote
, block
, dec!
, def
, def?
, defmacro
, defn
, do
, doc
, doc-raw
, dotimes
, dotimes-i
, dyn
, eprint
, eprintln
, err
, error-stack-off
, error-stack-on
, eval
, expand-macro
, expand-macro-all
, expand-macro1
, fn
, format
, gensym
, get-error
, identity
, inc!
, intern-stats
, len0?
, len>0?
, length
, let
, let*
, loop
, macro
, maybe-docstring?
, meta-add-tags
, meta-column-no
, meta-file-name
, meta-line-no
, meta-tag?
, nsubstitute!
, occurs
, print
, print-error
, println
, quote
, reader-macro-dot
, recur
, ref
, return-from
, set!
, substitute
, undef
, unwind-protect
, values
, values-length
, values-nth
, var
File forms
cd
, close
, collate-fs-changes
, flush
, fs-accessed
, fs-base
, fs-crawl
, fs-dir?
, fs-exists?
, fs-file?
, fs-len
, fs-modified
, fs-notify
, fs-parent
, fs-rm
, fs-same?
, get-temp
, get-temp-file
, glob
, open
, read
, read-all
, read-line
, temp-dir
, with-temp
, with-temp-file
, write-line
, write-string
Globals forms
*last-command*
, *last-status*
, *repl-settings*
, *std-lib-namespaces*
, *std-lib-syms-hash*
Hashmap forms
hash-clear!
, hash-get
, hash-haskey
, hash-keys
, hash-remove!
, hash-set!
, make-hash
Iterator forms
append
, append-iter
, append-to!
, collect
, collect-str
, collect-vec
, double-ended-iter?
, double-ended-iterator
, empty?
, file-iter
, filter
, filter-iter
, for
, for-i
, interleave
, interleave-iter
, iter
, iter?
, iterator
, list-iter
, map
, map-iter
, meld
, meld-iter
, next!
, nth
, range
, range-iter
, reduce
, reduce-times
, repeat
, repeat-iter
, reverse
, reverse-iter
, slice
, slice-iter
, string-iter
, take
, take-iter
, vec-iter
Logger forms
Math forms
%
, *
, *euler*
, *pi*
, +
, -
, /
, 2pow
, abs
, arccos
, arcsin
, arctan
, ceil
, cos
, exp
, floor
, fract
, lne
, log
, log2
, pow
, round
, sin
, sqrt
, tan
, to-degrees
, to-radians
Namespace forms
ns-auto-export
, ns-create
, ns-enter
, ns-exists?
, ns-export
, ns-import
, ns-list
, ns-pop
, ns-push
, ns-symbols
Pair forms
car
, cdr
, join
, list
, xar!
, xdr!
Pair-ext forms
caaar
, caadr
, caar
, cadar
, cadddr
, caddr
, cadr
, cdaar
, cdadr
, cdar
, cddar
, cdddr
, cddr
Random forms
Regex forms
make-regex
, re-color
, re-find
, re-find-all
, re-match
, re-replace
Root forms
*read-table*
, *read-table-terminal*
, *string-read-table*
Scripting forms
Sequence forms
butlast
, collect-copy
, empty-seq?
, first
, in?
, last
, non-empty-seq?
, qsort
, rest
, seq-for
, seq?
, setnth!
Shell forms
*stderr*
, *stdin*
, *stdout*
, alias
, alias?
, bg-color-rgb
, clear-dirs
, dirs
, epoch
, err>
, err>>
, err>null
, fc
, fg-color-rgb
, get-dirs
, getopts
, getopts-help
, history-context
, history-empty?
, history-length
, history-nth
, history-push
, history-push-throwaway
, let-env
, out-err>
, out-err>>
, out-err>null
, out>
, out>>
, out>null
, popd
, prompt
, pushd
, register-alias
, set-dirs-max
, syntax-off
, syntax-on
, sys-command?
, timer
, unalias
, unregister-alias
, version
Stats forms
first-quartile
, max
, mean
, median
, min
, mode
, std-dev
, summary-stats
, third-quartile
String forms
char->int
, codepoints
, do-unstr
, str
, str-append
, str-bytes
, str-cat-list
, str-clear!
, str-contains
, str-empty?
, str-iter-empty?
, str-iter-next!
, str-iter-peek
, str-iter-start
, str-lower
, str-ltrim
, str-map
, str-nth
, str-push!
, str-replace
, str-rsplit
, str-rsplitn
, str-rtrim
, str-split
, str-splitn
, str-starts-with
, str-sub
, str-trim
, str-upper
, with-padding
Struct forms
System forms
bg
, exit
, export
, fg
, fork
, get-env
, get-pid
, jobs
, pid
, pipe
, reap-jobs
, sleep
, syscall
, time
, umask
, unexport
, wait
Test forms
assert-equal
, assert-error
, assert-error-msg
, assert-false
, assert-not-equal
, assert-true
, run-example
Threading-macros forms
->
, ->>
, chain
, chain-and
, chain-when
Type forms
boolean?
, builtin?
, char?
, false?
, falsey?
, file?
, float->int
, float?
, func?
, hash?
, int->float
, int?
, lambda?
, list?
, macro?
, nil?
, none?
, pair?
, process?
, regex?
, some?
, str->float
, str->int
, string?
, sym
, sym->str
, symbol?
, true?
, type
, values?
, vec?
Vector forms
make-vec
, vec
, vec-clear!
, vec-empty?
, vec-insert!
, vec-nth
, vec-pop!
, vec-push!
, vec-remove!
, vec-set!
, vec-slice
Documentation
Char forms
char-lower |
Type: Function |
root::char-lower |
Usage: (char-lower char) -> char |
Get lower case (utf) character for a character.
Example:
(test::assert-equal #\a (char-lower #\A))
(test::assert-equal #\a (char-lower #\a))
(test::assert-not-equal #\a (char-lower #\Z))
(test::assert-equal #\λ (char-lower #\Λ))
(test::assert-equal #\λ (char-lower #\λ))
char-upper |
Type: Function |
root::char-upper |
Usage: (char-upper char) -> char |
Get upper case (utf) character for a character.
Example:
(test::assert-equal #\A (char-upper #\A))
(test::assert-equal #\A (char-upper #\a))
(test::assert-not-equal #\A (char-upper #\Z))
(test::assert-equal #\Λ (char-upper #\λ))
(test::assert-equal #\Λ (char-upper #\Λ))
char-whitespace? |
Type: Function |
root::char-whitespace? |
Usage: (char-whitespace? char) -> t/nil |
Returns true if a character is whitespace, false/nil otherwise.
Example:
(test::assert-true (char-whitespace? #\ ))
(test::assert-true (char-whitespace? #\tab))
(test::assert-false (char-whitespace? #\s))
Conditional forms
< |
Type: Function |
root::< |
Usage: (< val0 ... valN) |
Less than. Works for int, float or string.
Example:
(test::assert-true (< 1 2))
(test::assert-true (< 1 2 3 4))
(test::assert-false (< 2 2))
(test::assert-false (< 2 2 2))
(test::assert-false (< 2 2 3))
(test::assert-true (< 1.0 2.0))
(test::assert-false (< 2.0 2.0))
(test::assert-false (< 2.0 2.0 2.0))
(test::assert-false (< 2.0 2.0 3.0))
(test::assert-false (< 2.1 2.0 3.0))
(test::assert-false (< 2 1))
(test::assert-false (< 3 2 3))
(test::assert-true (< "aaa" "aab"))
(test::assert-false (< "aaa" "aaa"))
(test::assert-true (< "aaa" "aab" "ccc"))
(test::assert-false (< "baa" "aab"))
<= |
Type: Function |
root::<= |
Usage: (<= val0 ... valN) |
Less than or equal. Works for int, float or string.
Example:
(test::assert-true (<= 1 2))
(test::assert-true (<= 2 2))
(test::assert-true (<= 2 2 2))
(test::assert-true (<= 2 2 3))
(test::assert-true (<= 1.0 2.0))
(test::assert-true (<= 2.0 2.0))
(test::assert-true (<= 2.0 2.0 2.0))
(test::assert-true (<= 2.0 2.0 3.0))
(test::assert-false (<= 2.1 2.0 3.0))
(test::assert-false (<= 2 1))
(test::assert-false (<= 3 2 3))
(test::assert-true (<= "aaa" "aab"))
(test::assert-true (<= "aaa" "aaa"))
(test::assert-true (<= "aaa" "aab" "ccc"))
(test::assert-false (<= "baa" "aab"))
= |
Type: Function |
root::= |
Usage: (= val0 ... valN) |
Equals. Works for int, float or string.
Example:
(test::assert-false (= 1 2))
(test::assert-true (= 2 2))
(test::assert-true (= 2 2 2))
(test::assert-false (= 3 2 2))
(test::assert-false (= 3.0 2.0))
(test::assert-true (= 2.0 2.0))
(test::assert-true (= 2.0 2.0 2.0))
(test::assert-false (= 3.0 2.0 2.0))
(test::assert-false (= 2.1 2.0 3.0))
(test::assert-false (= 2 1))
(test::assert-false (= 3 2 1))
(test::assert-false (= 1.1 1.0))
(test::assert-true (= 1.1 1.1))
(test::assert-false (= 3 2 3))
(test::assert-false (= "aab" "aaa"))
(test::assert-true (= "aaa" "aaa"))
(test::assert-true (= "aaa" "aaa" "aaa"))
(test::assert-false (= "aaa" "aaaa" "aaa"))
(test::assert-false (= "ccc" "aab" "aaa"))
(test::assert-false (= "aaa" "aab"))
> |
Type: Function |
root::> |
Usage: (> val0 ... valN) |
Greater than. Works for int, float or string.
Example:
(test::assert-false (> 1 2))
(test::assert-false (> 2 2))
(test::assert-false (> 2 2 2))
(test::assert-false (> 3 2 2))
(test::assert-true (> 3.0 2.0))
(test::assert-false (> 2.0 2.0))
(test::assert-false (> 2.0 2.0 2.0))
(test::assert-false (> 3.0 2.0 2.0))
(test::assert-false (> 2.1 2.0 3.0))
(test::assert-true (> 2 1))
(test::assert-true (> 3 2 1))
(test::assert-true (> 1.1 1.0))
(test::assert-false (> 3 2 3))
(test::assert-true (> "aab" "aaa"))
(test::assert-false (> "aaa" "aaa"))
(test::assert-true (> "ccc" "aab" "aaa"))
(test::assert-false (> "aaa" "aab"))
>= |
Type: Function |
root::>= |
Usage: (>= val0 ... valN) |
Greater than or equal. Works for int, float or string.
Example:
(test::assert-false (>= 1 2))
(test::assert-true (>= 2 2))
(test::assert-true (>= 2 2 2))
(test::assert-true (>= 3 2 2))
(test::assert-true (>= 3.0 2.0))
(test::assert-true (>= 2.0 2.0))
(test::assert-true (>= 2.0 2.0 2.0))
(test::assert-true (>= 3.0 2.0 2.0))
(test::assert-false (>= 2.1 2.0 3.0))
(test::assert-true (>= 2 1))
(test::assert-true (>= 1.1 1.0))
(test::assert-false (>= 3 2 3))
(test::assert-true (>= "aab" "aaa"))
(test::assert-true (>= "aaa" "aaa"))
(test::assert-true (>= "ccc" "aab" "aaa"))
(test::assert-false (>= "aaa" "aab"))
and |
Type: SpecialForm |
root::and |
Usage: (and exp0 ... expN) -> [false(#f) or expN result] |
Evaluates each form until one produces nil or false(#f), produces false(#f) if any form is nil/#f or the result of the last expression. The and form will stop evaluating when the first expression produces nil/#f.
Example:
(test::assert-equal #f (and nil (err "and- can not happen")))
(test::assert-equal #f (and #f (err "and- can not happen")))
(test::assert-equal "and- done" (and #t "and- done"))
(test::assert-equal "and- done" (and #t #t "and- done"))
(test::assert-equal 6 (and #t #t (+ 1 2 3)))
(test::assert-equal 6 (and (/ 10 5) (* 5 2) (+ 1 2 3)))
cond |
Type: Macro |
root::cond |
Usage: (cond ((test form*)*) -> result |
Evaluate each test in order. If it is true then evaluate the form(s) in an implicit do and return the result. Stop evaluting at the first true test. Return nil if no conditions are true.
Example:
(defn select-option (a)
(cond ((= a 1) "opt-one")
((= a 2) (set! b 5) "opt-two")
((= a 3) (str "opt" "-three"))))
(defn select-option-def (a)
(cond ((= a 1) "opt-one")
((= a 2) "opt-two")
((= a 3) (str "opt" "-three"))
(#t "default")))
(def b 0)
(assert-equal "opt-one" (select-option 1))
(assert-equal b 0)
(assert-equal "opt-two" (select-option 2))
(assert-equal b 5)
(assert-equal "opt-three" (select-option 3))
(assert-equal nil (select-option 4))
(assert-equal "opt-one" (select-option-def 1))
(assert-equal "opt-two" (select-option-def 2))
(assert-equal "opt-three" (select-option-def 3))
(assert-equal "default" (select-option-def 4))
if |
Type: SpecialForm |
root::if |
Usage: (if p1 a1 p2 a2 ... pn an?) -> [evaled form result] |
If conditional. Will evaluate p1 and if true (i.e. not nil or false) then return the evaluation of a1, if falsey(i.e. nil or false) evaluate p2 and so on. On an odd number of arguments (an is missing) then evaluate and return pn. Return false(#f) if no predicate is true. This degenerates into the traditional (if predicate then-form else-form). NOTE: Both nil and false(#f) are ‘falsey’ for the purposes of if.
Example:
(def test-if-one
(if #t "ONE TRUE" "ONE FALSE"))
(def test-if-two
(if nil "TWO TRUE" "TWO FALSE"))
(def test-if-three
(if #f "THREE TRUE" "THREE FALSE"))
(test::assert-equal "ONE TRUE" test-if-one)
(test::assert-equal "TWO FALSE" test-if-two)
(test::assert-equal "THREE FALSE" test-if-three)
(def test-if-one2
(if #t "ONE2 TRUE"))
(def test-if-two2
(if nil "TWO2 TRUE"))
(def test-if-three2
(if #f "THREE2 TRUE"))
(test::assert-equal "ONE2 TRUE" test-if-one2)
(test::assert-equal #f test-if-two2)
(test::assert-equal #f test-if-three2)
(def test-if-one2
(if nil "ONE FALSE" #t "ONE TRUE" #t "ONE TRUE2"))
(def test-if-two2
(if nil "TWO TRUE" #f "TWO FALSE" #t "TWO TRUE2"))
(def test-if-three2
(if #f "THREE TRUE" nil "THREE FALSE" "THREE DEFAULT"))
(test::assert-equal "ONE TRUE" test-if-one2)
(test::assert-equal "TWO TRUE2" test-if-two2)
(test::assert-equal "THREE DEFAULT" test-if-three2)
(test::assert-equal nil (if nil))
(test::assert-equal #f (if nil #t nil #t nil t))
match |
Type: Macro |
root::match |
Usage: (match condition (value form*)*) -> result |
Evaluate condition and look for matching value in each branch of type (value form*). Form(s) will be wrapped in an implicit do. Use nil to take action if no match (encouraged!).
Example:
(defn select-option (a)
(match a (1 "opt-one")
(2 (set! b 5) "opt-two")
(3 (str "opt" "-three"))))
(defn select-option-def (a)
(match a (1 "opt-one")
(2 "opt-two")
(3 (str "opt" "-three"))
(nil "default")))
(def b 0)
(assert-equal b 0)
(assert-equal "opt-one" (select-option 1))
(assert-equal "opt-two" (select-option 2))
(assert-equal b 5)
(assert-equal "opt-three" (select-option 3))
(assert-equal #f (select-option 4))
(assert-equal "opt-one" (select-option-def 1))
(assert-equal "opt-two" (select-option-def 2))
(assert-equal "opt-three" (select-option-def 3))
(assert-equal "default" (select-option-def 4))
not |
Type: Function |
root::not |
Usage: (not expression) |
Return true(#t) if expression is nil, false(#f) otherwise.
Example:
(test::assert-true (not nil))
(test::assert-false (not 10))
(test::assert-false (not #t))
(test::assert-false (not (+ 1 2 3)))
null |
Type: Function |
root::null |
Usage: (null expression) |
Return true(#t) if expression is nil (null).
Example:
(test::assert-true (null nil))
(test::assert-false (null 10))
(test::assert-false (null #t))
(test::assert-false (null (+ 1 2 3)))
or |
Type: SpecialForm |
root::or |
Usage: (or exp0 ... expN) -> [false(#f) or first non nil expression] |
Evaluates each form until one produces a non-nil/non-false result, produces #f if all expressions are ‘falsey’. The or form will stop evaluating when the first expression produces non-nil/false.
Example:
(test::assert-true (or nil nil #t (err "and- can not happen")))
(test::assert-true (or #f nil #t (err "and- can not happen")))
(test::assert-true (or #f #f #t (err "and- can not happen")))
(test::assert-equal #f (or nil nil nil))
(test::assert-equal #f (or #f nil nil))
(test::assert-equal #f (or #f nil #f))
(test::assert-equal #f (or #f #f #f))
(test::assert-equal "or- done" (or nil "or- done"))
(test::assert-equal "or- done" (or nil nil "or- done"))
(test::assert-equal 6 (or nil nil (+ 1 2 3)))
(test::assert-equal 2 (or (/ 10 5) (* 5 2) (+ 1 2 3)))
when |
Type: Macro |
root::when |
Usage: (when provided-condition if-true) |
when is a convenience function used to check a form, provided-condition, and run some form, if-true, if provided-condition evaluates to true.
Example:
(assert-true (when #t #t))
(assert-false (when #t nil))
(assert-false (when nil nil))
Core forms
*collection-src* |
Type: String |
root::*collection-src* |
Usage: (print *collection-src*) |
The builtin source code for collection.lisp.
Example:
;(print *collection-src*)
#t
*core-src* |
Type: String |
root::*core-src* |
Usage: (print *core-src*) |
The builtin source code for core.lisp.
Example:
;(print *core-src*)
#t
*getopts-src* |
Type: String |
root::*getopts-src* |
Usage: (print *getopts-src*) |
The builtin source code for shell.lisp.
Example:
;(print *getopts-src*)
#t
*iterator-src* |
Type: String |
root::*iterator-src* |
Usage: (print *iterator-src*) |
The builtin source code for iterator.lisp.
Example:
;(print *iterator-src*)
#t
*lib-src* |
Type: String |
root::*lib-src* |
Usage: (print *lib-src*) |
The builtin source code for lib.lisp.
Example:
;(print *lib-src*)
#t
*seq-src* |
Type: String |
root::*seq-src* |
Usage: (print *seq-src*) |
The builtin source code for seq.lisp.
Example:
;(print *seq-src*)
#t
*shell-read-src* |
Type: String |
root::*shell-read-src* |
Usage: (print *shell-read-src*) |
The builtin source code for shell-read.lisp.
Example:
;(print *shell-read-src*)
#t
*shell-src* |
Type: String |
root::*shell-src* |
Usage: (print *shell-src*) |
The builtin source code for shell.lisp.
Example:
;(print *shell-src*)
#t
*slsh-std-src* |
Type: String |
root::*slsh-std-src* |
Usage: (print *slsh-std-src*) |
The builtin source code for slsh-std.lisp.
Example:
;(print *slsh-std-src*)
#t
*slshrc-src* |
Type: String |
root::*slshrc-src* |
Usage: (print *slshrc-src*) |
The builtin source code for slshrc.
Example:
;(print *slshrc-src*)
#t
*struct-src* |
Type: String |
root::*struct-src* |
Usage: (print *struct-src*) |
The builtin source code for struct.lisp.
Example:
;(print *struct-src*)
#t
*test-src* |
Type: String |
root::*test-src* |
Usage: (print *test-src*) |
The builtin source code for test.lisp.
Example:
;(print *test-src*)
#t
and-let* |
Type: Macro |
root::and-let* |
Usage: (and-let* vals &rest let-body) |
Takes list, vals, of form ((binding0 sexp0) (binding1 sexp1) …) checking if result of each sexp evaluates to false, short circuiting and returning nil if so. If all vals bindings evaluate to true, then the let-body is evaluated with all values of binding bound to the result of the evaluation of sexp. Sexps can reference bindings from previous items in the list of vals. If no let-body is supplied the last binding in the list of vals is returned.
Example:
(test::assert-equal "charlie bravo alpha."
(and-let* ((val (str "alpha."))
(other-val (str "bravo " val)))
(str "charlie " other-val)) "]")
(test::assert-equal "alpha, bravo." (and-let* ((val (do
(str "bravo.")))
(other-val (do
(str "alpha, " val))))))
(test::assert-false (and-let* ((val (do (str "alpha, ") nil))
(other-val (do (str "bravo " val))))))
(test::assert-false (and-let* ((a-list (list 1 2 3 4 5 6 7 8))
(evens (filter (fn (x) (= 0 (% x 2))) a-list))
(doubled (map (fn (x) (* x 2)) evens))
(odds (collect (filter (fn (x) (= 1 (% x 2))) doubled))))
#t))
apply |
Type: Function |
root::apply |
Usage: (apply function arg* list) |
Call the provided function with the supplied arguments, last is a list that will be expanded.
Example:
(def test-apply-one (apply str '(\"O\" \"NE\")))
(test::assert-equal \"ONE\" test-apply-one)
(test::assert-equal 10 (apply + 1 '(2 7)))
back-quote |
Type: SpecialForm |
root::back-quote |
Usage: `expression -> expression |
Return expression without evaluation. Always use the ` reader macro or expansion will not work (i.e. (back-quote expression) will not do , expansion). Backquote (unlike quote) allows for symbol/form evaluation using , or ,@.
Example:
(test::assert-equal (list 1 2 3) `(1 2 3))
(test::assert-equal `(1 2 3) '(1 2 3))
(def test-bquote-one 1)
(def test-bquote-list '(1 2 3))
(test::assert-equal (list 1 2 3) `(,test-bquote-one 2 3))
(test::assert-equal (list 1 2 3) `(,@test-bquote-list))
block |
Type: SpecialForm |
root::block |
Usage: (block name form*) |
Create a block with name (name is not evaluated), if no return-from encountered then return last expression (like do). Note: If the last expression in a block is a tail call then it can not use return-from since the tail call will leave the block and the return-from will not find it.
Example:
(test::assert-equal '(4 5) (block xxx '(1 2) (return-from xxx '(4 5)) '(a b) '(2 3)))
(test::assert-equal '(4 5) (block xxx '(1 2) (return-from nil '(4 5)) '(a b) '(2 3)))
(test::assert-equal '(5 6) (block xxx '(1 2) (block yyy (return-from xxx '(5 6)) '(a b)) '(2 3)))
(test::assert-equal '(5 6) (block xxx '(1 2) (block yyy ((fn (p) (return-from xxx p)) '(5 6)) '(a b)) '(2 3)))
(test::assert-equal '(2 3) (block xxx '(1 2) (block yyy (return-from yyy #t) '(a b)) '(2 3)))
(test::assert-equal '(5 6) (block yyy ((fn (p) (return-from yyy p)) '(5 6)) '(a b)) '(2 3))
(test::assert-equal 2
(block forloop
(for item in '(1 2 3)
(when (= 2 item)
(return-from forloop item)))
nil)) ; This nil keeps the for loop from being a tail call.
dec! |
Type: Macro |
root::dec! |
Usage: (dec! symbol [number]) -> new value |
Decrement the value in symbol by one or the optional number
Example:
(def *dec-test* 5)
(test::assert-equal 4 (dec! *dec-test*))
(test::assert-equal 4 *dec-test*)
(test::assert-error (dec! *dec-test* "xxx"))
(test::assert-equal 1 (dec! *dec-test* 3))
(test::assert-equal 1 *dec-test*)
(def *dec-test* "xxx")
(test::assert-error (dec! *dec-test*))
(let ((dec-test 5))
(test::assert-equal 4 (dec! dec-test))
(test::assert-equal 4 dec-test)
(test::assert-equal 1 (dec! dec-test 3))
(test::assert-equal 1 dec-test))
def |
Type: SpecialForm |
root::def |
Usage: (def symbol doc_string? expression) -> expression |
Adds an expression to the current namespace. Return the expression that was defined. Symbol is not evaluted. Can take an option doc string (docstrings can only be set on namespaced (global) symbols).
Example:
(def test-do-one nil)
(def test-do-two nil)
(def test-do-three (do (set! test-do-one "One")(set! test-do-two "Two")"Three"))
(test::assert-equal "One" test-do-one)
(test::assert-equal "Two" test-do-two)
(test::assert-equal "Three" test-do-three)
(let ((test-do-one nil))
; Add this to tthe let's scope (shadow the outer test-do-two).
(test::assert-equal "Default" (def ns::test-do-four "Default"))
; set the currently scoped value.
(set! test-do-one "1111")
(set! test-do-two "2222")
(test::assert-equal "1111" test-do-one)
(test::assert-equal "2222" test-do-two)
(test::assert-equal "Default" test-do-four))
; Original outer scope not changed.
(test::assert-equal "One" test-do-one)
(test::assert-equal "Default" test-do-four)
;(def (sym "test-do-one") "do one")
(test::assert-error (def (sym "test-do-one") "do one"))
;(test::assert-equal "do one" test-do-one)
(test::assert-error (def (sym->str test-do-one) "do one 2"))
def? |
Type: SpecialForm |
root::def? |
Usage: (def? expression) -> t\|nil |
Return true if is a defined symbol (bound within the current scope). If expression is a symbol it is not evaluted and if a list it is evaluted to produce a symbol.
Example:
(def test-is-def #t)
(def test-is-def2 'test-is-def)
(test::assert-true (def? test-is-def))
(test::assert-true (def? (sym "test-is-def")))
(test::assert-true (def? (ref test-is-def2)))
(test::assert-false (def? test-is-def-not-defined))
(test::assert-false (def? (sym "test-is-def-not-defined")))
(test::assert-error (def? (ref test-is-def)))
defmacro |
Type: Macro |
root::defmacro |
Usage: (defmacro name doc_string? argument_list body) |
Create a macro and bind it to a symbol in the current scope.
Example:
(defmacro test-mac (x) (let ((y (+ (ref (ref x)) 1))) `(set! ,x ,y)))
(def test-mac-x 2)
(test-mac test-mac-x)
(test::assert-equal 3 test-mac-x)
(defmacro test-mac (x) `(set! ,x 15))
(test-mac test-mac-x)
(test::assert-equal 15 test-mac-x)
defn |
Type: Macro |
root::defn |
Usage: (defn name &rest args) |
Define a named function in the current namespace.
Example:
(defn defn-test (x y) (+ x y))
(test::assert-equal 5 (defn-test 2 3))
(defn defn-test (x y) (set! x (* x 2))(+ x y))
(test::assert-equal 7 (defn-test 2 3))
(defn defn-test (x y))
(test::assert-false (defn-test 2 3))
(defn defn-test (x y) #t)
(test::assert-true (defn-test 2 3))
do |
Type: SpecialForm |
root::do |
Usage: (do exp0 ... expN) -> expN |
Evaluatate each form and return the last.
Example:
(def test-do-one nil)
(def test-do-two nil)
(def test-do-three (do (set! test-do-one "One")(set! test-do-two "Two")"Three"))
(test::assert-equal "One" test-do-one)
(test::assert-equal "Two" test-do-two)
(test::assert-equal "Three" test-do-three)
doc |
Type: Function |
root::doc |
Usage: (doc symbol) |
Return the doc string for a symbol or nil if no string.
Example:
;(doc 'car)
#t
doc-raw |
Type: Function |
root::doc-raw |
Usage: (doc-raw symbol) |
Return the raw (unexpanded) doc string for a symbol or nil if no string.
Example:
;(doc-raw 'car)
#t
dotimes |
Type: Macro |
root::dotimes |
Usage: (dotimes times body) |
Evaluate body a number of times equal to times’ numerical value.
Example:
(def i 0)
(dotimes 11 (set! i (+ 1 i)))
(assert-equal 11 i)
dotimes-i |
Type: Macro |
root::dotimes-i |
Usage: (dotimes-i idx-bind times body) |
Evaluate body a number of times equal to times’ numerical value. Includes an incrementing reference binding, idx-bind, accessible in body.
Example:
(def i 0)
(def i-tot 0)
(dotimes-i idx 11 (do (set! i-tot (+ idx i-tot))(set! i (+ 1 i))))
(assert-equal 11 i)
(assert-equal 55 i-tot)
dyn |
Type: Macro |
root::dyn |
Usage: (dyn key value expression) -> result_of_expression |
Creates a dynamic binding for key, assigns value to it and evals expression under it. Note that if key must be a symbol and is not evaluted. The binding is gone once the dyn form ends. This is basically a set! on the binding in an unwind protect to reset it when done. When used on a global will set the first binding found and reset it when done. Calls to dyn can be nested and previous dynamic values will be restored as interior dyn’s exit.
Example:
(defn test-dyn-fn () (print "Print dyn out"))
(dyn *stdout* (open "/tmp/sl-sh.dyn.test" :create :truncate) (test-dyn-fn))
(test::assert-equal "Print dyn out" (read-line (open "/tmp/sl-sh.dyn.test" :read)))
eprint |
Type: Function |
root::eprint |
Usage: (eprint arg0 ... argN) -> nil |
Print the arguments (as strings) to stderr.
Example:
; Use a file for stderr for test.
(dyn *stderr* (open "/tmp/sl-sh.eprint.test" :create :truncate) (do (eprint "eprint test out")(eprint " two") (close *stderr*)))
(test::assert-equal "eprint test out two" (read-line (open "/tmp/sl-sh.eprint.test" :read)))
eprintln |
Type: Function |
root::eprintln |
Usage: (eprintln arg0 ... argN) -> nil |
Print the arguments (as strings) to stderr and then a newline.
Example:
; Use a file for stderr for test.
(dyn *stderr* (open "/tmp/sl-sh.eprintln.test" :create :truncate) (do (eprintln "eprintln test out")(eprintln "line two") (close *stderr*)))
(def topen (open "/tmp/sl-sh.eprintln.test" :read))
(test::assert-equal "eprintln test out
" (read-line topen))
(test::assert-equal "line two
" (read-line topen))
err |
Type: Function |
root::err |
Usage: (err string) -> raises an error |
Raise an error with the supplied string.
Example:
(def test-err-err (get-error (err "Test Error")))
(test::assert-equal :error (car test-err-err))
(test::assert-equal "Test Error" (cadr test-err-err))
error-stack-off |
Type: Lambda |
root::error-stack-off |
Usage: (error-stack-off) |
Currently a no-op, used to turn off error stacks.
Example:
; no-op
(error-stack-off)
error-stack-on |
Type: Lambda |
root::error-stack-on |
Usage: (error-stack-on) |
Currently a no-op, used to turn on error stacks.
Example:
; no-op
(error-stack-on)
eval |
Type: Function |
root::eval |
Usage: (eval expression) |
Evaluate the provided expression. If expression is a string read it to make an ast first to evaluate otherwise evaluate the expression (note eval is a function not a special form, the provided expression will be evaluated as part of call).
Example:
(def test-eval-one nil)
(eval (read "(set! test-eval-one \"ONE\")"))
(test::assert-equal "ONE" test-eval-one)
(eval '(set! test-eval-one "TWO"))
(test::assert-equal "TWO" test-eval-one)
expand-macro |
Type: Function |
root::expand-macro |
Usage: (expand-macro expression) |
Expands a macro expression. If that expansion is also a macro then expand it recursively. Just returns the expression if not a macro.
Example:
(test::assert-equal '(def xx "value") (expand-macro '(def xx "value")))
(defmacro mac-test-for
(bind in in_list body) (do
(if (not (= in 'in)) (err "Invalid test-mac-for: (test-mac-for [v] in [iterator] (body))"))
`((fn (,bind)
(if (> (length ,in_list) 0)
(root::loop (plist) (,in_list) (do
(set! ,bind (root::first plist))
(,@body)
(if (> (length plist) 1) (recur (root::rest plist)))))))nil)))
(test::assert-equal '(
(fn
(i)
(if
(> (length '(1 2 3)) 0)
(root::loop
(plist)
('(1 2 3))
(do
(set! i (root::first plist)) nil
(if
(> (length plist) 1)
(recur (root::rest plist))))))) nil)
(expand-macro '(mac-test-for i in '(1 2 3) ())))
(test::assert-equal '(1 2 3) (expand-macro '(1 2 3)))
expand-macro-all |
Type: Function |
root::expand-macro-all |
Usage: (expand-macro-all expression) |
Expands a macro expression like expand-macro but also expand any embedded macros. Just returns the expression if not a macro.
Example:
(test::assert-equal '(def xx "value") (expand-macro-all '(def xx "value")))
(defmacro mac-test-loop
(params bindings body)
`((fn ,params ,body) ,@bindings))
(defmacro mac-test-for
(bind in in_list body) (do
(if (not (= in 'in)) (err "Invalid test-mac-for: (test-mac-for [v] in [iterator] (body))"))
`((fn (,bind)
(if (> (length ,in_list) 0)
(mac-test-loop (plist) (,in_list) (do
(set! ,bind (root::first plist))
(,@body)
(if (> (length plist) 1) (recur (root::rest plist)))))))nil)))
(test::assert-equal '(
(fn
(i)
(if
(> (length '(1 2 3)) 0)
(
(fn
(plist)
(do
(set! i (root::first plist)) nil
(if
(> (length plist) 1)
(recur (root::rest plist)))))
'(1 2 3)))) nil)
(expand-macro-all '(mac-test-for i in '(1 2 3) ())))
(test::assert-equal '(1 2 3) (expand-macro-all '(1 2 3)))
expand-macro1 |
Type: Function |
root::expand-macro1 |
Usage: (expand-macro1 expression) |
Expands a macro expression. Only expand the first macro. Just returns the expression if not a macro.
Example:
(test::assert-equal '(def xx "value") (expand-macro1 '(def xx "value")))
(defmacro mac-test-for
(bind in in_list body) (do
(if (not (= in 'in)) (err "Invalid test-mac-for: (test-mac-for [v] in [iterator] (body))"))
`((fn (,bind)
(if (> (length ,in_list) 0)
(root::loop (plist) (,in_list) (do
(set! ,bind (root::first plist))
(,@body)
(if (> (length plist) 1) (recur (root::rest plist)))))))nil)))
(test::assert-equal '((fn
(i)
(if
(> (length '(1 2 3)) 0)
(root::loop
(plist)
('(1 2 3))
(do
(set! i (root::first plist)) nil
(if
(> (length plist) 1)
(recur (root::rest plist)))))))nil)
(expand-macro1 '(mac-test-for i in '(1 2 3) ())))
(test::assert-equal '(1 2 3) (expand-macro1 '(1 2 3)))
fn |
Type: SpecialForm |
root::fn |
Usage: (fn (param*) expr*) -> exprN |
Create a function (lambda).
Example:
(def test-fn1 nil)
(def test-fn2 nil)
(def test-fn3 nil)
(def test-fn-empty ((fn ())))
(test::assert-false test-fn-empty)
((fn () (set! test-fn1 1)))
(test::assert-equal 1 test-fn1)
((fn () (set! test-fn1 10)(set! test-fn2 2)))
(test::assert-equal 10 test-fn1)
(test::assert-equal 2 test-fn2)
((fn () (set! test-fn1 11)(set! test-fn2 20)(set! test-fn3 3)))
(test::assert-equal 11 test-fn1)
(test::assert-equal 20 test-fn2)
(test::assert-equal 3 test-fn3)
((fn (x y z) (set! test-fn1 x)(set! test-fn2 y)(set! test-fn3 z)) 12 21 30)
(test::assert-equal 12 test-fn1)
(test::assert-equal 21 test-fn2)
(test::assert-equal 30 test-fn3)
(test::assert-equal 63 ((fn (x y z) (set! test-fn1 x)(set! test-fn2 y)(set! test-fn3 z)(+ x y z)) 12 21 30))
format |
Type: Function |
root::format |
Usage: (format arg0 ... argN) -> string |
Build a formatted string from arguments. Arguments will be turned into strings.
Example:
(test::assert-equal "stringsome" (format "string" "some"))
(test::assert-equal "string" (format "string" ""))
(test::assert-equal "string 50" (format "string" " " 50))
(test::assert-equal "string 50 100.5" (format "string" " " 50 " " 100.5))
gensym |
Type: Function |
root::gensym |
Usage: (gensym) -> symbol |
Generate a unique symbol. Gensym uses a prefix of gs@@ followed by an incrementing counter. It is useful to generate unique symbol names when writing macros (for instance).
Example:
(def test-gensym-one (gensym))
(def test-gensym-two (gensym))
(def test-gensym-three (gensym))
(test::assert-true (str-starts-with "gs@@" (sym->str test-gensym-one)))
(test::assert-true (str-starts-with "gs@@" (sym->str test-gensym-two)))
(test::assert-true (str-starts-with "gs@@" (sym->str test-gensym-three)))
(test::assert-true (symbol? (gensym)))
(test::assert-true (symbol? test-gensym-one))
(test::assert-true (symbol? test-gensym-two))
(test::assert-true (symbol? test-gensym-three))
get-error |
Type: Function |
root::get-error |
Usage: (get-error exp0 ... expN) -> pair |
Evaluate each form (like do) but on error return (:error msg backtrace) instead of aborting. On success return (:ok . expN-result). If there is no error will return the value of the last expression as the cdr of the pair. Always returns a pair with the first value either being :ok or :error.
Example:
(def get-error-t1 (get-error (err "Some Error")))
(test::assert-equal :error (car get-error-t1))
(test::assert-equal "Some Error" (cadr get-error-t1))
(test::assert-true (vec? (caddr get-error-t1)))
(test::assert-equal '(:ok . "Some String") (get-error "Some String"))
(test::assert-equal '(:ok . "Some Other String") (get-error (def test-get-error "Some ") (str test-get-error "Other String")))
identity |
Type: Lambda |
root::identity |
Usage: (identity x) |
Identity function.
Example:
(assert-equal 0 (identity 0))
inc! |
Type: Macro |
root::inc! |
Usage: (inc! symbol [number]) -> new value |
Increment the value in symbol by one or the optional number
Example:
(def *inc-test* 1)
(test::assert-equal 2 (inc! *inc-test*))
(test::assert-equal 2 *inc-test*)
(test::assert-equal 5 (inc! *inc-test* 3))
(test::assert-error (inc! *inc-test* "xxx"))
(test::assert-equal 5 *inc-test*)
(def *inc-test* "xxx")
(test::assert-error (inc! *inc-test*))
(let ((inc-test 1))
(test::assert-equal 2 (inc! inc-test))
(test::assert-equal 2 inc-test)
(test::assert-equal 5 (inc! inc-test 3))
(test::assert-equal 5 inc-test))
intern-stats |
Type: SpecialForm |
root::intern-stats |
Usage: (intern-stats) |
Prints the stats for interned symbols.
Example:
;(intern-stats)
#t
len0? |
Type: Macro |
root::len0? |
Usage: (len0? thing) |
Is the length of thing 0?
Example:
(assert-true (len0? nil))
(assert-true (len0? '()))
(assert-true (len0? (vec)))
(assert-true (len0? (str)))
(assert-true (len0? ""))
(assert-false (len0? '(1)))
(assert-false (len0? (vec 1 2)))
(assert-false (len0? "string"))
len>0? |
Type: Macro |
root::len>0? |
Usage: (len>0? thing) |
Is the length of thing greater than 0?
Example:
(assert-false (len>0? nil))
(assert-false (len>0? '()))
(assert-false (len>0? (vec)))
(assert-false (len>0? (str)))
(assert-false (len>0? ""))
(assert-true (len>0? '(1)))
(assert-true (len>0? (vec 1 2)))
(assert-true (len>0? "string"))
length |
Type: Function |
root::length |
Usage: (length expression) -> int |
Return length of supplied expression.
Example:
(test::assert-equal 0 (length nil))
(test::assert-equal 5 (length \"12345\"))
; Note the unicode symbol is only one char even though it is more then one byte.
(test::assert-equal 6 (length \"12345Σ\"))
(test::assert-equal 3 (length '(1 2 3)))
(test::assert-equal 3 (length '#(1 2 3)))
(test::assert-equal 3 (length (list 1 2 3)))
(test::assert-equal 3 (length (vec 1 2 3)))
(test::assert-error (length 100))
(test::assert-error (length 100.0))
(test::assert-error (length #\\x))
let |
Type: Macro |
root::let |
Usage: (let vals &rest let-body) |
Takes list, vals, of form ((binding0 sexp0) (binding1 sexp1) …) and evaluates let-body with all values of binding bound to the result of the evaluation of sexp.
Example:
(def test-do-one "One1")
(def test-do-two "Two1")
(def test-do-three (let ((test-do-one "One")) (set! test-do-two "Two")(test::assert-equal "One" test-do-one)"Three"))
(test::assert-equal "One1" test-do-one)
(test::assert-equal "Two" test-do-two)
(test::assert-equal "Three" test-do-three)
((fn (idx) (let ((v2 (+ idx 2))(v3 (+ idx 3)))
(test::assert-equal (+ idx 2) v2)
(test::assert-equal (+ idx 3) v3)
(if (< idx 5) (recur (+ idx 1)))))0)
((fn (idx) (let ((v2 (+ idx 2))(v3 (+ idx 3)))
(test::assert-equal (+ idx 2) v2)
(test::assert-equal (+ idx 3) v3)
(if (< idx 5) (this-fn (+ idx 1)))))0)
let* |
Type: Macro |
root::let* |
Usage: (let* vals &rest let-body) |
Takes list, vals, of form ((binding0 sexp0) (binding1 sexp1) …) and evaluates let-body with all values of binding bound to the result of the evaluation of sexp. Differs from let in that sexps can reference bindings from previous items in the list of vals.
Example:
(let* ((add-one (fn (x) (+ 1 x)))
(double-add (fn (x) (add-one (add-one x)))))
(test::assert-equal 4 (add-one 3))
(test::assert-equal 6 (double-add 4)))
loop |
Type: Macro |
root::loop |
Usage: (loop params bindings &rest body) |
Binds bindings to parameters in body. Use recur with desired bindings for subsequent iteration. Within the loop the lambda ‘break’ will end the loop, break can take an option argument that is what the loop produces (nil if no argument).
Example:
(def tot 0)
(loop (idx) (3) (do
(set! tot (+ tot 1))
(if (> idx 1) (recur (- idx 1)))))
(assert-equal 3 tot)
(def tot 0)
(loop (idx) (0)
(set! tot (+ tot 1))
(if (= idx 2) (break))
(recur (+ idx 1)))
(assert-equal 3 tot)
(assert-equal 11 (loop (idx) (0)
(if (= idx 2) (break 11))
(recur (+ idx 1))))
(assert-false (loop (idx) (0)
(if (= idx 2) (break))
(recur (+ idx 1))))
(assert-error (loop (idx) (0)
(if (= idx 2) (break 1 3))
(recur (+ idx 1))))
macro |
Type: SpecialForm |
root::macro |
Usage: (macro (args) `(apply + ,@args)) |
Define an anonymous macro.
Example:
(def test-macro1 nil)
(def test-macro2 nil)
(def test-macro-empty (macro ()))
(test::assert-false (test-macro-empty))
(def test-mac nil)
(def mac-var 2)
(let ((mac-var 3))
(set! test-mac (macro (x) (set! test-macro2 100)(test::assert-equal 3 mac-var)`(* ,mac-var ,x))))
(set! test-macro1 (test-mac 10))
(test::assert-equal 30 test-macro1)
(test::assert-equal 100 test-macro2)
maybe-docstring? |
Type: Lambda |
root::maybe-docstring? |
Usage: (maybe-docstring? form) |
True if form might be a docstring, nil otherwise.
Example:
(test::assert-true (maybe-docstring? "string"))
(test::assert-true (maybe-docstring? '(str 1 2 3)))
(test::assert-false (maybe-docstring? '(1 2 3)))
meta-add-tags |
Type: Function |
root::meta-add-tags |
Usage: (meta-add-tags expression tag*) |
Adds multiple meta tags to an expression. It will work with symbols or vectors or lists of symbols (or any combination). This is intended for helping with structs and interfaces in lisp, you probably do not want to use it.
Example:
(def meta-add-tags-var '(1 2 3))
(meta-add-tags meta-add-tags-var :tag1)
(test::assert-true (meta-tag? meta-add-tags-var :tag1))
(test::assert-false (meta-tag? meta-add-tags-var :tag2))
(meta-add-tags meta-add-tags-var :tag2 '(:tag3 :tag4) '#(:tag5 :tag6) :tag7)
(test::assert-true (meta-tag? meta-add-tags-var :tag2))
(test::assert-true (meta-tag? meta-add-tags-var :tag3))
(test::assert-true (meta-tag? meta-add-tags-var :tag4))
(test::assert-true (meta-tag? meta-add-tags-var :tag5))
(test::assert-true (meta-tag? meta-add-tags-var :tag6))
(test::assert-true (meta-tag? meta-add-tags-var :tag7))
meta-column-no |
Type: SpecialForm |
root::meta-column-no |
Usage: (meta-column-no) |
Column number from the file this came from.
Example:
;(meta-column-no)
#t
meta-file-name |
Type: SpecialForm |
root::meta-file-name |
Usage: (meta-file-name) |
File name of the file this came from.
Example:
;(meta-file-name)
#t
meta-line-no |
Type: SpecialForm |
root::meta-line-no |
Usage: (meta-line-no) |
Line number from the file this came from.
Example:
;(meta-line-no)
#t
meta-tag? |
Type: Function |
root::meta-tag? |
Usage: (meta-tag? expression tag) |
True if expression has the meta tag ‘tag’ set. This is intended for helping with structs and interfaces in lisp, you probably do not want to use it.
Example:
(def meta-add-tag-var '(1 2 3))
(meta-add-tags meta-add-tag-var :tag1)
(test::assert-true (meta-tag? meta-add-tag-var :tag1))
(test::assert-false (meta-tag? meta-add-tag-var :tag2))
nsubstitute! |
Type: Lambda |
root::nsubstitute! |
Usage: (nsubstitute! new-item old-item lst &rest mods) |
Replaces all instances of old-item in lst with new-item. If last argument passed in is keyword :first only the first instance of old-item will be replaced.
Example:
(let ((lst (list 1 2 3 4 5)))
(test::assert-equal (list 1 2 10 4 5) (nsubstitute! 10 3 lst))
(test::assert-equal (list 1 2 10 4 5) lst))
occurs |
Type: Lambda |
root::occurs |
Usage: (occurs (list 1 2 ...) 7) (occurs (list 1 2 ...) 0 (fn (x) (% x 2))) |
Counts instances of item in sequence. Optional third argument is a function that can be applied to the specific element in the list before equality is tested with item.
Example:
(test::assert-equal 7 (occurs (list 1 3 5 2 4 10 2 4 88 2 1) 0 (fn (x) (% x 2))))
(test::assert-equal 3 (occurs (list 1 3 5 2 4 10 2 4 88 2 1) 2))
(test::assert-equal 0 (occurs (list 1 3 5 2 4 10 2 4 88 2 1) 42))
(test::assert-equal 2 (occurs (list 1 3 5 2 4 10 2 4 88 2 1) 8 (fn (x) (* x 2))))
print |
Type: Function |
root::print |
Usage: (print arg0 ... argN) -> nil |
Print the arguments (as strings) to stdout.
Example:
; Use a file for stdout for test.
(dyn *stdout* (open "/tmp/sl-sh.print.test" :create :truncate) (do (print "Print test out")(print " two") (close *stdout*)))
(test::assert-equal "Print test out two" (read-line (open "/tmp/sl-sh.print.test" :read)))
print-error |
Type: Lambda |
root::print-error |
Usage: (print-error error) |
Prints out an error with a backtrace. Used with the return of get-error when it produces an error
Example:
(let
((print-error-test (get-error (err "Oops!")))
(file-name "$(temp-dir)/print-error.test")
(topen))
(out> file-name (print-error print-error-test))
(set! topen (open file-name :read))
(test::assert-true (> (length (read-line topen)) 5))
(close topen))
println |
Type: Function |
root::println |
Usage: (println arg0 ... argN) -> nil |
Print the arguments (as strings) to stdout and then a newline.
Example:
; Use a file for stdout for test.
(dyn *stdout* (open "/tmp/sl-sh.println.test" :create :truncate) (do (println "Println test out")(println "line two") (close *stdout*)))
(def topen (open "/tmp/sl-sh.println.test" :read))
(test::assert-equal "Println test out
" (read-line topen))
(test::assert-equal "line two
" (read-line topen))
quote |
Type: SpecialForm |
root::quote |
Usage: 'expression -> expression |
Return expression without evaluation. The reader macro ‘expression will expand to (quote expression).
Example:
(test::assert-equal (list 1 2 3) (quote (1 2 3)))
(test::assert-equal (list 1 2 3) '(1 2 3))
(test::assert-equal '(1 2 3) (quote (1 2 3)))
reader-macro-dot |
Type: Lambda |
root::reader-macro-dot |
Usage: (reader-macro-dot stream ch) |
Reader macro for #.(…). Do not call directly.
Example:
(def dot-test (read "(1 2 #.(* 3 10) #.(str "o" "ne"))))
(test::assert-equal '(1 2 30 "one"))
recur |
Type: Function |
root::recur |
Usage: (recur &rest) |
Recursively call the enclosing function with the given parameters. Recur uses tail call optimization and must be in the tail position or it is an error. For a named function it would be equivalent to a normal recursive call in a tail position but it requires a tail position and does not need a name (a normal recursive call would work in a non-tail position but could blow the stack if it is to deep- unlike a recur or tail position recursive call). NOTE: potential footgun, the let macro expands to a lambda (fn) and a recur used inside the let would bind with the let not the enclosing lambda (this would apply to any macro that also expands to a lamda- this is by design with the loop macro but would be unexpected with let).
Example:
(def tot 0)
(loop (idx) (3) (do
(set! tot (+ tot 1))
(if (> idx 1) (recur (- idx 1)))))
(assert-equal 3 tot)
(set! tot 0)
((fn (idx) (do
(set! tot (+ tot 1))
(if (> idx 1) (recur (- idx 1)))))5)
(assert-equal 5 tot)
ref |
Type: SpecialForm |
root::ref |
Usage: (ref symbol) -> expression |
Return the expression that is referenced by symbol. Symbol is only evaluated if a list (that produces a symbol) and must be bound in the current scope or an error is raised.
Example:
(def test-is-def #t)
(def test-is-def2 'test-is-def)
(test::assert-true (ref test-is-def))
(set! test-is-def '(1 2 3))
(test::assert-equal '(1 2 3) (ref test-is-def))
(test::assert-error (ref test-is-def-no-exist))
(test::assert-error (ref (ref test-is-def)))
(test::assert-equal '(1 2 3) (ref (ref test-is-def2)))
return-from |
Type: SpecialForm |
root::return-from |
Usage: (return-from name expression?) |
Causes enclosing block with name (name is not evaluated) to evaluate to expression.
Example:
(test::assert-equal '(4 5) (block xxx '(1 2) (return-from xxx '(4 5)) '(a b) '(2 3)))
(test::assert-equal '(4 5) (block xxx '(1 2) (return-from nil '(4 5)) '(a b) '(2 3)))
(test::assert-equal '(5 6) (block xxx '(1 2) (block yyy (return-from xxx '(5 6)) '(a b)) '(2 3)))
(test::assert-equal '(5 6) (block xxx '(1 2) (block yyy ((fn (p) (return-from xxx p)) '(5 6)) '(a b)) '(2 3)))
(test::assert-equal '(2 3) (block xxx '(1 2) (block yyy (return-from yyy #t) '(a b)) '(2 3)))
set! |
Type: SpecialForm |
root::set! |
Usage: (set! symbol expression) -> expression |
Sets an existing expression in the current scope(s). Return the expression that was set. Symbol is not evaluted. Set will set the first binding it finds starting in the current scope and then trying enclosing scopes until exhausted.
Example:
(def test-do-one nil)
(def test-do-two nil)
(def test-do-three (do (set! test-do-one "One")(set! test-do-two "Two")"Three"))
(test::assert-equal "One" test-do-one)
(test::assert-equal "Two" test-do-two)
(test::assert-equal "Three" test-do-three)
(let ((test-do-one nil))
; set the currently scoped value.
(test::assert-equal "1111" (set! test-do-one "1111"))
(test::assert-equal "1111" test-do-one))
; Original outer scope not changed.
(test::assert-equal "One" test-do-one)
;(set! (sym "test-do-one") "do one")
;(test::assert-equal "do one" test-do-one)
(test::assert-error (set! (sym->str test-do-one) "do one 2"))
substitute |
Type: Macro |
root::substitute |
Usage: (substitute new-item old-item lst &rest mods) |
Replaces all instances of old-item in copy of lst with new-item. If last argument passed in is keyword :first only the first instance of old-item will be replaced.
Example:
(let ((lst (list 1 2 3 4 5))
(lst2 (list 1 2 3 3 3 4 5)))
(test::assert-equal (list 1 2 10 4 5) (substitute 10 3 lst))
(test::assert-equal lst lst)
(test::assert-equal (list 1 2 4 4 4 4 5) (substitute 4 3 lst2))
(test::assert-equal (list 1 2 4 3 3 4 5) (substitute 4 3 lst2 :first)))
undef |
Type: SpecialForm |
root::undef |
Usage: (undef symbol) -> expression |
Remove a symbol from the current namespace (if it exists). Returns the expression that was removed. It is an error if symbol is not defined in the current namespace. Symbol is not evaluted.
Example:
(def test-undef nil)
(test::assert-true (def? test-undef))
(undef test-undef)
(test::assert-false (def? test-undef))
(def test-undef "undef")
(test::assert-equal "undef" (undef test-undef))
(test::assert-false (def? test-undef))
(test::assert-equal "undef: symbol test-undef not defined in current scope (can only undef symbols in current scope)." (cadr (get-error (undef test-undef))))
unwind-protect |
Type: Function |
root::unwind-protect |
Usage: (unwind-protect protected cleanup*) -> [protected result] |
After evaluation first form, make sure the following cleanup forms run (returns first form’s result).
Example:
(def test-unwind-one nil)
(def test-unwind-err (get-error
(unwind-protect (err "Some protected error") (set! test-unwind-one "got it"))))
(test::assert-equal :error (car test-unwind-err))
(test::assert-equal "Some protected error" (cadr test-unwind-err))
(test::assert-equal "got it" test-unwind-one)
(def test-unwind-one nil)
(def test-unwind-two nil)
(def test-unwind-three nil)
(def test-unwind-four nil)
(def test-unwind-err (get-error
(unwind-protect
(do (set! test-unwind-one "set one")(err "Some protected error two")(set! test-unwind-two "set two"))
(set! test-unwind-three "set three")(set! test-unwind-four "set four"))))
(test::assert-equal :error (car test-unwind-err))
(test::assert-equal "Some protected error two" (cadr test-unwind-err))
(test::assert-equal "set one" test-unwind-one)
(test::assert-equal nil test-unwind-two)
(test::assert-equal "set three" test-unwind-three)
(test::assert-equal "set four" test-unwind-four)
values |
Type: Function |
root::values |
Usage: (values expression*) |
Produces a multi values object. Useful for returning more then one value from a function when most of time you only care about the first (primary) item. When evaluting a muti values object it will evaluate as if it the first item only.
Example:
(test::assert-true (values? (values 1 "str" 5.5)))
(test::assert-equal 1 (values-nth 0 (values 1 "str" 5.5)))
(test::assert-equal "str" (values-nth 1 (values 1 "str" 5.5)))
(test::assert-equal 5.5 (values-nth 2 (values 1 "str" 5.5)))
values-length |
Type: Function |
root::values-length |
Usage: (values-length expression) |
If expression is a values object then return it’s length (number of values).
Example:
(test::assert-equal 3 (values-length (values 1 "str" 5.5)))
(test::assert-equal 2 (values-length (values 1 "str")))
(test::assert-equal 1 (values-length (values "str")))
(test::assert-equal 0 (values-length (values)))
(test::assert-equal "str" (values-nth 1 (values 1 "str" 5.5)))
(test::assert-equal 5.5 (values-nth 2 (values 1 "str" 5.5)))
(def test-vals-len (values 1 "str" 5.5))
(test::assert-equal 3 (values-length test-vals-len))
values-nth |
Type: Function |
root::values-nth |
Usage: (values-nth idx expression) |
If expression is a values object then return the item at index idx.
Example:
(test::assert-equal 1 (values-nth 0 (values 1 "str" 5.5)))
(test::assert-equal "str" (values-nth 1 (values 1 "str" 5.5)))
(test::assert-equal 5.5 (values-nth 2 (values 1 "str" 5.5)))
(def test-vals-nth (values 1 "str" 5.5))
(test::assert-equal 1 (values-nth 0 test-vals-nth))
(test::assert-equal "str" (values-nth 1 test-vals-nth))
(test::assert-equal 5.5 (values-nth 2 test-vals-nth))
var |
Type: SpecialForm |
root::var |
Usage: (var symbol expression) -> expression |
NOTE: var is deprecated, use let or let* to create local bindings. Adds an expression to the current lexical scope. Return the expression that was defined. This will not add to a namespace (use def for that), use it within functions or let forms to create local bindings. Symbol is not evaluated.
Example:
(let (())
(var test-do-one nil)
(var test-do-two nil)
(var test-do-three (do (set! test-do-one "One")(set! test-do-two "Two")"Three"))
(test::assert-equal "One" test-do-one)
(test::assert-equal "Two" test-do-two)
(test::assert-equal "Three" test-do-three)
(let ((test-do-one nil))
; Add this to the let's scope (shadow the outer test-do-two).
(test::assert-equal "Default" (var test-do-two "Default"))
; set the currently scoped value.
(set! test-do-one "1111")
(set! test-do-two "2222")
(test::assert-equal "1111" test-do-one)
(test::assert-equal "2222" test-do-two))
; Original outer scope not changed.
(test::assert-equal "One" test-do-one)
(test::assert-equal "Two" test-do-two))
File forms
Options to open, one or more of these can be added to open after the filename. A file can only be opened for reading or writing (read is default).
Option | Description |
---|---|
:read | Open file for reading, this is the default. |
:write | Open file for writing. |
:append | Open file for writing and append new data to end. |
:truncate | Open file for write and delete all existing data. |
:create | Create the file if it does not exist and open for writing. |
:create-new | Create if does not exist, error if it does and open for writing. |
:on-error-nil | If open has an error then return nil instead of producing an error. |
Notes on closing. Files will close when they go out of scope. Using close will cause a reference to a file to be marked close (removes that reference). If there are more then one references to a file it will not actually close until all are released. Close will also flush the file even if it is not the final reference. If a reference to a file is captured in a closure that can also keep it open (closures currently capture the entire scope not just used symbols).
cd |
Type: Function |
root::cd |
Usage: (cd dir-to-change-to) |
Change directory.
Example:
(syscall 'mkdir "/tmp/tst-fs-cd")
(syscall 'touch "/tmp/tst-fs-cd/fs-cd-marker")
(test::assert-false (fs-exists? "fs-cd-marker"))
(pushd "/tmp/tst-fs-cd")
(root::cd "/tmp")
(root::cd "/tmp/tst-fs-cd")
(test::assert-true (fs-exists? "fs-cd-marker"))
(syscall 'rm "/tmp/tst-fs-cd/fs-cd-marker")
(popd)
(syscall 'rmdir "/tmp/tst-fs-cd")
close |
Type: Function |
root::close |
Usage: (close file) |
Close a file.
Example:
(def tmp (get-temp))
(def tst-file (open (str tmp "/slsh-tst-open.txt") :create :truncate))
(write-line tst-file "Test Line Two")
(close tst-file)
(def tst-file (open (str tmp "/slsh-tst-open.txt") :read))
(test::assert-equal "Test Line Two
" (read-line tst-file))
(close tst-file)
collate-fs-changes |
Type: Lambda |
root::collate-fs-changes |
Usage: (collate-fs-changes file-or-dir-to-watch) |
Takes a file or directory to watch and returns a function that encloses the state of the file or directory (and all its contents). When the resultant function is called it returns a map whose keys are the types of change: :created , :deleted, and :modified and values are vectors of files subject to the change. Each invocation encloses the state of the previous invocation and can be called at any time to report change sets since the last invocation. sample return value: (make-hash ((:modified . #(“/tmp/collate-fs-changes”)) (:deleted . #()) (:created . #(“/tmp/collate-fs-changes/foo1.txt”))))
Example:
(defn test-collate (collate-test-dir)
(let* ((collate-test-file0 (get-temp-file collate-test-dir))
(collator (collate-fs-changes collate-test-dir))
(collate-test-file1 (get-temp-file collate-test-dir))
(slp (sleep 100))
(changes (collator)))
(test::assert-equal (vec collate-test-file1) (hash-get changes :created))
(test::assert-equal (make-vec) (hash-get changes :deleted))
(let ((tst-file (open collate-test-file0 :truncate)))
(write-string tst-file "boop")
(flush tst-file)
(close tst-file))
(sleep 100)
(set! changes (collator))
(test::assert-equal (vec collate-test-file0) (hash-get changes :modified))
(test::assert-equal (make-vec) (hash-get changes :deleted))
(test::assert-equal (make-vec) (hash-get changes :created))
(fs-rm collate-test-dir)
(sleep 100)
(set! changes (collator))
(test::assert-equal (make-vec) (hash-get changes :created))
(test::assert-equal (make-vec) (hash-get changes :modified))
(let ((del-items (hash-get changes :deleted)))
(test::assert-equal 3 (length del-items))
(test::assert-includes collate-test-dir del-items)
(test::assert-includes collate-test-file0 del-items)
(test::assert-includes collate-test-file1 del-items))))
(with-temp (fn (tmp-dir)
(let ((a-dir (get-temp tmp-dir)))
(test-collate a-dir))))
flush |
Type: Function |
root::flush |
Usage: (flush file) |
Flush a file.
Example:
(def tmp (get-temp))
(def tst-file (open (str tmp \"/slsh-tst-open.txt\") :create :truncate))
(write-line tst-file \"Test Line Three\")
(flush tst-file)
(def tst-file (open (str tmp \"/slsh-tst-open.txt\") :read))
(test::assert-equal \"Test Line Three\n\" (read-line tst-file))
(close tst-file)
fs-accessed |
Type: Function |
root::fs-accessed |
Usage: (fs-accessed /path/to/file/or/dir) |
Returns the unix time file last accessed in ms.
Example:
(with-temp-file (fn (tmp)
(let ((tst-file (open tmp :read))
(last-acc (fs-accessed tmp)))
(close tst-file)
(let ((tst-file (open tmp :read)))
(test::assert-true (> (fs-accessed tmp) last-acc))
(close tst-file))))
fs-base |
Type: Function |
root::fs-base |
Usage: (fs-base /path/to/file/or/dir) |
Returns base name of file or directory passed to function.
Example:
(with-temp (fn (tmp)
(let ((tmp-file (temp-file tmp)))
(test::assert-equal (length \".tmp01234\") (length (fs-base tmp-file))))))
fs-crawl |
Type: Function |
root::fs-crawl |
Usage: (fs-crawl /path/to/file/or/dir (fn (x) (println "found path" x) [max-depth] |
[:follow-syms]) If a directory is provided the path is recursively searched and every file and directory is called as an argument to the provided function. If a file is provided the path is provided as an argument to the provided function. Takes two optional arguments (in any order) an integer, representing max depth to traverse if file is a directory, or the symbol, :follow-syms, to follow symbol links when traversing if desired.
Example:
(with-temp-file (fn (tmp-file)
(def cnt 0)
(fs-crawl tmp-file (fn (x)
(test::assert-equal (fs-base tmp-file) (fs-base x))
(set! cnt (+ 1 cnt))))
(test::assert-equal 1 cnt)))
(defn create-in (in-dir num-files visited)
(dotimes-i i num-files
(hash-set! visited (get-temp-file in-dir) nil)))
(defn create-dir (tmp-dir visited)
(let ((new-tmp (get-temp tmp-dir)))
(hash-set! visited new-tmp nil)
new-tmp))
(with-temp (fn (root-tmp-dir)
(let ((tmp-file-count 5)
(visited (make-hash)))
(def cnt 0)
(hash-set! visited root-tmp-dir nil)
(create-in root-tmp-dir tmp-file-count visited)
(let* ((tmp-dir (create-dir root-tmp-dir visited))
(new-files (create-in tmp-dir tmp-file-count visited))
(tmp-dir (create-dir tmp-dir visited))
(new-files (create-in tmp-dir tmp-file-count visited)))
(fs-crawl root-tmp-dir (fn (x)
(let ((file (hash-get visited x)))
(test::assert-true (not file)) ;; also tests double counting
(hash-set! visited x #t)
(set! cnt (+ 1 cnt)))))
(test::assert-equal (+ 3 (* 3 tmp-file-count)) cnt)
(test::assert-equal (+ 3 (* 3 tmp-file-count)) (length (hash-keys visited)))
(iterator::map (fn (x) (test::assert-true (hash-get visited y))) (hash-keys visited))))))
(with-temp (fn (root-tmp-dir)
(let ((tmp-file-count 5)
(visited (make-hash)))
(def cnt 0)
(hash-set! visited root-tmp-dir nil)
(create-in root-tmp-dir tmp-file-count visited)
(let* ((tmp-dir (create-dir root-tmp-dir visited))
(new-files (create-in tmp-dir tmp-file-count visited))
(tmp-dir (create-dir tmp-dir (make-hash)))
(new-files (create-in tmp-dir tmp-file-count (make-hash))))
(fs-crawl root-tmp-dir (fn (x)
(let ((file (hash-get visited x)))
(test::assert-true (not file)) ;; also tests double counting
(hash-set! visited x #t)
(set! cnt (+ 1 cnt)))) 2)
(test::assert-equal (+ 3 (* 2 tmp-file-count)) cnt)
(test::assert-equal (+ 3 (* 2 tmp-file-count)) (length (hash-keys visited)))
(iterator::map (fn (x) (test::assert-true (hash-get visited y))) (hash-keys visited))))))
(with-temp (fn (root-tmp-dir)
(let ((tmp-file-count 5)
(visited (make-hash)))
(def cnt 0)
(hash-set! visited root-tmp-dir nil)
(create-in root-tmp-dir tmp-file-count visited)
(let* ((tmp-dir (create-dir root-tmp-dir (make-hash)))
(new-files (create-in tmp-dir tmp-file-count (make-hash)))
(tmp-dir (create-dir tmp-dir (make-hash)))
(new-files (create-in tmp-dir tmp-file-count (make-hash))))
(fs-crawl root-tmp-dir (fn (x)
(let ((file (hash-get visited x)))
(test::assert-true (not file)) ;; also tests double counting
(hash-set! visited x #t)
(set! cnt (+ 1 cnt)))) 1)
(test::assert-equal (+ 2 tmp-file-count) cnt)
(test::assert-equal (+ 2 tmp-file-count) (length (hash-keys visited)))
(iterator::map (fn (x) (test::assert-true (hash-get visited y))) (hash-keys visited))))))
fs-dir? |
Type: Function |
root::fs-dir? |
Usage: (fs-dir? path-to-test) |
Is the given path a directory?
Example:
$(mkdir /tmp/tst-fs-dir)
$(touch /tmp/tst-fs-dir/fs-dir-file)
(test::assert-false (fs-dir? "/tmp/tst-fs-dir/fs-dir-file"))
(test::assert-true (fs-dir? "/tmp/tst-fs-dir"))
(test::assert-false (fs-dir? "/tmp/tst-fs-dir/fs-dir-nope"))
$(rm /tmp/tst-fs-dir/fs-dir-file)
$(rmdir /tmp/tst-fs-dir)
fs-exists? |
Type: Function |
root::fs-exists? |
Usage: (fs-exists? path-to-test) |
Does the given path exist?
Example:
$(mkdir /tmp/tst-fs-exists)
$(touch /tmp/tst-fs-exists/fs-exists)
(test::assert-true (fs-exists? "/tmp/tst-fs-exists/fs-exists"))
(test::assert-true (fs-exists? "/tmp/tst-fs-exists"))
(test::assert-false (fs-exists? "/tmp/tst-fs-exists/fs-exists-nope"))
$(rm /tmp/tst-fs-exists/fs-exists)
$(rmdir /tmp/tst-fs-exists)
fs-file? |
Type: Function |
root::fs-file? |
Usage: (fs-file? path-to-test) |
Is the given path a file?
Example:
$(mkdir /tmp/tst-fs-file)
$(touch "/tmp/tst-fs-file/fs-file")
(test::assert-true (fs-file? "/tmp/tst-fs-file/fs-file"))
(test::assert-false (fs-file? "/tmp/tst-fs-file"))
(test::assert-false (fs-file? "/tmp/tst-fs-file/fs-file-nope"))
$(rm "/tmp/tst-fs-file/fs-file")
$(rmdir /tmp/tst-fs-file)
fs-len |
Type: Function |
root::fs-len |
Usage: (fs-len /path/to/file/or/dir) |
Returns the size of the file in bytes.
Example:
(with-temp-file (fn (tmp)
(let ((tst-file (open tmp :create :truncate)))
(write-line tst-file \"Test Line Read Line One\")
(write-string tst-file \"Test Line Read Line Two\")
(flush tst-file)
(close tst-file)
(println \"fs-len is: \" (fs-len tst-file))
(test::assert-equal 47 (fs-len tst-file)))))
fs-modified |
Type: Function |
root::fs-modified |
Usage: (fs-modified /path/to/file/or/dir) |
Returns the unix time file last modified in ms.
Example:
(with-temp-file (fn (tmp)
(let ((tst-file (open tmp :create :truncate))
(last-mod (fs-modified tmp)))
(write-line tst-file \"Test Line Read Line One\")
(write-string tst-file \"Test Line Read Line Two\")
(flush tst-file)
(close tst-file)
(test::assert-true (> (fs-modified tmp) last-mod)))))
fs-notify |
Type: Lambda |
root::fs-notify |
Usage: (fs-notify callback to-watch &rest args) |
fs-notify is designed to notify the caller of changes to a file or directory heirarchy via a callback that accepts two arguments, the file that changed and the type of change: :created, :deleted, xor :modified. Takes a callback and file or directory to watch for changes and the number of milliseconds to sleep before checking for changes to the provided file/directory hierarchy. This function loops forever, and calls the callback whenever it detects a change. This function relies on the function collate-fs-changes to compute differences. The following invocation of fs-notify prints out every change event for the provided directory, polling every 250ms by default. (fs-notify (fn (f e) (println “file: “ f “, event: “ e)) “/dir/to/watch”) This incovation provides an optional arg to specify the polling rate in ms. (fs-notify (fn (f e) (println “file: “ f “, event: “ e)) “/dir/to/watch” 1000)
Example:
#t
fs-parent |
Type: Function |
root::fs-parent |
Usage: (fs-parent /path/to/file/or/dir) |
Returns base name of file or directory passed to function.
Example:
(with-temp (fn (tmp)
(let ((tmp-file (get-temp-file tmp)))
(test::assert-true (fs-same? (fs-parent tmp-file) tmp)))))
fs-rm |
Type: Function |
root::fs-rm |
Usage: (fs-rm \"/dir/or/file/to/remove\") |
Takes a file or directory as a string and removes it. Works recursively for directories.
Example:
(def fp nil)
(let* ((a-file (get-temp-file)))
(test::assert-true (fs-exists? a-file))
(set! fp a-file)
(fs-rm a-file)))
(test::assert-false (nil? fp))
(test::assert-false (fs-exists? fp))
fs-same? |
Type: Function |
root::fs-same? |
Usage: (fs-same? /path/to/file/or/dir /path/to/file/or/dir) |
Returns true if the two provided file paths refer to the same file or directory.
Example:
(with-temp-file (fn (tmp-file)
(test::assert-true (fs-same? tmp-file tmp-file)))
get-temp |
Type: Function |
root::get-temp |
Usage: (get-temp [\"/path/to/directory/to/use/as/base\" \"optional-prefix\" \"optional-suffix\" length]) |
Creates a directory inside of an OS specific temporary directory. See temp-dir for OS specific notes. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary file created. Defaults to prefix of ".tmp", no suffix, and five random characters.
Example:
(test::assert-true (str-contains (temp-dir) (get-temp)))
(with-temp (fn (tmp)
(let ((tmp-dir (get-temp tmp)))
(test::assert-true (str-contains tmp tmp-dir)))))
(with-temp (fn (tmp)
(let ((tmp-dir (get-temp tmp \"some-prefix\")))
(test::assert-true (str-contains tmp tmp-dir))
(test::assert-true (str-contains \"some-prefix\" tmp-dir)))))
(with-temp (fn (tmp)
(let ((tmp-dir (get-temp tmp \"some-prefix\" \"some-suffix\")))
(test::assert-true (str-contains tmp tmp-dir))
(test::assert-true (str-contains \"some-prefix\" tmp-dir))
(test::assert-true (str-contains \"some-suffix\" tmp-dir)))))
(with-temp (fn (tmp)
(let ((tmp-dir (get-temp tmp \"some-prefix\" \"some-suffix\" 6)))
(test::assert-true (str-contains tmp tmp-dir))
(test::assert-true (str-contains \"some-prefix\" tmp-dir))
(test::assert-true (str-contains \"some-suffix\" tmp-dir))
(test::assert-equal (length \"some-prefix012345some-suffix\") (length (fs-base tmp-dir))))))
get-temp-file |
Type: Function |
root::get-temp-file |
Usage: (get-temp-file [\"/path/to/directory/to/use/as/base\" \"optional-prefix\" \"optional-suffix\" length]) |
Returns name of file created inside temporary directory. Optionally takes a directory to use as the parent directory of the temporary file. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary files created. Defaults to prefix of ".tmp", no suffix, and five random characters.
Example:
(test::assert-true (str-contains (temp-dir) (get-temp-file)))
(with-temp (fn (tmp)
(let ((tmp-file (get-temp-file tmp)))
(test::assert-true (str-contains tmp tmp-file)))))
(with-temp (fn (tmp)
(let ((tmp-file (get-temp-file tmp \"some-prefix\")))
(test::assert-true (str-contains \"some-prefix\" tmp-file)))))
(with-temp (fn (tmp)
(let ((tmp-file (get-temp-file tmp \"some-prefix\" \"some-suffix\")))
(test::assert-true (str-contains \"some-prefix\" tmp-file))
(test::assert-true (str-contains \"some-suffix\" tmp-file)))))
(with-temp (fn (tmp)
(let ((tmp-file (get-temp-file tmp \"some-prefix\" \"some-suffix\" 10)))
(test::assert-true (str-contains \"some-prefix\" tmp-file))
(test::assert-true (str-contains \"some-suffix\" tmp-file))
(test::assert-equal (length \"some-prefix0123456789some-suffix\") (length (fs-base tmp-file))))))
glob |
Type: Function |
root::glob |
Usage: (glob /path/with/*) |
Takes a list/varargs of globs and return the list of them expanded.
Example:
(syscall 'mkdir "/tmp/tst-fs-glob")
(syscall 'touch "/tmp/tst-fs-glob/g1")
(syscall 'touch "/tmp/tst-fs-glob/g2")
(syscall 'touch "/tmp/tst-fs-glob/g3")
(test::assert-equal '("/tmp/tst-fs-glob/g1" "/tmp/tst-fs-glob/g2" "/tmp/tst-fs-glob/g3") (glob "/tmp/tst-fs-glob/*"))
(syscall 'rm "/tmp/tst-fs-glob/g1")
(syscall 'rm "/tmp/tst-fs-glob/g2")
(syscall 'rm "/tmp/tst-fs-glob/g3")
(syscall 'rmdir "/tmp/tst-fs-glob")
open |
Type: Function |
root::open |
Usage: (open filename option*) |
Open a file. Options are: :read :write :append :truncate :create :create-new :on-error-nil
Example:
(def tmp (get-temp))
(def test-open-f (open (str tmp "/slsh-tst-open.txt") :create :truncate))
(write-line test-open-f "Test Line One")
(close test-open-f)
(test::assert-equal "Test Line One
" (read-line (open (str tmp "/slsh-tst-open.txt"))))
read |
Type: Function |
root::read |
Usage: (read [file\|string]? end-exp?) -> expression |
Read a file or string and return the next object (symbol, string, list, etc). Raises an error if the file or string has been read unless end-exp is provided then returns that on the end condition. If no parameters are provided then read stdin.
Example:
(def tmp (get-temp))
(def tst-file (open (str tmp "/slsh-tst-open.txt") :create :truncate))
(write-line tst-file "(1 2 3)(x y z)")
;(write-string tst-file "Test Line Read Line Two")
(flush tst-file)
(def tst-file (open (str tmp "/slsh-tst-open.txt") :read))
(test::assert-equal '(1 2 3) (read tst-file))
(test::assert-equal '(x y z) (read tst-file))
(test::assert-error (read test-file))
(close tst-file)
(def tst-file (open (str tmp "/slsh-tst-open.txt") :read))
(test::assert-equal '(1 2 3) (read tst-file :done))
(test::assert-equal '(x y z) (read tst-file :done))
(test::assert-equal :done (read tst-file :done))
(close tst-file)
(test::assert-equal '(4 5 6) (read "(4 5 6)"))
(def test-str "7 8 9")
(test::assert-equal 7 (read test-str))
(test::assert-equal 8 (read test-str))
(test::assert-equal 9 (read test-str))
(test::assert-error (read test-str))
(def test-str "7 8 9")
(test::assert-equal 7 (read test-str :done))
(test::assert-equal 8 (read test-str :done))
(test::assert-equal 9 (read test-str :done))
(test::assert-equal :done (read test-str :done))
(test::assert-equal '(x y z) (read "(x y z)"))
read-all |
Type: Function |
root::read-all |
Usage: (read-all [file\|string]? empty-exp?) -> list\|vec\|empty-exp |
Read a file or string and return the list representation. This reads the entire file or string and will wrap in an outer vector if not a vector or list (always returns a vector or list). Unlike most lisp readers this one will put loose symbols in a list (i.e. you enter things at the repl without the enclosing parens). Note the file|string arg is optional, if not provided will read from stdin (or can provide stdin). If the read item is empty (including a comment) then raises an error or produces empty-exp if it is provided.
Example:
(def tmp (get-temp))
(def tst-file (open (str tmp "/slsh-tst-open.txt") :create :truncate))
(write-line tst-file "(1 2 3)(x y z)")
(flush tst-file)
(def tst-file (open (str tmp "/slsh-tst-open.txt") :read))
(test::assert-equal '#((1 2 3)(x y z)) (read-all tst-file))
(close tst-file)
(test::assert-equal '(4 5 6) (read-all "(4 5 6)"))
(test::assert-equal '(7 8 9) (read-all "7 8 9"))
(test::assert-equal '(x y z) (read-all "(x y z)" :not-used))
(test::assert-equal :empty (read-all ";(x y z)" :empty))
read-line |
Type: Function |
root::read-line |
Usage: (read-line file) -> string |
Read a line from a file.
Example:
(def tmp (get-temp))
(def tst-file (open (str tmp "slsh-tst-open.txt") :create :truncate))
(write-line tst-file "Test Line Read Line One")
(write-string tst-file "Test Line Read Line Two")
(flush tst-file)
(def tst-file (open (str tmp "slsh-tst-open.txt") :read))
(test::assert-equal "Test Line Read Line One
" (read-line tst-file))
(test::assert-equal "Test Line Read Line Two" (read-line tst-file))
(close tst-file)
temp-dir |
Type: Function |
root::temp-dir |
Usage: (temp-dir) |
Returns a string representing the temporary directory. See get-temp for higher level temporary directory creation mechanism. On Unix: Returns the value of the TMPDIR environment variable if it is set, otherwise for non-Android it returns /tmp. If Android, since there is no global temporary folder (it is usually allocated per-app), it returns /data/local/tmp. On Windows: Returns the value of, in order, the TMP, TEMP, USERPROFILE environment variable if any are set and not the empty string. Otherwise, temp_dir returns the path of the Windows directory. This behavior is identical to that of GetTempPath, which this function uses internally.
Example:
(test::assert-true (fs-dir? (temp-dir)))
with-temp |
Type: Function |
root::with-temp |
Usage: (with-temp (fn (x) (println \"given temp dir:\" x)) [\"optional-prefix\" \"optional-suffix\" length]) |
Takes a function that accepts a temporary directory. This directory will be recursively removed when the provided function is finished executing. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary directory created. Defaults to prefix of ".tmp", no suffix, and five random characters.
Example:
(def fp nil)
(with-temp (fn (tmp-dir)
(let* ((tmp-file (str tmp-dir \"/sl-sh-tmp-file.txt\"))
(a-file (open tmp-file :create :truncate)))
(test::assert-true (fs-exists? tmp-file))
(set! fp tmp-file)
(close a-file))))
(test::assert-false (nil? fp))
(test::assert-false (fs-exists? fp))
(with-temp
(fn (tmp)
(test::assert-true (str-contains \"some-prefix\" tmp)))
\"some-prefix\")
(with-temp
(fn (tmp)
(test::assert-true (str-contains \"some-prefix\" tmp))
(test::assert-true (str-contains \"some-suffix\" tmp)))
\"some-prefix\"
\"some-suffix\")
(with-temp
(fn (tmp)
(test::assert-true (str-contains \"some-prefix\" tmp))
(test::assert-true (str-contains \"some-suffix\" tmp))
(test::assert-equal (length \"some-prefix0123456789some-suffix\") (length (fs-base tmp))))
\"some-prefix\"
\"some-suffix\"
10)
with-temp-file |
Type: Function |
root::with-temp-file |
Usage: (with-temp-file (fn (x) (println \"given temp file:\" x)) [\"optional-prefix\" \"optional-suffix\" length]) |
Takes a function that accepts a temporary file. This file will be removed when the provided function is finished executing. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary file created. Defaults to prefix of ".tmp", no suffix, and five random characters.
Example:
(def fp nil)
(with-temp-file (fn (tmp-file)
(let* ((a-file (open tmp-file :create :truncate)))
(test::assert-true (fs-exists? tmp-file))
(set! fp tmp-file)
(close a-file))))
(test::assert-false (nil? fp))
(test::assert-false (fs-exists? fp))
(with-temp-file
(fn (tmp)
(test::assert-true (str-contains \"some-prefix\" tmp)))
\"some-prefix\")
(with-temp-file
(fn (tmp)
(test::assert-true (str-contains \"some-prefix\" tmp))
(test::assert-true (str-contains \"some-suffix\" tmp)))
\"some-prefix\"
\"some-suffix\")
(with-temp-file
(fn (tmp)
(test::assert-true (str-contains \"some-prefix\" tmp))
(test::assert-true (str-contains \"some-suffix\" tmp))
(test::assert-equal (length \"some-prefix0123456789some-suffix\") (length (fs-base tmp))))
\"some-prefix\"
\"some-suffix\"
10)
write-line |
Type: Function |
root::write-line |
Usage: (write-line file string) |
Write a line to a file.
Example:
(def tmp (get-temp))
(def tst-file (open (str tmp "/slsh-tst-open.txt") :create :truncate))
(write-line tst-file "Test Line Write Line")
(flush tst-file)
(def tst-file (open (str tmp "/slsh-tst-open.txt") :read))
(test::assert-equal "Test Line Write Line
" (read-line tst-file))
(close tst-file)
write-string |
Type: Function |
root::write-string |
Usage: (write-string file string) |
Write a string to a file.
Example:
(def tmp (get-temp))
(def tst-file (open (str tmp "/slsh-tst-open.txt") :create :truncate))
(write-string tst-file "Test Line Write Line")
(flush tst-file)
(def tst-file (open (str tmp "/slsh-tst-open.txt") :read))
(test::assert-equal "Test Line Write Line" (read-line tst-file))
(close tst-file)
Globals forms
In sl-sh global symbols (made by ‘def) are wrapped in earmuffs like in common lisp. Some of these symbols contain information used by the standard library and may be useful to end users, while others are intended for use in scripting.
*last-command* |
Type: String |
root::*last-command* |
Namespace: root
last run command by sl-sh on repl
*last-status* |
Type: Int |
root::*last-status* |
Namespace: root
Return code of last run sl-sh command on the repl
*repl-settings* |
Type: HashMap |
root::*repl-settings* |
Namespace: root
hash map of repl settings
*std-lib-namespaces* |
Type: Vector |
root::*std-lib-namespaces* |
Namespace: root
vector of all namespaces present in sl-sh by default
*std-lib-syms-hash* |
Type: HashMap |
root::*std-lib-syms-hash* |
Namespace: root
vector of all symbols in sl-sh-standard library
Hashmap forms
hash-clear! |
Type: Function |
root::hash-clear! |
Usage: (hash-clear! hashmap) |
Clears a hashmap. This is a destructive form!
Example:
(def tst-hash (make-hash '((:key1 . \"val one\")(key2 . \"val two\")(\"key3\" . \"val three\")(#\\S . \"val S\"))))
(test::assert-equal 4 (length (hash-keys tst-hash)))
(test::assert-true (hash-haskey tst-hash :key1))
(test::assert-true (hash-haskey tst-hash 'key2))
(test::assert-true (hash-haskey tst-hash \"key3\"))
(test::assert-true (hash-haskey tst-hash #\\S))
(hash-clear! tst-hash)
(test::assert-equal 0 (length (hash-keys tst-hash)))
(test::assert-false (hash-haskey tst-hash :key1))
(test::assert-false (hash-haskey tst-hash 'key2))
(test::assert-false (hash-haskey tst-hash \"key3\"))
(test::assert-false (hash-haskey tst-hash #\\S))
hash-get |
Type: SpecialForm |
root::hash-get |
Usage: (hash-get hashmap key default?) -> value |
Get a value for a key from a hashmap. If the optional default is provided and the key is not in the hash then evaluate and return it. NOTE: default will only be evaluted if it is used.
Example:
(def tst-hash (make-hash '((:key1 . "val one")(key2 . "val two")("key3" . "val three")(#\S . "val S"))))
(test::assert-equal 4 (length (hash-keys tst-hash)))
(test::assert-equal "val one" (hash-get tst-hash :key1))
(test::assert-equal "val two" (hash-get tst-hash 'key2))
(test::assert-equal "val three" (hash-get tst-hash "key3"))
(test::assert-equal "val S" (hash-get tst-hash #\S))
(test::assert-equal "default" (hash-get tst-hash :not-here "default"))
(test::assert-equal "string default" (hash-get tst-hash :not-here (str "string " "default")))
hash-haskey |
Type: Function |
root::hash-haskey |
Usage: (hash-haskey hashmap key) |
Checks if a key is in a hashmap.
Example:
(def tst-hash (make-hash '((:key1 . \"val one\")(key2 . \"val two\")(\"key3\" . \"val three\")(#\\S . \"val S\"))))
(test::assert-equal 4 (length (hash-keys tst-hash)))
(test::assert-true (hash-haskey tst-hash :key1))
(test::assert-true (hash-haskey tst-hash 'key2))
(test::assert-true (hash-haskey tst-hash \"key3\"))
(test::assert-true (hash-haskey tst-hash #\\S))
(test::assert-false (hash-haskey tst-hash 'key1))
(test::assert-false (hash-haskey tst-hash :key2))
(test::assert-false (hash-haskey tst-hash \"keynone\"))
(hash-remove! tst-hash :key1)
(test::assert-false (hash-haskey tst-hash :key1))
(hash-set! tst-hash :key1 \"val one b\")
(test::assert-true (hash-haskey tst-hash :key1))
hash-keys |
Type: Function |
root::hash-keys |
Usage: (hash-keys hashmap) |
Returns a vector of all the hashmaps keys. The keys will be unordered.
Example:
(def tst-hash (make-hash '((:key1 . \"val one\")(key2 . \"val two\")(\"key3\" . \"val three\")(#\\S . \"val S\"))))
(test::assert-equal 4 (length (hash-keys tst-hash)))
(test::assert-true (in? (hash-keys tst-hash) :key1) \" Test :key1\")
(test::assert-true (in? (hash-keys tst-hash) 'key2) \" Test key2\")
; Note string or char used as a key will be a symbol in the hash-keys list...
(test::assert-true (in? (hash-keys tst-hash) 'S) \" Test S\")
(test::assert-true (in? (hash-keys tst-hash) 'key3) \" Test key3\")
(test::assert-false (in? (hash-keys tst-hash) :key4))
hash-remove! |
Type: Function |
root::hash-remove! |
Usage: (hash-remove! hashmap key) |
Remove a key from a hashmap. This is a destructive form!
Example:
(def tst-hash (make-hash '((:key1 . \"val one\")(key2 . \"val two\")(\"key3\" . \"val three\")(#\\S . \"val S\"))))
(test::assert-equal 4 (length (hash-keys tst-hash)))
(test::assert-equal \"val one\" (hash-get tst-hash :key1))
(test::assert-equal \"val two\" (hash-get tst-hash 'key2))
(test::assert-equal \"val three\" (hash-get tst-hash \"key3\"))
(test::assert-equal \"val S\" (hash-get tst-hash #\\S))
(hash-remove! tst-hash 'key2)
(test::assert-equal 3 (length (hash-keys tst-hash)))
(test::assert-equal \"val one\" (hash-get tst-hash :key1))
(test::assert-equal \"val three\" (hash-get tst-hash \"key3\"))
(test::assert-equal \"val S\" (hash-get tst-hash #\\S))
(hash-remove! tst-hash :key1)
(test::assert-equal 2 (length (hash-keys tst-hash)))
(test::assert-equal \"val three\" (hash-get tst-hash \"key3\"))
(test::assert-equal \"val S\" (hash-get tst-hash #\\S))
(hash-remove! tst-hash \"key3\")
(test::assert-equal 1 (length (hash-keys tst-hash)))
(test::assert-equal \"val S\" (hash-get tst-hash #\\S))
(hash-remove! tst-hash #\\S)
(test::assert-equal 0 (length (hash-keys tst-hash)))
hash-set! |
Type: Function |
root::hash-set! |
Usage: (hash-set! hashmap key value) |
Add or update a hashmap key’s value. This is a destructive form!
Example:
(def tst-hash (make-hash))
(test::assert-equal 0 (length (hash-keys tst-hash)))
(hash-set! tst-hash :new-key '(1 2 3))
(test::assert-equal 1 (length (hash-keys tst-hash)))
(test::assert-equal '(1 2 3) (hash-get tst-hash :new-key))
(def tst-hash (make-hash '((:key1 . \"val one\")(key2 . \"val two\")(\"key3\" . \"val three\"))))
(test::assert-equal 3 (length (hash-keys tst-hash)))
(test::assert-equal \"val one\" (hash-get tst-hash :key1))
(test::assert-equal \"val two\" (hash-get tst-hash 'key2))
(test::assert-equal \"val three\" (hash-get tst-hash \"key3\"))
(hash-set! tst-hash :new-key '(1 2 3))
(test::assert-equal 4 (length (hash-keys tst-hash)))
(test::assert-equal \"val one\" (hash-get tst-hash :key1))
(test::assert-equal \"val two\" (hash-get tst-hash 'key2))
(test::assert-equal \"val three\" (hash-get tst-hash \"key3\"))
(test::assert-equal '(1 2 3) (hash-get tst-hash :new-key))
(hash-set! tst-hash 'key2 \"val two b\")
(hash-set! tst-hash :key1 \"val one b\")
(hash-set! tst-hash \"key3\" \"val three b\")
(test::assert-equal 4 (length (hash-keys tst-hash)))
(test::assert-equal \"val one b\" (hash-get tst-hash :key1))
(test::assert-equal \"val two b\" (hash-get tst-hash 'key2))
(test::assert-equal \"val three b\" (hash-get tst-hash \"key3\"))
(test::assert-equal '(1 2 3) (hash-get tst-hash :new-key))
make-hash |
Type: Function |
root::make-hash |
Usage: (make-hash associations?) |
Make a new hash map. If associations is provided (makes an empty map if not) then it is a list of pairs (key . value) that populate the intial map. Neither key nor value in the associations will be evaluated.
Example:
(def tst-hash (make-hash))
(test::assert-equal 0 (length (hash-keys tst-hash)))
(def tst-hash (make-hash ()))
(test::assert-equal 0 (length (hash-keys tst-hash)))
(def tst-hash (make-hash nil))
(test::assert-equal 0 (length (hash-keys tst-hash)))
(def tst-hash (make-hash '((:key1 . \"val one\")(key2 . \"val two\")(\"key3\" . \"val three\"))))
(test::assert-equal 3 (length (hash-keys tst-hash)))
(test::assert-equal \"val one\" (hash-get tst-hash :key1))
(test::assert-equal \"val two\" (hash-get tst-hash 'key2))
(test::assert-equal \"val three\" (hash-get tst-hash \"key3\"))
(def tst-hash (make-hash '#((:keyv1 . \"val one\")(keyv2 . \"val two\")(\"keyv3\" . \"val three\"))))
(test::assert-equal 3 (length (hash-keys tst-hash)))
(test::assert-equal \"val one\" (hash-get tst-hash :keyv1))
(test::assert-equal \"val two\" (hash-get tst-hash 'keyv2))
(test::assert-equal \"val three\" (hash-get tst-hash \"keyv3\"))
; Not in test below that tst-hash-val is NOT evaluated so the symbol is the value.
(def tst-hash-val \"some val\")
(def tst-hash (make-hash '#((:keyv1 . \"val one\")(:keyv2 . \"val two\")(:keyv3 . tst-hash-val))))
(test::assert-equal 3 (length (hash-keys tst-hash)))
(test::assert-equal \"val one\" (hash-get tst-hash :keyv1))
(test::assert-equal \"val two\" (hash-get tst-hash :keyv2))
(test::assert-equal 'tst-hash-val (hash-get tst-hash :keyv3))
Iterator forms
append |
Type: Lambda |
iterator::append |
Usage: (append first-iter &rest rest-iters) |
Combine the provided items into a single iterator (calls iter on each parameter). If non-list items are passed they are wrapped in a singleton iterator (i.e. will work with loose object). Note that nil is an empty list not a “loose item”.
Example:
(def test-iter (append '(0 1 2) '#(3 4 5) '(6 7 8 9)))
(assert-false (test-iter :empty?))
(assert-equal 10 (test-iter :count))
(assert-true (test-iter :empty?))
(def test-iter (append '(0 1 2) 3 4 5 '(6 7 8 9)))
(assert-false (test-iter :empty?))
(assert-equal 10 (test-iter :count))
(assert-true (test-iter :empty?))
(def test-iter (append 0 1 2 '(3 4)))
(assert-false (test-iter :empty?))
(assert-equal 0 (test-iter :next!))
(assert-equal 1 (test-iter :next!))
(assert-equal 2 (test-iter :next!))
(assert-equal 3 (test-iter :next!))
(assert-equal 4 (test-iter :next!))
(assert-true (test-iter :empty?))
(def test-iter (append 0 1 2 nil))
(assert-false (test-iter :empty?))
(assert-equal 0 (test-iter :next!))
(assert-equal 1 (test-iter :next!))
(assert-equal 2 (test-iter :next!))
(assert-true (test-iter :empty?))
(def test-iter (append 0 1 2 '(nil)))
(assert-false (test-iter :empty?))
(assert-equal 0 (test-iter :next!))
(assert-equal 1 (test-iter :next!))
(assert-equal 2 (test-iter :next!))
(assert-equal nil (test-iter :next!))
(assert-true (test-iter :empty?))
append-iter |
Type: Lambda |
iterator::append-iter |
Usage: (append-iter) |
Iterator that appends multiple iterators. Append iter will consume the iterators it is appending. If non-list items are passed they are wrapped in a singleton iterator (i.e. will work with loose object). attribute: iters private method: :next! method: :empty? method: :init impl iterator::iterator
Example:
(def test-iter ((iterator::append-iter) :init '(0 1 2) '#(3 4 5) '(6 7 8 9)))
(def test-slice-iter (test-iter :slice 3 7))
(assert-false (test-slice-iter :empty?))
(assert-equal 3 (test-slice-iter :next!))
(assert-equal 4 (test-slice-iter :next!))
(assert-equal 5 (test-slice-iter :next!))
(assert-equal 6 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-iter ((iterator::append-iter) :init '(0 1 2) nil '#(3 4 5) nil '(6 7 8 9)))
(def test-slice-iter (test-iter :slice 0 4))
(assert-false (test-slice-iter :empty?))
(assert-equal 0 (test-slice-iter :next!))
(assert-equal 1 (test-slice-iter :next!))
(assert-equal 2 (test-slice-iter :next!))
(assert-equal 3 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-iter ((iterator::append-iter) :init '(0 1 2) '#(3 4 5) '(6 7 8 9)))
(def test-slice-iter (test-iter :slice 7))
(assert-false (test-slice-iter :empty?))
(assert-equal 7 (test-slice-iter :next!))
(assert-equal 8 (test-slice-iter :next!))
(assert-equal 9 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-iter ((iterator::append-iter) :init '(0 1 2) '#(3 4 5) '(6 7 8 9)))
(assert-false (test-iter :empty?))
(assert-equal 10 (test-iter :count))
(assert-true (test-iter :empty?))
(def test-iter ((iterator::append-iter) :init '(0 1 2) '() '#(3 4 5) nil '(6 7 8 9)))
(assert-false (test-iter :empty?))
(assert-equal 10 (test-iter :count))
(assert-true (test-iter :empty?))
(def test-iter ((iterator::append-iter) :init nil '(0 1 2) (vec) '#(3 4 5) '(6 7 8 9) nil))
(assert-false (test-iter :empty?))
(assert-equal 10 (test-iter :count))
(assert-true (test-iter :empty?))
append-to! |
Type: Lambda |
iterator::append-to! |
Usage: (append-to! ret &rest others) |
Combine the provided items after the first (first must be a vector or list) into a single iterator. These values are added the first argument destructively. If non-list items are passed they are wrapped in a singleton iterator (i.e. will work with loose object). Note that nil is an empty list not a “loose item”.
Example:
(def test-iter '(0 1 2))
(append-to! test-iter '#(3 4 5) '(6 7 8 9))
(set! test-iter (iter test-iter))
(def test-slice-iter (test-iter :slice 3 7))
(assert-false (test-slice-iter :empty?))
(assert-equal 3 (test-slice-iter :next!))
(assert-equal 4 (test-slice-iter :next!))
(assert-equal 5 (test-slice-iter :next!))
(assert-equal 6 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-iter '(0 1 2))
(append-to! test-iter '#(3 4 5) '(6 7 8 9))
(set! test-iter (iter test-iter))
(def test-slice-iter (test-iter :slice 0 4))
(assert-false (test-slice-iter :empty?))
(assert-equal 0 (test-slice-iter :next!))
(assert-equal 1 (test-slice-iter :next!))
(assert-equal 2 (test-slice-iter :next!))
(assert-equal 3 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-iter '(0 1 2))
(append-to! test-iter '#(3 4 5) '(6 7 8 9))
(set! test-iter (iter test-iter))
(def test-slice-iter (test-iter :slice 7))
(assert-false (test-slice-iter :empty?))
(assert-equal 7 (test-slice-iter :next!))
(assert-equal 8 (test-slice-iter :next!))
(assert-equal 9 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-iter '(0 1 2))
(append-to! test-iter '#(3 4 5) '(6 7 8 9))
(set! test-iter (iter test-iter))
(assert-false (test-iter :empty?))
(assert-equal 10 (test-iter :count))
(assert-true (test-iter :empty?))
(def test-iter nil)
(append-to! test-iter nil '(0 1 2) nil '#(3 4 5) '(6 7 8 9) nil)
(set! test-iter (iter test-iter))
(assert-false (test-iter :empty?))
(assert-equal 10 (test-iter :count))
(assert-true (test-iter :empty?))
(def test-iter (vec 0))
(append-to! test-iter nil '#(1) '(2 3) nil)
(set! test-iter (iter test-iter))
(assert-false (test-iter :empty?))
(assert-equal 0 (test-iter :next!))
(assert-equal 1 (test-iter :next!))
(assert-equal 2 (test-iter :next!))
(assert-equal 3 (test-iter :next!))
(assert-true (test-iter :empty?))
collect |
Type: Lambda |
iterator::collect |
Usage: (collect s) |
Collect all the values into a list. This will consume the iterator and produce a new list. Will call iter on input to turn a collection into an iterator.
Example:
(def collect-test (iterator::collect '#(1 2 3)))
(assert-true (list? collect-test))
(assert-equal '(1 2 3) collect-test)
collect-str |
Type: Lambda |
iterator::collect-str |
Usage: (collect-str s) |
Collect all the values into a string. This will consume the iterator and produce a new string. Will call iter on input to turn a collection into an iterator.
Example:
(def collect-str-test (iterator::collect-str (iterator::map (fn (ch) (char-upper ch)) "λabc σ")))
(assert-true (string? collect-str-test))
(assert-equal "ΛABC Σ" collect-str-test)
collect-vec |
Type: Lambda |
iterator::collect-vec |
Usage: (collect-vec s) |
Collect all the values into a vector. This will consume the iterator and produce a new vector. Will call iter on input to turn a collection into an iterator.
Example:
(def collect-vec-test (iterator::collect-vec '(1 2 3)))
(assert-true (vec? collect-vec-test))
(assert-equal '#(1 2 3) collect-vec-test)
double-ended-iter? |
Type: Lambda |
iterator::double-ended-iter? |
Usage: (double-ended-iter? thing) |
Return true if thing is an iterator and double ended, nil otherwise.
Example:
(struct::defstruct test-iter
; fields
(current 0)
; methods
(:fn next! (self) (do (def val current)(set! current (+ 1 current)) val))
(:fn empty? (self) (>= current 3))
(:impl iterator::iterator))
(assert-true (iterator::double-ended-iter? (iterator::iter '(1 2 3))))
(assert-false (iterator::double-ended-iter? '(1 2 3)))
(assert-false (iterator::double-ended-iter? (test-iter)))
double-ended-iterator |
Type: Lambda |
iterator::double-ended-iterator |
Usage: (defstruct iter (:fn next! (self)...)(:fn next-back! (self)...)(:fn empty? (self)...)(:impl iterator::iterator iterator::double-ended-iterator)) |
Trait that makes an iterator double ended (can get items from front and back. Requires a struct to define methods next-back! and implement iterator. Note that next! and next-back! can not cross, the iterator is empty when they meet. method: :nth-back! Consume the iterator until the nth element from the end and return it (0 based). Note that repeated called to nth-back! will return new data since it consumes the iterator. method: :reverse Produce an iterator that is the reverse of self.
Example:
(ns-import 'struct)
(ns-import 'iterator)
(defstruct test-double-iter
; fields
(current 0)
(current-end 2)
; methods
(:fn next! (self) (do (var val current)(set! current (+ 1 current)) val))
(:fn next-back! (self) (do (var val current-end)(set! current-end (- current-end 1)) val))
(:fn empty? (self) (> current current-end))
(:impl iterator::iterator iterator::double-ended-iterator))
(def tmap (test-double-iter))
(assert-false (tmap :empty?))
(assert-equal 0 (tmap :next!))
(assert-equal 1 (tmap :next!))
(assert-equal 2 (tmap :next!))
(assert-true (tmap :empty?))
(def tmap (test-double-iter))
(assert-false (tmap :empty?))
(assert-equal 2 (tmap :next-back!))
(assert-equal 1 (tmap :next-back!))
(assert-equal 0 (tmap :next-back!))
(assert-true (tmap :empty?))
(def tmap (test-double-iter))
(assert-false (tmap :empty?))
(assert-equal 0 (tmap :next!))
(assert-equal 2 (tmap :next-back!))
(assert-equal 1 (tmap :next-back!))
(assert-true (tmap :empty?))
; :nth-back! Example
(def tmap ((vec-iter) :init '#(0 1 2 3 4) 0))
(assert-false (tmap :empty?))
(assert-equal 4 (tmap :nth-back! 0))
(assert-equal 3 (tmap :nth-back! 0))
(assert-equal 0 (tmap :nth-back! 2))
(assert-true (tmap :empty?))
; :reverse Example
(def tmap ((test-double-iter) :reverse))
(assert-false (tmap :empty?))
(assert-equal 2 (tmap :next!))
(assert-equal 1 (tmap :next!))
(assert-equal 0 (tmap :next!))
(assert-true (tmap :empty?))
empty? |
Type: Lambda |
iterator::empty? |
Usage: (empty? s) |
Is an iterator empty (no more items)? Will call iter on input first.
Example:
(assert-true (iterator::empty? nil))
(assert-true (iterator::empty? '#()))
(assert-false (iterator::empty? '#(1)))
file-iter |
Type: Lambda |
iterator::file-iter |
Usage: (file-iter) |
Iterator that wraps a file. Each call to next! returns the next line (with trailing newline. attribute: file private attribute: next-line private method: :next! method: :empty? method: :init impl iterator::iterator
Example:
(def tst-file (open "/tmp/file-iter-test.txt" :create :truncate))
(write-line tst-file "line 1")
(write-line tst-file "line 2")
(write-line tst-file "line 3")
(write-string tst-file "line 4")
(close tst-file)
(def test-iter ((iterator::file-iter) :init (open "/tmp/file-iter-test.txt")))
(assert-false (test-iter :empty?))
(assert-equal "line 1\n" (test-iter :next!))
(assert-equal "line 2\n" (test-iter :next!))
(assert-equal "line 3\n" (test-iter :next!))
(assert-equal "line 4" (test-iter :next!))
(assert-true (test-iter :empty?))
filter |
Type: Lambda |
iterator::filter |
Usage: (filter predicate items) |
Returns a filter-iter around items (will call iter on items). Iterator that applies a lambda to each element to determine if is returned- is lazy.
Example:
(def test-iter (iterator::filter (fn (x) (not (= x 2))) '(1 2 3)))
(assert-false (test-iter :empty?))
(assert-equal 1 (test-iter :next!))
(assert-equal 3 (test-iter :next!))
(assert-true (test-iter :empty?))
filter-iter |
Type: Lambda |
iterator::filter-iter |
Usage: (filter-iter) |
Iterator that applies a lambda to each element to determine if is returned- is lazy. attribute: data private attribute: predicate private attribute: next private attribute: is-empty private method: :next! method: :empty? method: :advance-data! method: :init impl iterator::iterator
Example:
(def test-iter (((iterator::list-iter) :init '(1 2 3)) :filter (fn (x) (not (= x 2)))))
(assert-false (test-iter :empty?))
(assert-equal 1 (test-iter :next!))
(assert-equal 3 (test-iter :next!))
(assert-true (test-iter :empty?))
for |
Type: Macro |
iterator::for |
Usage: (for bind in items body) |
Loops over each element in an iterator. Will call iter on the input object. bind is bound to the current element of items and is accesible in body. body is evaluated a number of times equal to the the number of items in in_list.
Example:
(def i 0)
(iterator::for x in (iterator::range 11) (set! i (+ 1 i)))
(assert-equal 11 i)
for-i |
Type: Macro |
iterator::for-i |
Usage: (for-i idx-bind bind in items body) |
Loops over each element in an iterator. Will call iter on the input object. idx-bind is bound to an incrementing number starting with 0. bind is bound to the current element of items and is accesible in body. body is evaluated a number of times equal to the the number of items in in_list.
Example:
(def i 0)
(def i-tot 0)
(for-i idx x in '(1 2 3 4 5 6 7 8 9 10 11) (do (set! i-tot (+ idx i-tot))(set! i (+ 1 i))))
(assert-equal 11 i)
(assert-equal 55 i-tot)
interleave |
Type: Lambda |
iterator::interleave |
Usage: (interleave fst scnd) |
interleaves two iterators together. Resultant iter is double length of fst unless scnd has less items. Then iter is double length of scnd.
Example:
(ns-import 'iterator)
(test::assert-equal (list 1 2 3 4) (collect (interleave (iter (list 1 3)) (iter (list 2 4)))))
(test::assert-equal (list 1 2 3 4) (collect (interleave (iter (list 1 3)) (iter (list 2 4 5)))))
interleave-iter |
Type: Lambda |
iterator::interleave-iter |
Usage: (interleave-iter) |
create iterator that interleaves two iterators together. Resultant iter is double length of fst if fst has less items, or double length of scnd if scnd has less items. attribute: fst private attribute: scnd private attribute: flip-flop private method: :next! method: :empty? method: :init impl iterator::iterator impl iterator::double-ended-iterator
Example:
iter |
Type: Lambda |
iterator::iter |
Usage: (iter thing) |
Return thing as an iterator if possible (if it is an iterator just return thing).
Example:
(assert-true (iterator::iter? (iterator::iter '(1 2 3))))
(assert-true (iterator::iter? (iterator::iter '#(1 2 3))))
(assert-true (iterator::iter? (iterator::iter "abc")))
(assert-true (iterator::iter? (iterator::iter (iterator::iter '(1 2 3)))))
iter? |
Type: Lambda |
iterator::iter? |
Usage: (iter? thing) |
Return true if thing is an iterator, nil otherwise.
Example:
(assert-true (iterator::iter? (iterator::iter '(1 2 3))))
(assert-false (iterator::iter? '(1 2 3)))
iterator |
Type: Lambda |
iterator::iterator |
Usage: (defstruct iter (:fn next! (self)...)(:fn empty? (self)...)(:impl iterator::iterator)) |
Trait that provides iterator methods. Requires a struct to define methods next! and empty? method: :collect Collect all the values into a list. This will consume the iterator and produce a new list. method: :collect-vec Collect all the values into a vector. This will consume the iterator and produce a new list. method: :collect-str Collect all the values into a string. This will consume the iterator and produce a new string. method: :map Apply the provided function to each element of the iterator. Map is lazy. method: :filter Apply the provided predicate to the iterator producing only elements that are true. Filter is lazy. method: :slice method: :count Consume the iterator and return the number of items. method: :nth! Consume the iterator until the nth! element and return it (0 based). Note that repeated called to nth! will return new data since it consumes the iterator. method: :double-ended? Return t if this iterator is double ended, nil otherwise.
Example:
(ns-import 'struct)
(ns-import 'iterator)
(defstruct test-iter
; fields
(current 0)
; methods
(:fn next! (self) (do (def val current)(set! current (+ 1 current)) val))
(:fn empty? (self) (>= current 3))
(:impl iterator::iterator))
(def tmap (test-iter))
(assert-false (tmap :empty?))
(assert-equal 0 (tmap :next!))
(assert-equal 1 (tmap :next!))
(assert-equal 2 (tmap :next!))
(assert-true (tmap :empty?))
; :collect Example
(def collect-test ((iter '#(1 2 3)) :collect))
(assert-true (list? collect-test))
(assert-equal '(1 2 3) collect-test)
; :collect-vec Example
(def collect-vec-test ((iter '(1 2 3)) :collect-vec))
(assert-true (vec? collect-vec-test))
(assert-equal '#(1 2 3) collect-vec-test)
; :collect-str Example
(def collect-str-test (((iter "λabc σ") :map (fn (ch) (char-upper ch))) :collect-str))
(assert-true (string? collect-str-test))
(assert-equal "ΛABC Σ" collect-str-test)
; :map Example
(def tmap ((test-iter) :map (fn (x) (+ 1 x))))
(assert-false (tmap :empty?))
(assert-equal 1 (tmap :next!))
(assert-equal 2 (tmap :next!))
(assert-equal 3 (tmap :next!))
(assert-true (tmap :empty?))
; :filter Example
(def tmap ((test-iter) :filter (fn (x) (not (= x 1)))))
(assert-false (tmap :empty?))
(assert-equal 0 (tmap :next!))
(assert-equal 2 (tmap :next!))
(assert-true (tmap :empty?))
; :count Example
(def tmap (test-iter))
(assert-false (tmap :empty?))
(assert-equal 3 (tmap :count))
(assert-true (tmap :empty?))
; :nth! Example
(def tmap ((list-iter) :init '(0 1 2 3 4)))
(assert-false (tmap :empty?))
(assert-equal 0 (tmap :nth! 0))
(assert-equal 1 (tmap :nth! 0))
(assert-equal 4 (tmap :nth! 2))
(assert-true (tmap :empty?))
; :double-ended? Example
(ns-import 'struct)
(ns-import 'iterator)
(defstruct test-double-iter
; fields
(current 0)
(current-end 2)
; methods
(:fn next! (self) (do (def val current)(set! current (+ 1 current)) val))
(:fn next-back! (self) (do (def val current-end)(set! current-end (- current-end 1)) val))
(:fn empty? (self) (> current current-end))
(:impl iterator::iterator iterator::double-ended-iterator))
(assert-false ((test-iter) :double-ended?))
(assert-true ((test-double-iter) :double-ended?))
list-iter |
Type: Lambda |
iterator::list-iter |
Usage: (list-iter) |
Iterator that wraps a list. attribute: data private attribute: rev-data private attribute: elements private method: :next! method: :next-back! method: :empty? method: :init method: :make-rev impl iterator::iterator impl iterator::double-ended-iterator
Example:
(def test-list-iter ((list-iter) :init '(1 2 3)))
(assert-false (test-list-iter :empty?))
(assert-equal 1 (test-list-iter :next!))
(assert-equal 2 (test-list-iter :next!))
(assert-equal 3 (test-list-iter :next!))
(assert-true (test-list-iter :empty?))
(def test-list-iter ((list-iter) :init '(1 2 3)))
(assert-false (test-list-iter :empty?))
(assert-equal 1 (test-list-iter :next!))
(assert-equal 3 (test-list-iter :next-back!))
(assert-equal 2 (test-list-iter :next!))
(assert-true (test-list-iter :empty?))
(def test-list-iter ((list-iter) :init '(1 2 3)))
(assert-false (test-list-iter :empty?))
(assert-equal 3 (test-list-iter :next-back!))
(assert-equal 2 (test-list-iter :next-back!))
(assert-equal 1 (test-list-iter :next-back!))
(assert-true (test-list-iter :empty?))
map |
Type: Lambda |
iterator::map |
Usage: (map map-fn items) |
Returns a map-iter around items (will call iter on items). Apply the provided function to each element of the iterator. Map is lazy.
Example:
(def tmap (iterator::map (fn (x) (+ 1 x)) '(0 1 2)))
(assert-false (tmap :empty?))
(assert-equal 1 (tmap :next!))
(assert-equal 2 (tmap :next!))
(assert-equal 3 (tmap :next!))
(assert-true (tmap :empty?))
(def tmap (iterator::reverse (iterator::map (fn (x) (+ 1 x)) '(0 1 2))))
(assert-false (tmap :empty?))
(assert-equal 3 (tmap :next!))
(assert-equal 2 (tmap :next!))
(assert-equal 1 (tmap :next!))
(assert-true (tmap :empty?))
map-iter |
Type: Lambda |
iterator::map-iter |
Usage: (map-iter) |
Iterator that applies a lambda to each element of another iterator- is lazy. attribute: data private attribute: map-fn private method: :next! method: :next-back! method: :empty? method: :init method: :double-ended? impl iterator::iterator impl iterator::double-ended-iterator
Example:
(def test-map-iter (((iterator::list-iter) :init '(1 2 3)) :map (fn (x) (* x 2))))
(assert-false (test-map-iter :empty?))
(assert-equal 2 (test-map-iter :next!))
(assert-equal 4 (test-map-iter :next!))
(assert-equal 6 (test-map-iter :next!))
(assert-true (test-map-iter :empty?))
meld |
Type: Lambda |
iterator::meld |
Usage: (meld fst scnd) |
melds two iterators together. Resultant iter is composed of pairs (fst, scnd) for each value of next! in each provided iterator. Length of returned iter is equal to length of the shortest provided iterator.
Example:
(ns-import 'iterator)
(test::assert-equal (list (join 'string 'bean) (join 'monte 'carlo)) (collect (meld (iter (list 'string 'monte)) (iter (list 'bean 'carlo)))))
(test::assert-equal (list (join 1 2) (join 3 4)) (collect (meld (iter (list 1 3)) (iter (list 2 4 5)))))
meld-iter |
Type: Lambda |
iterator::meld-iter |
Usage: (meld-iter) |
create iterator that melds two iterators together. Resultant iter is composed of pairs (fst, scnd) for each value of next! in each provided iterator. Length of meld-iter is equal to length of shorter iterator. attribute: fst private attribute: scnd private attribute: flip-flop private method: :next! method: :empty? method: :init impl iterator::iterator impl iterator::double-ended-iterator
Example:
next! |
Type: Lambda |
iterator::next! |
Usage: (next! s) |
Calls iter on s and returns the next item.
Example:
(assert-equal 1 (iterator::next! '(1 2 3)))
(assert-equal 1 (iterator::next! '#(1 2 3)))
(def next-test (iterator::iter '(4 5 6)))
(assert-equal 4 (iterator::next! next-test))
(assert-equal 5 (iterator::next! next-test))
(assert-equal 6 (iterator::next! next-test))
(assert-true (next-test :empty?))
nth |
Type: Lambda |
iterator::nth |
Usage: (nth idx coll) |
Consume the iterator until the idx (nth) element and return it (0 based). Note that repeated called to nth will return new data since it consumes the iterator.
Example:
(def tmap ((list-iter) :init '(0 1 2 3 4)))
(assert-false (tmap :empty?))
(assert-equal 0 (nth 0 tmap))
(assert-equal 1 (nth 0 tmap))
(assert-equal 4 (nth 2 tmap))
(assert-true (tmap :empty?))
range |
Type: Lambda |
iterator::range |
Usage: (range &rest i) |
Create an iterator that generates numbers within a range. Can be called with one int (n) to produce 0..(n-1) or with two ints (m, n) to produce m..n.
Example:
(def test-iter (iterator::range 3 6))
(assert-false (test-iter :empty?))
(assert-equal 3 (test-iter :next!))
(assert-equal 4 (test-iter :next!))
(assert-equal 5 (test-iter :next!))
(assert-equal 6 (test-iter :next!))
(assert-true (test-iter :empty?))
(def test-iter (iterator::range 3))
(assert-false (test-iter :empty?))
(assert-equal 0 (test-iter :next!))
(assert-equal 1 (test-iter :next!))
(assert-equal 2 (test-iter :next!))
(assert-true (test-iter :empty?))
range-iter |
Type: Lambda |
iterator::range-iter |
Usage: (range-iter) |
Iterator that generates numbers within a range. attribute: start private attribute: end private method: :next! method: :next-back! method: :empty? method: :init method: :count impl iterator::iterator impl iterator::double-ended-iterator
Example:
(def test-iter ((range-iter) :init 3 6))
(assert-false (test-iter :empty?))
(assert-equal 3 (test-iter :next!))
(assert-equal 4 (test-iter :next!))
(assert-equal 5 (test-iter :next!))
(assert-equal 6 (test-iter :next!))
(assert-true (test-iter :empty?))
(def test-iter ((range-iter) :init 3 6))
(assert-false (test-iter :empty?))
(assert-equal 6 (test-iter :next-back!))
(assert-equal 5 (test-iter :next-back!))
(assert-equal 4 (test-iter :next-back!))
(assert-equal 3 (test-iter :next-back!))
(assert-true (test-iter :empty?))
reduce |
Type: Lambda |
iterator::reduce |
Usage: (reduce reducing-fcn init-val coll) |
reduce is used to amalgamate a provided iterator, coll, and an intitial value, according to the reducing function provided. The iter function will be called on coll to make sure it is an iterator. The reducing-fcn should be a function of two arguments. In the first iteration of reduce, the init-val will be used as the first argument to the reducing-fcn and (next! coll) will be used as the second argument. For all subsequent iterations, The result from the previous application of the reducing-fcn will be used as the first argument to the reducing-fcn and the second argument will be the next item in the collection when the collection is empty reduce will return the amalgamated result.
Example:
(assert-true (= 15 (reduce + 0 (list 1 2 3 4 5))))
(assert-false (= 15 (reduce + 1 (list 1 2 3 4 5))))
(assert-true (= "one hoopy frood" (reduce str "" (list "one " "hoopy " "frood"))))
reduce-times |
Type: Lambda |
iterator::reduce-times |
Usage: (reduce-times value wrapping-fcn times) |
Apply wrapping-fcn to value number of times. Function is recursive. Recursive binding for value is previous application of wrapping function to value.
Example:
(assert-equal (list (list 3)) (reduce-times 3 list 2))
(assert-equal 5 (reduce-times (reduce-times 5 list 5) first 5))
repeat |
Type: Lambda |
iterator::repeat |
Usage: (repeat target &rest n) |
repeat target n times. if n is not provided returns infinite iterator.
Example:
(test::assert-equal (list #\m #\m #\m #\m) (collect (repeat #\m 4)))
(test::assert-equal (list #\m #\m #\m #\m) (collect (take (repeat #\m) 4)))
repeat-iter |
Type: Lambda |
iterator::repeat-iter |
Usage: (repeat-iter) |
iterator that returns provided repeat with specified length. if length is negative returns infinite iterator. attribute: to-repeat private attribute: len private attribute: current private method: :empty? method: :next! method: :init impl iterator::iterator
Example:
reverse |
Type: Lambda |
iterator::reverse |
Usage: (reverse items) |
Produce an iterator the is the reverse of items. Will call iter on items and requires a double ended iterator.
Example:
(def tmap (reverse ((vec-iter) :init '#(0 1 2) 0)))
(assert-false (tmap :empty?))
(assert-equal 2 (tmap :next!))
(assert-equal 1 (tmap :next!))
(assert-equal 0 (tmap :next!))
(assert-true (tmap :empty?))
(assert-error (reverse "string"))
reverse-iter |
Type: Lambda |
iterator::reverse-iter |
Usage: (reverse-iter) |
Iterator that reverses another iterators direction. Requires a double ended iterator. attribute: wrapped private method: :next! method: :next-back! method: :empty? method: :init impl iterator::iterator impl iterator::double-ended-iterator
Example:
(def test-iter (((vec-iter) :init '#(1 2 3) 0) :reverse))
(assert-false (test-iter :empty?))
(assert-equal 3 (test-iter :next!))
(assert-equal 2 (test-iter :next!))
(assert-equal 1 (test-iter :next!))
(assert-true (test-iter :empty?))
slice |
Type: Lambda |
iterator::slice |
Usage: (slice items start &rest end) |
Provides a slice of iterator. Will call iter on items. Slice iter will consume the iterator it is slicing.
Example:
(def test-slice-iter (slice '(0 1 2 3 4 5 6 7 8 9) 3 6))
(assert-false (test-slice-iter :empty?))
(assert-equal 3 (test-slice-iter :next!))
(assert-equal 4 (test-slice-iter :next!))
(assert-equal 5 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-slice-iter (slice '(0 1 2 3 4 5 6 7 8 9) 0 3))
(assert-false (test-slice-iter :empty?))
(assert-equal 0 (test-slice-iter :next!))
(assert-equal 1 (test-slice-iter :next!))
(assert-equal 2 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-slice-iter (slice '(0 1 2 3 4 5 6 7 8 9) 7))
(assert-false (test-slice-iter :empty?))
(assert-equal 7 (test-slice-iter :next!))
(assert-equal 8 (test-slice-iter :next!))
(assert-equal 9 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
slice-iter |
Type: Lambda |
iterator::slice-iter |
Usage: (slice-iter) |
Iterator that provides a slice of the underlying iter. Slice iter will consume the iterator it is slicing. attribute: data private attribute: start private attribute: total private attribute: count private method: :next! method: :empty? method: :init impl iterator::iterator
Example:
(def test-slice-iter (((iterator::list-iter) :init '(0 1 2 3 4 5 6 7 8 9)) :slice 3 6))
(assert-false (test-slice-iter :empty?))
(assert-equal 3 (test-slice-iter :next!))
(assert-equal 4 (test-slice-iter :next!))
(assert-equal 5 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-slice-iter (((iterator::list-iter) :init '(0 1 2 3 4 5 6 7 8 9)) :slice 0 3))
(assert-false (test-slice-iter :empty?))
(assert-equal 0 (test-slice-iter :next!))
(assert-equal 1 (test-slice-iter :next!))
(assert-equal 2 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
(def test-slice-iter (((iterator::list-iter) :init '(0 1 2 3 4 5 6 7 8 9)) :slice 7))
(assert-false (test-slice-iter :empty?))
(assert-equal 7 (test-slice-iter :next!))
(assert-equal 8 (test-slice-iter :next!))
(assert-equal 9 (test-slice-iter :next!))
(assert-true (test-slice-iter :empty?))
string-iter |
Type: Lambda |
iterator::string-iter |
Usage: (string-iter) |
Iterator that wraps a string. attribute: data private method: :next! method: :empty? method: :init impl iterator::iterator
Example:
(def test-string-iter ((string-iter) :init "123"))
(assert-false (test-string-iter :empty?))
(assert-equal #\1 (test-string-iter :next!))
(assert-equal #\2 (test-string-iter :next!))
(assert-equal #\3 (test-string-iter :next!))
(assert-true (test-string-iter :empty?))
take |
Type: Lambda |
iterator::take |
Usage: (take provided-iter n) |
return iterator with first n items of provided-iter. Returned iterator is the same as provided-iter if n is greater than the length of provided-iter.
Example:
(test::assert-equal (list #\m #\m) (collect (take (repeat #\m 4) 2)))
take-iter |
Type: Lambda |
iterator::take-iter |
Usage: (take-iter) |
take itertor attribute: provided-iter private attribute: len private attribute: current private method: :empty? method: :next! method: :init impl iterator::iterator
Example:
vec-iter |
Type: Lambda |
iterator::vec-iter |
Usage: (vec-iter) |
Iterator that wraps a vector. attribute: data private attribute: start private attribute: end private method: :next! method: :next-back! method: :empty? method: :nth! method: :nth-back! method: :init impl iterator::iterator impl iterator::double-ended-iterator
Example:
(def test-vec-iter ((vec-iter) :init '#(1 2 3) 0))
(assert-false (test-vec-iter :empty?))
(assert-equal 1 (test-vec-iter :next!))
(assert-equal 2 (test-vec-iter :next!))
(assert-equal 3 (test-vec-iter :next!))
(assert-true (test-vec-iter :empty?))
(def test-vec-iter ((vec-iter) :init (vec) 0))
(assert-true (test-vec-iter :empty?))
Logger forms
logger |
Type: Lambda |
root::logger |
Usage: (logger) |
logger struct
Initialize a logger object with a name and a log level that can be called
repeatedly to log to stdout. Supported log levels in order are :trace, :debug,
:info, :warn, :error, or :off. Calls to functions provided by struct are noops
unless that particular log level is enabled. To override the log level
specified in code set the environment variable SLSH_LOG_LEVEL to the desired
log level before initializing the struct.
Format is:
{unix time} {pid} {log level}: [{logger-name}] {log-string}
attribute: log-level private
attribute: log-level-int private
attribute: logger-name private
attribute: convert-log-level private
method: :get-log
method: :log-it
method: :trace
method: :debug
method: :info
method: :warn
method: :error
method: :init
Example:
(defn test-logger (log-name log-level)
(let ((a-logger ((logger) :init log-name log-level))
(str-list (list)))
(append-to! str-list (list (a-logger :get-log :trace (str "test log " log-level))))
(append-to! str-list (list (a-logger :get-log :debug (str "test log " log-level))))
(append-to! str-list (list (a-logger :get-log :info (str "test log " log-level))))
(append-to! str-list (list (a-logger :get-log :warn (str "test log " log-level))))
(append-to! str-list (list (a-logger :get-log :error (str "test log " log-level))))
(collect (filter (fn (x) (not (falsey? x))) str-list))))
(test::assert-equal 5 (length (test-logger "test-logger" :trace)))
(test::assert-equal 4 (length (test-logger "test-logger" :debug)))
(test::assert-equal 3 (length (test-logger "test-logger" :info)))
(test::assert-equal 2 (length (test-logger "test-logger" :warn)))
(test::assert-equal 1 (length (test-logger "test-logger" :error)))
(test::assert-equal 0 (length (test-logger "test-logger" :off)))
(test::assert-error-msg ((logger) :init "test-logger" :bad-log-level) "log level must be a symbol one of: :trace, :debug, :info, :warn, :error, or :off")
(test::assert-error-msg ((logger) :init 'bad-log-name :error) "in-logger-name must be a string.")
Math forms
% |
Type: Function |
root::% |
Usage: (% int int) |
Remainder from dividing first int by the second.
Example:
(ns-import 'math)
(test::assert-equal 0 (% 50 10))
(test::assert-equal 5 (% 55 10))
(test::assert-equal 1 (% 1 2))
(test::assert-error (%))
(test::assert-error (% 1))
(test::assert-error (% 1 2 3))
(test::assert-error (% 1 2.0))
* |
Type: Function |
root::* |
Usage: (* number*) |
Multiply a sequence of numbers. (*) will return 1.
Example:
(ns-import 'math)
(test::assert-equal 1 (*))
(test::assert-equal 5 (* 5))
(test::assert-equal 5 (* 1 5))
(test::assert-equal 5.0 (* 1.0 5))
(test::assert-equal 7.5 (* 1.5 5))
(test::assert-equal 7.5 (* 1.5 5.0))
(test::assert-equal 15 (* 3 5))
(test::assert-equal 8 (* 1 2 4))
(test::assert-equal 16 (* 2 2 4))
(test::assert-equal 16.0 (* 2 2.0 4))
(test::assert-equal 16.0 (* 2.0 2.0 4.0))
(test::assert-equal 55.0000000001 (* 100 0.55))
(test::assert-error (* 1 2 4 "5"))
*euler* |
Type: Float |
math::*euler* |
Usage: (print *e*) |
Float representing euler’s number.
Example:
(ns-import 'math)
(test::assert-equal 2.718281828459045 *e*)
*pi* |
Type: Float |
math::*pi* |
Usage: (print *pi*) |
Float representing pi.
Example:
(ns-import 'math)
(test::assert-equal 3.141592653589793 *pi*)
+ |
Type: Function |
root::+ |
Usage: (+ number*) |
Add a sequence of numbers. (+) will return 0.
Example:
(ns-import 'math)
(test::assert-equal 0 (+))
(test::assert-equal 5 (+ 5))
(test::assert-equal 5 (+ (values 5)))
(test::assert-equal 5 (+ (values 5 6)))
(test::assert-equal 10 (+ 5 (values 5 6)))
(test::assert-equal 5 (+ 5.0))
(test::assert-equal 6 (+ 1 5))
(test::assert-equal 6.5 (+ 1 5.5))
(test::assert-equal 7 (+ 1 2 4))
(test::assert-error (+ 1 2 4 "5"))
- |
Type: Function |
root::- |
Usage: (- number+) |
Subtract a sequence of numbers. Requires at least one number (negate if only one number).
Example:
(ns-import 'math)
(test::assert-error (-))
(test::assert-error (- 5 "2"))
(test::assert-equal -5 (- 5))
(test::assert-equal -5.0 (- 5.0))
(test::assert-equal -4 (- 1 5))
(test::assert-equal -4.5 (- 1 5.5))
(test::assert-equal 4 (- 10 2 4))
(test::assert-equal 4.9 (- 10.9 2 4))
/ |
Type: Function |
root::/ |
Usage: (/ number+) |
Divide a sequence of numbers. Requires at least two numbers.
Example:
(ns-import 'math)
(test::assert-equal 5 (/ 50 10))
(test::assert-equal 5 (/ 50.0 10.0))
(test::assert-equal 0 (/ 1 5))
(test::assert-equal .2 (/ 1.0 5))
(test::assert-equal .2 (/ 1.0 5.0))
(test::assert-equal 5.5 (/ 5.5 1))
(test::assert-equal 2 (/ 16 2 4))
(test::assert-equal 5 (/ 100 2 5 2))
(test::assert-error (/))
(test::assert-error (/ 1))
(test::assert-error (/ 1 0))
(test::assert-error (/ 10 5 0))
(test::assert-error (/ 10 "5" 2))
2pow |
Type: Function |
math::2pow |
Usage: (2pow base) |
Raise 2 to power of argument.
Example:
(ns-import 'math)
(test::assert-equal 1024 (2pow 10))
(test::assert-equal (2pow (* 10 2)) (pow (2pow 10) 2))
abs |
Type: Function |
math::abs |
Usage: (abs arg) |
Returns absolute value of arg.
Example:
(ns-import 'math)
(test::assert-equal 2.0 (abs 2))
(test::assert-equal 144 (abs -144))
(test::assert-equal 4.53 (abs -4.53))
arccos |
Type: Function |
math::arccos |
Usage: (arccos num) |
Take arccos of argument
Example:
(ns-import 'math)
(test::assert-equal 0.01 (cos (arccos 0.01)))
arcsin |
Type: Function |
math::arcsin |
Usage: (arcsin num) |
Take arcsin of argument
Example:
(ns-import 'math)
(test::assert-equal 0.01 (sin (arcsin 0.01)))
arctan |
Type: Function |
math::arctan |
Usage: (arctan num) |
Take arctan of argument
Example:
(ns-import 'math)
(test::assert-equal 0.01 (tan (arctan 0.01)))
ceil |
Type: Function |
math::ceil |
Usage: (ceil value) |
Returns smallest integer greater than or equal to value.
Example:
(ns-import 'math)
(test::assert-equal 2.0 (ceil 2))
(test::assert-equal 145 (ceil 144.444444))
(test::assert-equal 5 (ceil 4.53))
cos |
Type: Function |
math::cos |
Usage: (cos num) |
Take cos of argument
Example:
(ns-import 'math)
(test::assert-equal -0.14550003380861354 (cos 8))
(test::assert-equal (cos 6) (/ (sin 6) (tan 6)))
exp |
Type: Function |
math::exp |
Usage: (exp num) |
Returns e ^ num, the exponential function.
Example:
(ns-import 'math)
(test::assert-equal *euler* (exp 1))
(test::assert-equal 1 (exp 0))
(test::assert-equal 42 (exp (lne 42)))
floor |
Type: Function |
math::floor |
Usage: (floor value) |
Returns largest integer less than or equal to value.
Example:
(ns-import 'math)
(test::assert-equal 2.0 (floor 2))
(test::assert-equal 144 (floor 144.444444))
(test::assert-equal 4 (floor 4.53))
fract |
Type: Function |
math::fract |
Usage: (fract num) |
Returns fractional part of a number
Example:
(ns-import 'math)
(test::assert-equal 0.9893582466233818 (fract 1911.9893582466233818))
(test::assert-equal 0.0 (fract 1911))
lne |
Type: Function |
math::lne |
Usage: (lne num) |
Returns natural logarithm of number
Example:
(ns-import 'math)
(def x 7.0)
(def y 11.0)
(test::assert-equal 1 (lne *euler*))
(test::assert-equal 0 (lne 1))
(test::assert-equal (lne (* x y)) (+ (lne x) (lne y)))
(test::assert-equal (lne (/ x y)) (- (lne x) (lne y)))
(test::assert-equal (lne (pow x y)) (* y (lne x)))
log |
Type: Function |
math::log |
Usage: (log num base) |
Returns log of number given base.
Example:
(ns-import 'math)
(test::assert-equal 8 (log 256 2))
(test::assert-equal 3 (log 27 3))
(test::assert-equal (log (pow 8 2) 10) (* 2 (log 8 10)))
(test::assert-equal 1 (log 11 11))
(test::assert-equal '-inf (log 0 11))
(test::assert-equal (log 11 5) (/ (log 11 3) (log 5 3)))
log2 |
Type: Function |
math::log2 |
Usage: (log2 num) |
Returns log base 2 of input.
Example:
(ns-import 'math)
(test::assert-equal 7 (log2 128))
(test::assert-equal (log 7 2) (/ 1.0 (log 2 7)))
pow |
Type: Function |
math::pow |
Usage: (pow base power) |
Raise first argument to power of second argument.
Example:
(ns-import 'math)
(test::assert-equal 16 (pow 4 2))
(test::assert-equal 10 (log (pow 2 10) 2))
(test::assert-equal (pow 8 15) (* (pow 8 10) (pow 8 5)))
(test::assert-equal (pow 100 3) (/ (pow 100 5) (pow 100 2)))
(test::assert-equal 1 (pow 85 0))
round |
Type: Function |
math::round |
Usage: (round arg) |
Round arg to nearest int value.
Example:
(ns-import 'math)
(test::assert-equal 2.0 (round 2))
(test::assert-equal 144 (round 144.444444))
(test::assert-equal 5 (round 4.53))
sin |
Type: Function |
math::sin |
Usage: (sin num) |
Take sin of argument
Example:
(ns-import 'math)
(test::assert-equal 0.9893582466233818 (sin 8))
(test::assert-equal (sin 6) (* (tan 6) (cos 6)))
sqrt |
Type: Function |
math::sqrt |
Usage: (sqrt num) |
Take square root of argument.
Example:
(ns-import 'math)
(test::assert-equal 2.0 (sqrt 4))
(test::assert-equal 2.04939015319192 (sqrt 4.2))
(test::assert-equal 12 (sqrt 144))
tan |
Type: Function |
math::tan |
Usage: (tan num) |
Take tan of argument
Example:
(ns-import 'math)
(test::assert-equal -6.799711455220379 (tan 8))
(test::assert-equal (tan 6) (/ (sin 6) (cos 6)))
to-degrees |
Type: Function |
math::to-degrees |
Usage: (to-degrees num) |
Convert degrees to radians.
Example:
(ns-import 'math)
(test::assert-equal 0 (- (to-degrees *pi*) 180))
to-radians |
Type: Function |
math::to-radians |
Usage: (to-radians num) |
Convert degrees to radians.
Example:
(ns-import 'math)
(test::assert-equal 0 (- *pi* (to-radians 180)))
Namespace forms
ns-auto-export |
Type: Macro |
root::ns-auto-export |
Usage: (ns-auto-export symbol) |
Macro that takes a symbol, the symbol of the current namespace, and writes an
ns-export statement that includes all symbols defined in the namespaces scope
that do not begin with the ‘-‘ symbol. This is a convenience method that allows
user to avoid enumerating all symbols while also introducing a mechanism to
exclude symbols from being excluded. Note, if using ns-auto-export, it is
not possible to export a symbol that is already defined in another namespace,
if said functionality is desired the symbol must be manually exported with
another ns-export statement; ns-auto-export can be used in conjunction with
ns-export.
ns-create |
Type: Function |
root::ns-create |
Usage: (ns-create namespace) |
Creates and enters a new a namespace (must evaluate to a string or symbol).
Example:
(ns-push 'test-ns-create)
(def test-ns-enter *ns*)
(ns-create 'ns-create-test-namespace)
(def test-symbol "testing")
(test::assert-equal "testing" test-symbol)
(ns-enter test-ns-create::test-ns-enter)
(test::assert-false (def? test-symbol))
(ns-pop)
#t
ns-enter |
Type: Function |
root::ns-enter |
Usage: (ns-enter namespace) |
Enters an existing namespace (must evaluate to a string or symbol).
Example:
(ns-push 'test-ns-enter)
(def test-ns-enter *ns*)
(ns-create 'ns-enter-test-namespace)
(def test-symbol "testing")
(test::assert-equal "testing" test-symbol)
(ns-enter test-ns-enter::test-ns-enter)
(test::assert-false (def? test-symbol))
(ns-enter 'ns-enter-test-namespace)
(test::assert-true (def? test-symbol))
(test::assert-equal "testing" test-symbol)
(ns-enter test-ns-enter::test-ns-enter)
(ns-pop)
#t
ns-exists? |
Type: Function |
root::ns-exists? |
Usage: (ns-exists? namespace) |
True if the supplied namespace exists (must evaluate to a string or symbol).
Example:
(test::assert-false (ns-exists? 'ns-exists-test-namespace))
(ns-push 'ns-exists-test-namespace)
(ns-pop)
(test::assert-true (ns-exists? 'ns-exists-test-namespace))
ns-export |
Type: Macro |
root::ns-export |
Usage: (ns-export symbol_or_sequence) |
Export a symbol or list of symbols to be imported into other namespaces.
ns-import |
Type: Macro |
root::ns-import |
Usage: (ns-import namespace) |
Import any symbols exported from namespace into the current namespace.
ns-list |
Type: Function |
root::ns-list |
Usage: (ns-list) |
Returns a vector of all namespaces.
Example:
(test::assert-not-includes "ns-list-test-namespace" (ns-list))
(ns-push 'ns-list-test-namespace)
(ns-pop)
(test::assert-includes "ns-list-test-namespace" (ns-list))
ns-pop |
Type: Macro |
root::ns-pop |
Usage: (ns-pop) |
Returns to the previous namespace saved in the last ns-push.
Example:
(def test-ns-pop *ns*)
(ns-push 'ns-pop-test-namespace)
(test::assert-equal "ns-pop-test-namespace" *active-ns*)
(ns-pop)
(test::assert-equal test-ns-pop *ns*)
ns-push |
Type: Macro |
root::ns-push |
Usage: (ns-push 'namespace) |
Pushes the current namespace on a stack for ns-pop and enters or creates namespace.
Example:
(def test-ns-push *ns*)
(ns-push 'ns-pop-test-namespace)
; *ns* will not be right...
(test::assert-equal "ns-pop-test-namespace" *active-ns*)
(ns-push 'ns-pop-test-namespace2)
(test::assert-equal "ns-pop-test-namespace2" *active-ns*)
(ns-pop)
(test::assert-equal "ns-pop-test-namespace" *active-ns*)
(ns-pop)
(test::assert-equal test-ns-push *ns*)
ns-symbols |
Type: Function |
root::ns-symbols |
Usage: (ns-symbols namespace) |
Returns the list of all symbols in namespace (must evaluate to a string or symbol).
Example:
(test::assert-includes 'loop (ns-symbols 'root))
(test::assert-not-includes 'dumb-symbol-xxx (ns-symbols 'root))
(test::assert-includes 'car (ns-symbols 'root))
Pair forms
Operations on the ‘Pair’ type (aka Cons Cell) that can be used to create traditional Lisp list structures. These are the default list structure and are produced with bare parentheses in code. These lists can also be created by building them up with joins or with the list form.
car |
Type: Function |
root::car |
Usage: (car pair) |
Return the car (first item) from a pair. If used on a proper list this will be the first element.
Example:
(def tst-pairs-two (list 'x 'y 'z))
(test::assert-equal 'x (car tst-pairs-two))
(test::assert-equal 10 (car '(10)))
(test::assert-equal 9 (car '(9 11 13)))
cdr |
Type: Function |
root::cdr |
Usage: (cdr pair) |
Return the cdr (second item) from a pair. If used on a proper list this will be the list minus the first element.
Example:
(def tst-pairs-three (list 'x 'y 'z))
(test::assert-equal '(y z) (cdr tst-pairs-three))
(test::assert-equal nil (cdr '(10)))
(test::assert-equal '(13) (cdr '(9 13)))
(test::assert-equal '(11 13) (cdr '(9 11 13)))
join |
Type: Function |
root::join |
Usage: (join car cdr) |
Create a pair with the provided car and cdr.
Example:
(def tst-pair-one (join 1 2))
(test::assert-equal 1 (car tst-pair-one))
(test::assert-equal 2 (cdr tst-pair-one))
(test::assert-equal '(1 2 3) (join 1 (join 2 (join 3 nil))))
list |
Type: Function |
root::list |
Usage: (list item0 item1 .. itemN) |
Create a proper list from pairs with items 0 - N.
Example:
(test::assert-equal '(1 2 3) (list 1 2 3))
xar! |
Type: Function |
root::xar! |
Usage: (xar! pair expression) |
Destructive form that replaces the car (first item) in a pair with a new expression. If used on a proper list will replace the first item. Can be used on nil to create a pair (expression . nil).
Example:
(def tst-pairs-three (list 'x 'y 'z))
(test::assert-equal '(x y z) tst-pairs-three)
(test::assert-equal '(s y z) (xar! tst-pairs-three 's))
(test::assert-equal '(s y z) tst-pairs-three)
(def tst-pairs-four nil)
(test::assert-equal '() tst-pairs-four)
(test::assert-equal '(t) (xar! tst-pairs-four 't))
(test::assert-equal '(t) tst-pairs-four)
xdr! |
Type: Function |
root::xdr! |
Usage: (xdr! pair expression) |
Destructive form that replaces the cdr (second item) in a pair with a new expression. If used on a proper list will replace everthing after the first item. Can be used on nil to create a pair (nil . expression).
Example:
(def tst-pairs-five (list 'a 'b 'c))
(test::assert-equal '(a b c) tst-pairs-five)
(test::assert-equal '(a y z) (xdr! tst-pairs-five '(y z)))
(test::assert-equal '(a y z) tst-pairs-five)
(def tst-pairs-six nil)
(test::assert-equal '() tst-pairs-six)
(test::assert-equal '(nil . v) (xdr! tst-pairs-six 'v))
(test::assert-equal '(nil . v) tst-pairs-six)
Pair-ext forms
caaar |
Type: Lambda |
root::caaar |
Usage: (caaar lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal 1 (caaar '(((1 4) 5) (6 3) 2)))
caadr |
Type: Lambda |
root::caadr |
Usage: (caadr lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal 6 (caadr '((1 4 5) (6 3) 2)))
caar |
Type: Lambda |
root::caar |
Usage: (caar lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal 1 (caar '((1) 2 3)))
cadar |
Type: Lambda |
root::cadar |
Usage: (cadar lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal 4 (cadar '((1 4 5) (6 3) 2)))
cadddr |
Type: Lambda |
root::cadddr |
Usage: (cadddr lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal 6 (cadddr '((1 7 8) (4 5) 2 6 (3 9))))
caddr |
Type: Lambda |
root::caddr |
Usage: (caddr lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal 6 (caddr '((1 4 5) 2 6)))
cadr |
Type: Lambda |
root::cadr |
Usage: (cadr lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal 2 (cadr '(1 2 3)))
cdaar |
Type: Lambda |
root::cdaar |
Usage: (cdaar lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal '(7 8) (cdaar '(((1 7 8) 4 5) 2 (6 3))))
cdadr |
Type: Lambda |
root::cdadr |
Usage: (cdadr lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal '(9) (cdadr '(((1 7 8) 4 5) (2 9) (6 3))))
cdar |
Type: Lambda |
root::cdar |
Usage: (cdar lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal '(4 5) (cdar '((1 4 5) 2 3)))
cddar |
Type: Lambda |
root::cddar |
Usage: (cddar lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal '(5) (cddar '(((1 7 8) 4 5) 2 (6 3))))
cdddr |
Type: Lambda |
root::cdddr |
Usage: (cdddr lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal '(3 9) (cdddr '(((1 7 8) 4 5) 2 6 3 9)))
cddr |
Type: Lambda |
root::cddr |
Usage: (cddr lst) |
Shorthand for car/cdr calls (a is car, d is cdr)
Example:
(assert-equal '(3) (cddr '((1 4 5) 2 3)))
Random forms
probool |
Type: Function |
root::probool |
Usage: (probool), (probool numerator denominator) |
PRObability of a BOOLean. If no arguments are given, returns #t 1/2 of the time, otherwise takes two integers, numerator and denominator, and returns #t numerator/denominator of the time. Throws an error if denominator is 0. If (>= (/ numerator denominator) 1) probool always returns true. If numerator is 0 probool always returns false.
Example:
(def val0 (probool))
(test::assert-true (or (= #t val0) (= nil val0)))
(def val1 (probool 17 42))
(test::assert-true (or (= #t val1) (= nil val1)))
(test::assert-true (probool 1 1))
(test::assert-false (probool 0 42))
(test::assert-error-msg (probool 0 0) "Denominator can not be zero")
(test::assert-error-msg (probool 0 0 0) "Expected zero or two numbers")
random |
Type: Function |
root::random |
Usage: (random), (random limit) |
Returns non-negative number less than limit and of the same type as limit.
Example:
(def rand-int (random 100))
(test::assert-true (and (> rand-int 0) (< rand-int 100))
(def rand-float (random 1.0))
(test::assert-true (and (> rand-float 0) (< rand-float 1)))
(test::assert-error-msg (random -1) "Expected positive integer")
(test::assert-error-msg (random 1 2) "Expected zero or one integers")
random-str |
Type: Function |
root::random-str |
Usage: (random-str str-length [char-set]) |
Takes a positive integer, str-length, and one of :hex, :ascii, :alnum, or a string. Returns random string of provided str-length composed of second argument, :hex results in random hex string, :ascii results in random string of all printable ascii characters, :alnum results in random string of all alphanumeric characters, and providing a string results in a random string composed by sampling input.
Example:
(test::assert-error-msg (random-str) "random-str: Missing required argument, see (doc 'random-str) for usage.")
(test::assert-error-msg (random-str -1) "Expected positive number")
(test::assert-error-msg (random-str 10) "random-str: Missing required argument, see (doc 'random-str) for usage.")
(test::assert-equal 100 (length (random-str 10 :hex))
(test::assert-true (str-contains "⚙" (random-str 42 "⚙"))
(test::assert-equal 19 (length (random-str 19 :ascii)
(test::assert-equal 91 (length (random-str 91 :alnum)
Regex forms
make-regex |
Type: Function |
root::make-regex |
Usage: (make-regex regex) -> Regex |
Given a valid regex string, return a sl-sh Regex. The syntax for regular expressions in sl-sh is borrowed from the Rust regex library and is specified here.
Example:
(test::assert-equal "Regex" (type (make-regex ".*")))
re-color |
Type: Function |
root::re-color |
Usage: (re-color regex string) -> t/nil |
Given a regex and a string, colorize the portions of string that match regex, giving unique values unique colors. Colors are chosen deterministically based on the hash of the capture group’s value. If no capture groups are provided the whole regex is colorized uniquely based on its value. Overlapping capture groups are not supported. The regex argument can either be a regex string or a regex type obtained from make-regex. An optional third keyword argument is accepted, :default, or :unique.
- :default preserves the default color behavior
- :unique tries to give unique capture group’s values unique colors. (see example for more information). </span>
Example:
(test::assert-equal
(str "This c" (fg-color-rgb 35 98 130) "onnection takes on" shell::*fg-default*)
(re-color (make-regex "is c(.*)") "This connection takes on"))
(def simple-time-regex (make-regex "(\d{2}):(\d{2})"))
(test::assert-equal
(str (fg-color-rgb 234 27 39) "11" shell::*fg-default* ":" (fg-color-rgb 234 27 39) "11" shell::*fg-default*)
(re-color "(\d{2}):(\d{2})" "11:11"))
(test::assert-equal
(str (fg-color-rgb 234 27 39) "11" shell::*fg-default* ":" (fg-color-rgb 234 27 39) "11" shell::*fg-default*)
(re-color "(\d{2}):(\d{2})" "11:11" :default))
(test::assert-equal
(str (fg-color-rgb 234 27 39) "11" shell::*fg-default* ":" (fg-color-rgb 245 141 19) "11" shell::*fg-default*)
(re-color "(\d{2}):(\d{2})" "11:11" :unique))
re-find |
Type: Function |
root::re-find |
Usage: (re-find regex string) -> #([String, ..]) |
Given a regex and a string, find the first matching occurrence of regex in string and return a vector of capture groups. The 0th element of the vector is always a string of the whole match. If N capture groups are provided, the Nth group’s value is placed in the Nth element of the vector, where N is one indexed. The regex argument can either be a regex string or a regex type obtained from make-regex.
Example:
(def found-capture (re-find (make-regex "(\d{4})-(\d{2})-(\d{2})") "2020-12-20 and then again on 2021-12-18 but not on 2020-11-20"))
(test::assert-equal 4 (length found-capture))
(test::assert-equal '#("2020-12-20" "2020" "12" "20") found-capture))
(def found (re-find "\d{4}-\d{2}-\d{2}" "2020-12-20 and then again on 2021-12-18 but not on 2020-11-20"))
(test::assert-equal 1 (length found))
(test::assert-equal '#("2020-12-20") found))
(def found-none (re-find "\d{40}-\d{2}-\d{2}" "2020-12-20 and then again on 2021-12-18 but not on 2020-11-20"))
(test::assert-equal '#() found-none)
re-find-all |
Type: Function |
root::re-find-all |
Usage: (re-find-all regex string) -> #(#([String, ..])..) |
Given a regex and a string, find all matching occurrences of regex in string and return a vector of a vector of capture groups. The 0th element of each nested vector is always a string of the whole match. If N capture groups are provided, the Nth group’s value is placed in the Nth element of its respective match vector, where N is one indexed. The regex argument can either be a regex string or a regex type obtained from make-regex.
Example:
(def found (re-find-all (make-regex "(\d{4})-(\d{2})-(\d{2})") "2020-12-20 and then again on 2021-12-18 but not on 2020-11-20"))
(test::assert-equal 3 (length found))
(test::assert-equal '#("2020-12-20" "2020" "12" "20") (vec-nth found 0))
(test::assert-equal '#("2021-12-18" "2021" "12" "18") (vec-nth found 1))
(test::assert-equal '#("2020-11-20" "2020" "11" "20") (vec-nth found 2))
(def found-one (re-find-all "(\d{4})-(\d{2})-(\d{2})" "2020-12-20 and then again on"))
(test::assert-equal 1 (length found-one))
(test::assert-equal '#("2020-12-20" "2020" "12" "20") (vec-nth found-one 0))
(def found-none (re-find-all "(\d{40})-(\d{2})-(\d{2})" "2020-12-20 and then again on"))
(test::assert-equal '#() found-none)
re-match |
Type: Function |
root::re-match |
Usage: (re-match regex string) -> boolean? |
Given a regex and a string, return true if regex is found in string, and return false otherwise. The regex argument can either be a regex string or a regex type obtained from make-regex.
Example:
(test::assert-true
(re-match (make-regex "(\d{4})-(\d{2})-(\d{2})") "2020-12-20 and then again on 2021-12-18 but not on 2020-11-20"))
(test::assert-false
(re-match "(\d{4})-(\d{2})-(\d{20})" "2020-12-20 and then again on 2021-12-18 but not on 2020-11-20"))
re-replace |
Type: Function |
root::re-replace |
Usage: (re-replace regex string replacement) -> String |
Given a regex, a string, and a replacement string, return a modified version of string where all occurrences of regex are edited according to the replacement syntax. The replacement string syntax is borrowed from the Rust regex library and is specified here. The regex argument can either be a regex string or a regex type obtained from make-regex.
Example:
(test::assert-equal
"Thon connection takes on"
(re-replace (make-regex "This") "This connection takes on" "Thon"))
(test::assert-equal
"Thon connection takes"
(re-replace "is (.*) (.*)" "This connection takes on" "\$2 \$1"))
(test::assert-equal
"10-20-2020 and then again on 12-18-2021 but not on 11-20-2020"
(re-replace (make-regex "(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})") "2020-10-20 and then again on 2021-12-18 but not on 2020-11-20" "\$m-\$d-\$y"))
Root forms
*read-table* |
Type: HashMap |
root::*read-table* |
Usage: (print *read-table*) |
Symbol that contains the current read table.
Example:
;(hash-set! *read-table* #\$ 'shell-read::shell-read)
#t
*read-table-terminal* |
Type: HashMap |
root::*read-table-terminal* |
Usage: (print *read-table-terminal*) |
Symbol that contains the current terminal read table.
Example:
;(hash-set! *read-table-terminal* #\] 'nop-read)
#t
*string-read-table* |
Type: HashMap |
root::*string-read-table* |
Usage: (print *string-read-table*) |
Symbol that contains the current string read table.
Example:
;(hash-set! *string-read-table* #\$ 'shell-read::shell-read)
#t
Scripting forms
*load-path* |
Type: Vector |
root::*load-path* |
Usage: (set '*load-path* '("/path/one" "/path/two")) |
Set the a list of paths to search for loading scripts with the load form.
Example:
;(set '*load-path '("/path"))
;(load "script-in-path")
t
load |
Type: Function |
root::load |
Usage: (load path) -> [last form value] |
Read and eval a file (from path- a string).
Example:
(def test-load-one nil)
(def test-load-two nil)
(def test-load-fn (open "/tmp/slsh-test-load.testing" :create :truncate))
(write-line test-load-fn "(set! test-load-one \"LOAD TEST\") '(1 2 3)")
(close test-load-fn)
(set! test-load-two (load "/tmp/slsh-test-load.testing"))
(test::assert-equal "LOAD TEST" test-load-one)
(test::assert-equal '(1 2 3) test-load-two)
mkli |
Type: Lambda |
shell::mkli |
Usage: (mkli filepath [namespace] [body]) |
“make lisp”.creates a sl-sh shell script. given a file, a namespace (optional 2nd arg), and a string to populate as the body (optional 3rd arg), make a canonincal blank sl-sh script complete with all the relevant imports, and boilerplate namespace code taken care of to speed up development. It is recommended all calls to load are done at the top of the file (before the calls to ns-enter or ns-create, in case a library sl-sh script calls a library sl-sh script that created a namespace and forgot to call ns-pop. This ensures the exported symbols for the first library’s scripts namespace are importable in the executing script’s namespace. All calls to ns-import happen after a ns is created and entered so the current namespace is the namespace that houses all the imported symbols. ns-export must be called before ns-pop so the appropriate symbols are associated namespace, the one in which the symbols were created.
Example:
(defn test-file (code file)
(let ((tmp (open file :read)))
(assert-equal
code
(read-all tmp))
(close tmp))
(with-temp (fn (tmp-dir)
(let ((tmp0 (get-temp-file tmp-dir))
(tmp1 (get-temp-file tmp-dir))
(tmp2 (get-temp-file tmp-dir)))
(mkli tmp0 'mytest (println "hello test"))
(test-file
'#((ns-push 'mytest)
(ns-import 'shell)
(println "hello test")
(ns-auto-export 'mytest)
(ns-pop))
tmp0)
(mkli tmp1 'mytest)
(test-file
'#((ns-push 'mytest)
(ns-import 'shell)
(ns-auto-export 'mytest)
(ns-pop))
tmp1)
(mkli tmp2)
(test-file
'#(ns-import 'shell)
tmp2))))
Sequence forms
These macros will work on either a vector or a pair made into a proper list (cons list). Use these in preference to the vector/list specific versions when possible (i.e. first vs car). NOTE: list on this table can be a vector or a list.
butlast |
Type: Lambda |
root::butlast |
Usage: (butlast obj) |
Produces the provided list minus the last element. Nil if the list is empty or one element.
Example:
(assert-equal '(1 2) (butlast '(1 2 3)))
(assert-equal '(1 2) (butlast '#(1 2 3)))
(assert-equal nil (butlast '(1)))
(assert-equal nil (butlast '#(1)))
(assert-equal nil (butlast '()))
(assert-equal nil (butlast nil))
(assert-equal nil (butlast '#()))
collect-copy |
Type: Lambda |
root::collect-copy |
Usage: (collect-copy seq) |
Produces a copy of the provided list (copy has same type as the parameter).
Example:
(def test-colcl '(1 2 3))
(assert-true (list? test-colcl))
(def test-colcl2 (collect-copy test-colcl))
(assert-true (list? test-colcl2))
(assert-equal test-colcl test-colcl2)
(def test-colcv '#(1 2 3))
(assert-true (vec? test-colcv))
(def test-colcv2 (collect-copy test-colcv))
(assert-true (vec? test-colcv2))
(assert-equal test-colcv test-colcv2)
empty-seq? |
Type: Lambda |
root::empty-seq? |
Usage: (empty-seq? obj) -> t/nil |
empty-seq?
returns true if a list or vector is empty and false/nil
otherwise. If a non list or non vector is passed in it returns nil.
Example:
(test::assert-false (empty-seq? '(1 2 3)))
(test::assert-false (empty-seq? '#(1 2 3)))
(test::assert-true (empty-seq? '()))
(test::assert-true (empty-seq? '#()))
(test::assert-false (empty-seq? "aaa"))
(test::assert-false (empty-seq? 1))
first |
Type: Lambda |
root::first |
Usage: (first obj) |
Produces the first element of the provided list or vector. Nil if the list/vector is nil/empty. Note this is like car that works for lists and vectors.
Example:
(assert-equal 1 (first '(1 2 3)))
(assert-equal 1 (first '#(1 2 3)))
(assert-equal nil (first '()))
(assert-equal nil (first nil))
(assert-equal nil (first '#()))
in? |
Type: Lambda |
root::in? |
Usage: (in? seq-to-search item-to-match) |
Takes a seq? that is not an empty-seq? and returns true if the second argument is is in list, false otherwise.
Example:
(let ((vowels-list (list 'a 'e 'i 'o 'u)))
(assert-true (in? vowels-list 'u))
(assert-false (in? vowels-list 'c))
(assert-true (in? (list (list)) (list)))
(assert-false (in? 8 18)))
last |
Type: Lambda |
root::last |
Usage: (last obj) |
Produces the last element in a list or vector. Nil if the list/vector is empty.
Example:
(assert-equal 3 (last '(1 2 3)))
(assert-equal 3 (last '#(1 2 3)))
(assert-equal nil (last '()))
(assert-equal nil (last nil))
(assert-equal nil (last '#()))
non-empty-seq? |
Type: Lambda |
root::non-empty-seq? |
Usage: (non-empty-seq? obj) -> t/nil |
non-empty-seq?
returns true if a list or vector is not empty and false/nil
otherwise. If a non list or non vector is passed in it returns nil.
Example:
(test::assert-true (non-empty-seq? '(1 2 3)))
(test::assert-true (non-empty-seq? '#(1 2 3)))
(test::assert-false (non-empty-seq? '()))
(test::assert-false (non-empty-seq? '#()))
(test::assert-false (non-empty-seq? "aaa"))
(test::assert-false (non-empty-seq? 1))
qsort |
Type: Lambda |
root::qsort |
Usage: (qsort sequence comp-lambda?) -> [sorted vector] |
Sort a sequence using the quick sort algorithm. Returns a vector of the sorted sequence. The comp-lambda argument is optional, if provided it should be a lambda or builtin that takes two arguments and return t or nil (it is the compare function for the sort). Defaults to < if not provided.
Example:
(test::assert-equal '(1 2 3) (qsort '(2 3 1)))
(test::assert-equal '(1 2 3) (qsort '#(2 3 1)))
(test::assert-equal '(3 2 1) (qsort '(2 3 1) >))
(test::assert-equal '(3 2 1) (qsort '#(2 3 1) (fn (a b) (< b a))))
(test::assert-equal '("aaa" "aab" "aba" "baa" "bab" "ccc")
(qsort '("aaa" "aab" "aba" "baa" "bab" "ccc")))
(test::assert-equal '("aaa" "aab" "aba" "baa" "bab" "ccc")
(qsort '("ccc" "bab" "baa" "aba" "aab" "aaa")))
(test::assert-equal '("aaa" "aab" "aba" "baa" "bab" "ccc")
(qsort '("aba" "bab" "aab" "ccc" "baa" "aaa")))
(test::assert-equal '("ccc" "bab" "baa" "aba" "aab" "aaa")
(qsort '("aba" "bab" "aab" "ccc" "baa" "aaa") >))
(test::assert-equal '("ccc" "bab" "baa" "aba" "aab" "aaa")
(qsort '("aba" "bab" "aab" "ccc" "baa" "aaa") (fn (a b) (> a b))))
(test::assert-equal '() (qsort '()))
(test::assert-equal '() (qsort '#()))
(test::assert-equal '#() (qsort '()))
(test::assert-equal '#() (qsort '#()))
rest |
Type: Lambda |
root::rest |
Usage: (rest obj) |
Produces the provided list or vector minus the first element. Nil if the list/vector is nil/empty or one element. Note this is like cdr that works for lists and vectors. This calls vec-slice to create a new vector when called with a vector (i.e. is much more efficient with lists).
Example:
(assert-equal '(2 3) (rest '(1 2 3)))
(assert-equal '(2 3) (rest '#(1 2 3)))
(assert-equal nil (rest '(1)))
(assert-equal nil (rest '#(1)))
(assert-equal nil (rest '()))
(assert-equal nil (rest nil))
(assert-equal nil (rest '#()))
seq-for |
Type: Macro |
root::seq-for |
Usage: (seq-for bind in items body) |
Loops over each element in a sequence. Simple version that works with lists and vectors, use iterator::for in general.
Example:
(def i 0)
(seq-for x in '(1 2 3 4 5 6) (set! i (+ 1 i)))
(assert-equal 6 i)
seq? |
Type: Lambda |
root::seq? |
Usage: (seq? expression) -> t/nil |
True if expression is a list or vector, nil otherwise.
Example:
(test::assert-true (seq? '(1 2 3)))
(test::assert-true (seq? '#(1 2 3)))
(test::assert-true (seq? '()))
(test::assert-true (seq? '#()))
(test::assert-false (seq? "aaa"))
(test::assert-false (seq? 1))
setnth! |
Type: Lambda |
root::setnth! |
Usage: (setnth! idx obj sequence) |
Sets idx item in the vector or list to obj, produces nil or errors on invalid input. This is destructive! Because vectors support indexing and lists do not, this is a much faster operation for a vector (uses builtin vec-set! on input of type vector). Return the list or vector that was modified.
Example:
(def vctr (vec 0 1 2 3))
(def vec-copy (collect-copy vctr))
(setnth! 0 -5 vctr)
(setnth! 1 -400000 vctr)
(setnth! 2 -402202 vctr)
(setnth! 3 -30000 vctr)
(assert-not-equal vec-copy vctr)
(setnth! 0 -4 vctr)
(setnth! 1 -3 vctr)
(setnth! 2 -2 vctr)
(setnth! 3 -1 vctr)
(assert-equal (list -4 -3 -2 -1) vctr)
(assert-equal '(1 5 3) (setnth! 1 5 '#(1 2 3)) " Vector check")
(assert-error (setnth! 0 1 '#()))
(assert-error (setnth! 0 1 (vec)))
(def lst (list 0 1 2 3))
(def list-copy (collect-copy lst))
(setnth! 0 -4 lst)
(setnth! 1 -3 lst)
(setnth! 2 -2 lst)
(setnth! 3 -1 lst)
(assert-not-equal list-copy lst)
(setnth! 0 -4 lst)
(setnth! 1 -3 lst)
(setnth! 2 -2 lst)
(setnth! 3 -1 lst)
(assert-equal (list -4 -3 -2 -1) lst)
(assert-equal '(1 5 3) (setnth! 1 5 '(1 2 3)) " List check")
(assert-error (setnth! 0 1 '()))
(assert-error (setnth! 0 1 (list)))
Shell forms
Forms to do shell operations like file tests, pipes, redirects, etc.
*stderr* |
Type: File |
root::*stderr* |
Usage: (write-line *stderr*) |
File that connects to standard error by default. Can be used in place of a write file object in any form that takes one. Used as the default for eprint and eprintln.
Example:
; Use a file for stderr for test.
(dyn *stderr* (open "/tmp/sl-sh.stderr.test" :create :truncate) (do (write-line *stderr* "Test Error") (close *stderr*)))
(test::assert-equal "Test Error
" (read-line (open "/tmp/sl-sh.stderr.test" :read)))
*stdin* |
Type: File |
root::*stdin* |
Usage: (read-line *stdin*) |
File that connects to standard in by default. Can be used in place of a read file object in any form that takes one.
Example:
(def stdin-test (open "/tmp/sl-sh.stdin.test" :create :truncate))
(write-line stdin-test "Test line")
(close stdin-test)
; Use a file for stdin for test.
(dyn *stdin* (open "/tmp/sl-sh.stdin.test" :read) (do (test::assert-equal "Test line
" (read-line *stdin*)) (close *stdin*)))
*stdout* |
Type: File |
root::*stdout* |
Usage: (write-line *stdout*) |
File that connects to standard out by default. Can be used in place of a write file object in any form that takes one. Used as the default for print and println.
Example:
; Use a file for stdout for test.
(dyn *stdout* (open "/tmp/sl-sh.stdout.test" :create :truncate) (do (write-line *stdout* "Test out") (close *stdout*)))
(test::assert-equal "Test out
" (read-line (open "/tmp/sl-sh.stdout.test" :read)))
alias |
Type: Macro |
shell::alias |
Usage: (alias name body) or (alias name docstring body) |
Create an alias, intended to be used with executables not lisp code (use defn for that).
Example:
(shell::alias xx-echo1 (echo arg1))
(shell::alias xx-echo2 "Dummy doc string" (echo))
(let ((file-name (str (temp-dir)"/alias-test.out"))
(topen))
(out> file-name (xx-echo1 "stdout redir one1"))
(out>> file-name (xx-echo2 "stdout redir one2"))
(set! topen (open file-name :read))
(test::assert-equal "arg1 stdout redir one1\n" (read-line topen))
(test::assert-equal "stdout redir one2\n" (read-line topen))
(test::assert-false (read-line topen))
(close topen))
alias? |
Type: Lambda |
shell::alias? |
Usage: (alias? name) |
Provides boolean value confirming or denying given alias’ presence in set of registered aliases.
Example:
(def xx-echo-not-alias #t)
(test::assert-false (alias? 'xx-echo-not-alias))
(test::assert-false (alias? 'xx-echo))
(shell::alias xx-echo (echo -en))
(test::assert-true (alias? 'xx-echo))
(unalias xx-echo)
(test::assert-false (alias? 'xx-echo))
bg-color-rgb |
Type: Lambda |
shell::bg-color-rgb |
Usage: (bg-color-rgb red-val green-val blue-val) |
Set the background color to the desired rgb where each arg is an integer between 0 and 255 inclusive.
Example:
(test::assert-equal "[48;2;128;128;128m" (bg-color-rgb 128 128 128))
(test::assert-equal "[48;2;255;255;255m" (bg-color-rgb 255 255 255))
(test::assert-equal "[48;2;255;0;0m" (bg-color-rgb 255 0 0))
(test::assert-equal "[48;2;0;255;0m" (bg-color-rgb 0 255 0))
(test::assert-equal "[48;2;0;0;255m" (bg-color-rgb 0 0 255))
(test::assert-equal "[48;2;0;0;0m" (bg-color-rgb 0 0 0))
clear-dirs |
Type: Lambda |
shell::clear-dirs |
Usage: (clear-dirs) |
Clears the directory stack.
Example:
(clear-dirs)
(def cur-test-path (get-env PWD))
(test::assert-equal '() (get-dirs))
(pushd "/tmp")
(def cur-test-path2 (get-env PWD))
(test::assert-equal `(,cur-test-path) (get-dirs))
(pushd (str-trim cur-test-path))
(test::assert-equal `(,cur-test-path ,cur-test-path2) (get-dirs))
(clear-dirs)
(test::assert-equal '() (get-dirs))
dirs |
Type: Lambda |
shell::dirs |
Usage: (dirs) |
List the directory stack.
Example:
(clear-dirs)
(def cur-test-path (get-env PWD))
(dyn *stdout* (open "/tmp/sl-sh.dirs.test" :create :truncate) (dirs))
(test::assert-equal nil (read-line (open "/tmp/sl-sh.dirs.test" :read)))
(pushd "/tmp")
(def cur-test-path2 (get-env PWD))
(dyn *stdout* (open "/tmp/sl-sh.dirs.test" :create :truncate) (dirs))
(test::assert-equal cur-test-path (str-trim (read-line (open "/tmp/sl-sh.dirs.test" :read))))
(pushd (str-trim cur-test-path))
(dyn *stdout* (open "/tmp/sl-sh.dirs.test" :create :truncate) (dirs))
(def test-dirs-file (open "/tmp/sl-sh.dirs.test" :read))
(test::assert-equal cur-test-path (str-trim (read-line test-dirs-file)))
(test::assert-equal cur-test-path2 (str-trim (read-line test-dirs-file)))
(close test-dirs-file)
(popd)
(dyn *stdout* (open "/tmp/sl-sh.dirs.test" :create :truncate) (dirs))
(test::assert-equal cur-test-path (str-trim (read-line (open "/tmp/sl-sh.dirs.test" :read))))
(popd)
(dyn *stdout* (open "/tmp/sl-sh.dirs.test" :create :truncate) (dirs))
(test::assert-equal nil (read-line (open "/tmp/sl-sh.dirs.test" :read)))
epoch |
Type: Function |
root::epoch |
Usage: (epoch) |
Prints system time in milliseconds.
Example:
;(epoch)
#t
err> |
Type: Macro |
shell::err> |
Usage: (err> file body) |
Redirect stderr to file, truncate the file first.
Example:
(err> "/tmp/sl-sh.err>.test" (eprintln "stderr redir one"))
(def topen (open "/tmp/sl-sh.err>.test" :read))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(err> "/tmp/sl-sh.err>.test" (eprintln "stderr redir two"))
(def topen (open "/tmp/sl-sh.err>.test" :read))
(test::assert-equal "stderr redir two
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
err>> |
Type: Macro |
shell::err>> |
Usage: (err>> file body) |
Redirect stderr to file, append the output.
Example:
(err> "/tmp/sl-sh.err>>.test" (eprintln "stderr redir one"))
(def topen (open "/tmp/sl-sh.err>>.test" :read))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(err>> "/tmp/sl-sh.err>>.test" (eprintln "stderr redir two"))
(def topen (open "/tmp/sl-sh.err>>.test" :read))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-equal "stderr redir two
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
err>null |
Type: Macro |
shell::err>null |
Usage: (err>null body) |
Redirect stderr to null (/dev/null equivelent).
Example:
(err> "/tmp/sl-sh.err>null.test" (do (eprintln "stderr redir one")(err>null (eprintln "stdnull redir one"))))
(def topen (open "/tmp/sl-sh.err>null.test" :read))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
fc |
Type: Lambda |
shell::fc |
Usage: (fc) |
Put the contents of the last command into a temporary file
(temp-dir), and open the temporary file in the text editor,
If the editor returns with an error code of 0 the contents of the
temporary file are executed. fc
can be used in succession and the contents of
the temporary file are saved to the sl-sh history.
fg-color-rgb |
Type: Lambda |
shell::fg-color-rgb |
Usage: (fg-color-rgb red-val green-val blue-val) |
Set the foreground color to the desired rgb where each arg is an integer between 0 and 255 inclusive.
Example:
(test::assert-equal "[38;2;128;128;128m" (fg-color-rgb 128 128 128))
(test::assert-equal "[38;2;255;255;255m" (fg-color-rgb 255 255 255))
(test::assert-equal "[38;2;255;0;0m" (fg-color-rgb 255 0 0))
(test::assert-equal "[38;2;0;255;0m" (fg-color-rgb 0 255 0))
(test::assert-equal "[38;2;0;0;255m" (fg-color-rgb 0 0 255))
(test::assert-equal "[38;2;0;0;0m" (fg-color-rgb 0 0 0))
get-dirs |
Type: Lambda |
shell::get-dirs |
Usage: (get-dirs) |
Return the vector of directories.
Example:
(clear-dirs)
(def cur-test-path (get-env PWD))
(test::assert-equal '() (get-dirs))
(pushd "/tmp")
(def cur-test-path2 (get-env PWD))
(test::assert-equal `(,cur-test-path) (get-dirs))
(pushd (str-trim cur-test-path))
(test::assert-equal `(,cur-test-path ,cur-test-path2) (get-dirs))
(popd)
(test::assert-equal `(,cur-test-path) (get-dirs))
(popd)
(test::assert-equal '() (get-dirs))
getopts |
Type: Lambda |
shell::getopts |
Usage: (getopts options-map args) |
Getopts takes a hash map and a vector of args and returns a hash map with all
the values extracted from the args and bound to the corresponding keys in the
provided hash map. Support for automatically generating documentation is
available with helper function getopts-help.
Take this example script:
sample-getopts.lisp
#!/usr/bin/env sl-sh
(println "Passing: " args " to getopts")
;; getopts is given a hash map with one key, :-m, that corresponds to the flag,
;; -m, that it configures.
(def *sample-getopts-bindings*
(getopts
(make-hash
(list (join
:-m
(make-hash '((:arity . 1)
(:default . 0)
(:type . :int?))))))
args))
(println "The binding for -m is: " (hash-get *sample-getopts-bindings* :-m) "of type " (type (hash-get *sample-getopts-bindings* :-m)))
Running the script with one argument to the -m flag yields:
/sample-getopts.lisp -m 7
Passing: #("-m" "7") to getopts
The binding for -m is 7 of type Int
The hash map for the key :-m showcases the configuration keys that exist for each flag: arity, :default, and :type. :arity specifies that the -m flag will take one argument. :default specifies the bindng for :-m should be 0 if the -m flag is not seen in args. :type :int? specifies that the binding should be of that type, in this case int?. Running the script again with no -m flag yields:
/sample-getopts.lisp
Passing: #() to getopts
The binding for -m is 0 of type Int
Demonstrating the :default binding of 0 for the symbol :-m since the -m flag was not provided as an argument to the script. Configuration keys for flags:
- :arity (optional) Defaults to 0. If the arity is 0 the returned binding will be #t or nil. Can be any integer. The integer value for the :arity corresponds to the number of arguments getopts will enforce for this flag, if the number of arguments provided to the flag is not equal to the specified arity an error is thrown.
- :default (optional) Use this as a default if the given flag is not provided at execution time.
- :type (optional) Specify a type for every provided argument for the given flag. Types can be any of: (“list?” “macro?” “fs-dir?” “symbol?” “fs-exists?” “int?” “hash?” “vec?” “float?” “lambda?” “falsey?” “string?” “fs-file?” “char?”) Rules for flags:
- Flags can be single character: -m -n -c etc.
- Flags of a single single character with arity 0 can be adjacent without the need for additional dashes: -mnc
- Multiple flags of a single character with arity 0 can precede a flag of a single character with arity N as long as said character appears last: -mne “foo”
- Flags can be multi-character as long as they are preceded by two dashes: –multi-char-arg </span>
Example:
;See tests/getopts.lisp
#t
getopts-help |
Type: Lambda |
shell::getopts-help |
Usage: (getopts-help bindings) |
Companion function to getopts, call this function in the docstring of any function that relies on getopts. getopts-help takes as an argument the same bindings hash map that getopts does, and returns the documentation for those getopts settings. getopts-help optionally supports a :doc keyword for each command key. The value of doc is included in the resultant doc string getopts-help returns.
Example:
;;; The following represents a full example usage of getopts
;;; with documentation generated in the doc string of the function that uses
;;; getopts:
(def getopts-bindings
(make-hash
(list
(def getopts-help-bindings
(make-hash
(list (join
:-m
(make-hash '((:arity . 1)
(:default . 0)
(:type . :int?)
(:doc "this is displayed as
two indented lines."))))
(join
:-b
(make-hash '((:doc "this opts doc for -b
goes on two lines!"))))
(join
:-a
(make-hash '((:arity . 1)
(:doc "this doc is for -a."))))
(join
:-k
(make-hash '((:arity . 1)
(:type . :int?)))))))
(test::assert-equal
(str-split :whitespace (getopts-help getopts-help-bindings))
(str-split :whitespace (str-push! (str) # "-a" # "arity 1" # "this doc is for -a." # "-b" # "arity 0" # "this opts doc for -b" # "goes on two lines!" # "-k" # "arity 1" # "required type :int?" # "-m" # "arity 1" # "default value 0" # "required type :int?" # "this is displayed as" # "two indented lines.")))
history-context |
Type: Function |
root::history-context |
Usage: (history-context :context_id context-string) -> nil |
Sets the history context for searches. Usually the current path but can be any string. Pass nil to set it to nothing.
Example:
;(history-context :repl "/home")
#t
history-empty? |
Type: Function |
root::history-empty? |
Usage: (history-empty? :context_id) -> t/nil |
Returns true if history for context_id is empty, nil otherwise.
Example:
;(history-empty? :repl)
#t
history-length |
Type: Function |
root::history-length |
Usage: (history-length :context_id) -> int |
Returns the number of history items for the given context.
Example:
;(history-length :repl)
#t
history-nth |
Type: Function |
root::history-nth |
Usage: (history-nth :context_id nth) -> String |
Returns the history at index nth (the newest is 0).
Example:
;(history-nth :repl 0)
#t
history-push |
Type: Function |
root::history-push |
Usage: (history-push :context_id string) -> nil/t |
Pushes string onto the history for the prompt context :context_id. Returns true on success or nil on failure.
Example:
;(history-push :repl "Some command")
#t
history-push-throwaway |
Type: Function |
root::history-push-throwaway |
Usage: (history-push-throwaway :context_id string) -> nil/t |
Pushes string onto the history for the prompt context :context_id. A throwaway item will will only persist until the next command is read (use it to allow editing of failed commands without them going into history). Returns true on success or nil on failure.
Example:
;(history-push-throwaway :repl "Some broken command")
#t
let-env |
Type: Macro |
shell::let-env |
Usage: (let-env vals &rest let_body) |
Like let but sets environment variables that are reset after the macro finishes.
Example:
(test::assert-equal "" $LET-ENV-TEST-VAR-NOT-HERE)
(let-env ((LET-ENV-TEST-VAR-NOT-HERE "here"))
(test::assert-equal "here" $LET-ENV-TEST-VAR-NOT-HERE))
(test::assert-equal "" $LET-ENV-TEST-VAR-NOT-HERE)
out-err> |
Type: Macro |
shell::out-err> |
Usage: (out-err> file body) |
Redirect both stdout and stderr to the same file, truncate the file first.
Example:
(out-err> "/tmp/sl-sh.out-err>.test" (do (println "stdout redir one")(eprintln "stderr redir one")))
(def topen (open "/tmp/sl-sh.out-err>.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(out-err> "/tmp/sl-sh.out-err>.test" (do (syscall 'echo "stdout echo redir one")(eprintln "stderr redir one")))
(def topen (open "/tmp/sl-sh.out-err>.test" :read))
(test::assert-equal "stdout echo redir one
" (read-line topen))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(out-err> "/tmp/sl-sh.out-err>.test" (do (println "stdout redir two")(eprintln "stderr redir two")))
(def topen (open "/tmp/sl-sh.out-err>.test" :read))
(test::assert-equal "stdout redir two
" (read-line topen))
(test::assert-equal "stderr redir two
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
out-err>> |
Type: Macro |
shell::out-err>> |
Usage: (out-err>> file body) |
Redirect both stdout and stderr to the same file, append the output.
Example:
(out-err> "/tmp/sl-sh.out-err>>.test" (do (println "stdout redir one")(eprintln "stderr redir one")))
(def topen (open "/tmp/sl-sh.out-err>>.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(out-err>> "/tmp/sl-sh.out-err>>.test" (do (println "stdout redir two")(eprintln "stderr redir two")))
(def topen (open "/tmp/sl-sh.out-err>>.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-equal "stdout redir two
" (read-line topen))
(test::assert-equal "stderr redir two
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
out-err>null |
Type: Macro |
shell::out-err>null |
Usage: (out-err>null body) |
Redirect both stdout and stderr to null (/dev/null equivelent).
Example:
(out-err> "/tmp/sl-sh.out-err>null.test" (do
(println "stdout redir one")
(eprintln "stderr redir one")
(out-err>null (do
(println "stdnull redir one")
(eprintln "stdnull redir one")))))
(def topen (open "/tmp/sl-sh.out-err>null.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-equal "stderr redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
out> |
Type: Macro |
shell::out> |
Usage: (out> file body) |
Redirect stdout to file, truncate the file first.
Example:
(out> "/tmp/sl-sh.out>.test" (syscall 'echo "stdout redir one"))
(def topen (open "/tmp/sl-sh.out>.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(out> "/tmp/sl-sh.out>.test" (syscall 'echo "stdout redir two"))
(def topen (open "/tmp/sl-sh.out>.test" :read))
(test::assert-equal "stdout redir two
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
out>> |
Type: Macro |
shell::out>> |
Usage: (out>> file body) |
Redirect stdout to file, append the output.
Example:
(out> "/tmp/sl-sh.out>>.test" (syscall 'echo "stdout redir one"))
(def topen (open "/tmp/sl-sh.out>>.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(out>> "/tmp/sl-sh.out>>.test" (syscall 'echo "stdout redir two"))
(def topen (open "/tmp/sl-sh.out>>.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-equal "stdout redir two
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
out>null |
Type: Macro |
shell::out>null |
Usage: (out>null body) |
Redirect stdout to null (/dev/null equivelent).
Example:
(out> "/tmp/sl-sh.out>null.test" (do (println "stdout redir one")(out>null (println "stdnull redir one"))))
(def topen (open "/tmp/sl-sh.out>null.test" :read))
(test::assert-equal "stdout redir one
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
popd |
Type: Lambda |
shell::popd |
Usage: (popd) |
Pop first directory from directory stack and change to it.
Example:
(def cur-test-path (get-env PWD))
(pushd "/tmp")
(def cur-test-path2 (get-env PWD))
(assert-equal cur-test-path2 (get-env PWD))
(popd)
(assert-equal cur-test-path (get-env PWD))
prompt |
Type: Function |
root::prompt |
Usage: (prompt string) -> string |
Starts an interactive prompt (like the repl prompt) with the supplied prompt and returns the input string.
Example:
;(def input-string (prompt "prompt> "))
#t
pushd |
Type: Lambda |
shell::pushd |
Usage: (pushd dir) |
Push current directory on the directory stack and change to new directory.
Example:
(def cur-test-path (get-env PWD))
(pushd "/tmp")
(def cur-test-path2 (get-env PWD))
(assert-equal cur-test-path2 (get-env PWD))
(popd)
(assert-equal cur-test-path (get-env PWD))
register-alias |
Type: Lambda |
shell::register-alias |
Usage: (register-alias name) |
Registers an alias to the current scope. Useful if unregistering or
ability to know whether an alias has been registered is desirable.
set-dirs-max |
Type: Lambda |
shell::set-dirs-max |
Usage: (set-dirs-max max) |
Sets the max number of directories to save in the stack.
Example:
(clear-dirs)
(def cur-test-path (get-env PWD))
(pushd "/tmp")
(def cur-test-path2 (get-env PWD))
(pushd (str-trim cur-test-path))
(pushd "/tmp")
(pushd (str-trim cur-test-path))
(test::assert-equal `(,cur-test-path ,cur-test-path2 ,cur-test-path ,cur-test-path2) (get-dirs))
(clear-dirs)
(set-dirs-max 3)
(pushd "/tmp")
(pushd (str-trim cur-test-path))
(pushd "/tmp")
(pushd (str-trim cur-test-path))
(test::assert-equal `(,cur-test-path2 ,cur-test-path ,cur-test-path2) (get-dirs))
syntax-off |
Type: Macro |
shell::syntax-off |
Usage: (syntax-off) |
Turn off syntax highlighting at the repl.
syntax-on |
Type: Lambda |
shell::syntax-on |
Usage: (syntax-on) |
Turn on syntax highlighting at the repl.
sys-command? |
Type: Lambda |
shell::sys-command? |
Usage: (sys-command? com) |
True if the supplied command is a system command.
Example:
(assert-true (sys-command? "ls"))
(assert-false (sys-command? "rst-not-a-comand-strsnt"))
timer |
Type: Lambda |
shell::timer |
Usage: (timer) |
timer struct Initialize a timer object that can be called repeatedly with :pr-next to return relative time passed since instantiation and time since last called or first instantiated. attribute: start-time private attribute: noop private attribute: cnt private attribute: prev-time private attribute: curr-time private attribute: timer-name private method: :get-next method: :pr-next method: :init
Example:
(def test-timer ((timer) :init "test-timer" nil))
(def timer-str (test-timer :get-next "event0"))
(def timer-str-vec (str-split :whitespace timer-str))
(test::assert-equal "{0}[test-timer-event0]:" (vec-nth timer-str-vec 0))
(test::assert-true (int? (str->int (vec-nth timer-str-vec 1))))
(test::assert-true (int? (str->int (vec-nth timer-str-vec 4))))
(def elapsed (vec-nth timer-str-vec 1))
(def difference (vec-nth timer-str-vec 4))
(test::assert-equal elapsed difference)
unalias |
Type: Macro |
shell::unalias |
Usage: (unalias name) |
Remove an alias. Use this instead of undef to make sure book keeping happens.
Example:
(shell::alias xx-echo (echo))
(let ((file-name (str (temp-dir)"/unalias-test.out"))
(topen))
(out> file-name (xx-echo "stdout redir\none1"))
(set! topen (open file-name :read))
(test::assert-equal "stdout redir\n" (read-line topen))
(test::assert-equal "one1\n" (read-line topen))
(test::assert-false (read-line topen))
(close topen))
(unalias xx-echo)
(test::assert-error (xx-echo "error"))
unregister-alias |
Type: Lambda |
shell::unregister-alias |
Usage: (unregister-alias name) |
Unregisters an alias, removing it from scope.
version |
Type: Function |
root::version |
Usage: (version) |
Produce executable version as string.
Example:
(test::assert-true (string? (version)))
Stats forms
first-quartile |
Type: Function |
stats::first-quartile |
Usage: (first-quartile number+) |
Returns first quartile of distribution of provided arguments.
Example:
(ns-import 'stats)
(test::assert-error-msg (first-quartile) "expected at least one number")
(test::assert-equal 2.5 (first-quartile 10 4 8 7 6 5 9 3 2 1))
max |
Type: Function |
stats::max |
Usage: (max number+) |
Returns maximum of provided arguments.
Example:
(ns-import 'stats)
(test::assert-error-msg (max) "expected at least one number")
(test::assert-equal 11 (max 10 4 8 7 6 5 9 3 2 1 11))
mean |
Type: Function |
stats::mean |
Usage: (mean number+) |
Average a sequence of numbers.
Example:
(ns-import 'stats)
(test::assert-error-msg (mean) "expected at least one number")
(test::assert-equal 5 (mean 5))
(test::assert-equal 7.5 (mean 5 10))
(test::assert-equal 5.5 (mean 1 2 3 4 5 6 7 8 9 10))
median |
Type: Function |
stats::median |
Usage: (median number+) |
Returns median of sequence of numbers.
Example:
(ns-import 'stats)
(test::assert-error-msg (median) "expected at least one number")
(test::assert-equal 5 (median 5))
(test::assert-equal 7.5 (median 10 5))
(test::assert-equal 5.5 (median 10 9 8 7 6 5 4 3 2 1))
(test::assert-equal 6 (median 10 4 8 7 6 5 9 3 2 1 11))
min |
Type: Function |
stats::min |
Usage: (min number+) |
Returns minimum of provided arguments.
Example:
(ns-import 'stats)
(test::assert-error-msg (min) "expected at least one number")
(test::assert-equal 1 (min 10 4 8 7 6 5 9 3 2 1 11))
mode |
Type: Function |
stats::mode |
Usage: (mode number+) |
Returns mode of a sequence of numbers. Since distributions can be multimodal, mode returns a list.
Example:
(ns-import 'stats)
(test::assert-error-msg (mode) "expected at least one number")
(test::assert-equal (list 5) (mode 5))
(test::assert-equal (list 1 3 4 5 6 7 8 9 10) (mode 1 3 4 5 6 7 8 9 10))
(test::assert-equal (list 7.0) (mode 1 7.0 3 4 5 6 7 8 9 10))
std-dev |
Type: Function |
stats::std-dev |
Usage: (std-dev number+) |
Returns standard deviation of a sequence of numbers.
Example:
(ns-import 'stats)
(test::assert-error-msg (std-dev) "expected at least one number")
(test::assert-equal 3.0276503540974917 (std-dev 1 2 3 4 5 6 7 8 9 10))
summary-stats |
Type: Function |
stats::summary-stats |
Usage: (summary-stats number+) |
Returns hash map containing summary statistics and sorted array.
Example:
(ns-import 'stats)
(test::assert-error-msg (summary-stats) "expected at least one number")
(def distr (summary-stats 10 2 9 4 6 5 7 8 3 1))
(test::assert-equal '#(1 2 3 4 5 6 7 8 9 10) (hash-get distr :vec))
(test::assert-equal 5.5 (hash-get distr :med))
(test::assert-equal 10 (hash-get distr :max))
(test::assert-equal 3.0276503540974917 (hash-get distr :sd))
(test::assert-equal 5.5 (hash-get distr :mean))
(test::assert-equal '#(1 2 3 4 5 6 7 8 9 10) (hash-get distr :mode))
(test::assert-equal 1 (hash-get distr :min))
(test::assert-equal 8 (hash-get distr :q3))
(test::assert-equal 2.5 (hash-get distr :q1))
third-quartile |
Type: Function |
stats::third-quartile |
Usage: (third-quartile number+) |
Returns third quartile of distribution of provided arguments.
Example:
(ns-import 'stats)
(test::assert-error-msg (third-quartile) "expected at least one number")
(test::assert-equal 8 (third-quartile 10 4 8 7 6 5 9 3 2 1))
String forms
char->int |
Type: Function |
root::char->int |
Usage: (char->int a-char) |
Reads a char or string, which may be composed of one or more unicode scalar values, (see (doc ‘codepoints) for more information) and returns a sum of the values. This is not a hashing function, and only accepts one grapheme in the form of a string or character. Graphemes composed of the same unicode scalar values will result in the same integer value.’
Example:
(test::assert-error-msg (char->int (make-vec)) "char->int expects one argument of type Char or String")
(test::assert-error-msg (char->int) "char->int: Missing required argument, see (doc 'char->int) for usage.")
(test::assert-error-msg (char->int "a" "b") "char->int: Too many arguments, see (doc 'char->int) for usage.")
(test::assert-error-msg (char->int "ab") "char->int takes one grapheme, multiple were provided.")
(test::assert-error-msg (char->int "λ⚙") "char->int takes one grapheme, multiple were provided.")
(test::assert-equal 97 (char->int "a"))
(test::assert-equal 97 (char->int #\a))
(test::assert-equal 7101 (char->int #\स्))
(test::assert-equal 9881 (char->int (str "\" "u{2699}")))
codepoints |
Type: Function |
root::codepoints |
Usage: (codepoints string) |
Returns array of unicode scalars for each char in string. Note, a char is not a grapheme. The hindi word namaste (“न” “म” “स्” “ते”) written in Devanagari script is 4 graphemes, but 6 unicode scalar values, (“u{928}” “u{92e}” “u{938}” “u{94d}” “u{924}” “u{947}”); reference.
Example:
(test::assert-error-msg (codepoints) "codepoints: Missing required argument, see (doc 'codepoints) for usage.")
(test::assert-error-msg (codepoints (make-vec)) "codepoints expects one argument of type Char or String")
(test::assert-error-msg (codepoints "a" "b") "codepoints: Too many arguments, see (doc 'codepoints) for usage.")
(test::assert-equal (vec (str "\" "u{2699}")) (codepoints "⚙"))
(test::assert-equal (vec (str "\" "u{938}") ((str "\" "u{94d}"))) (codepoints "स्"))
(test::assert-equal (vec (str "\" "u{938}") ((str "\" "u{94d}"))) (codepoints #\स्))
(test::assert-equal (vec (str "\" "u{61}")) (codepoints "a"))
(test::assert-equal (vec (str "\" "u{61}")) (codepoints #\a))
do-unstr |
Type: SpecialForm |
root::do-unstr |
Usage: (do-unstr arg0 ... argN) -> argN |
Like do except if in an ‘str’ form then any processes will send their output to stdout instead of being captured as a string (‘undoes’ a str for processes). Note: does not convert arguments into strings, works like do.
Example:
; out> uses do-unstr so use a simplified one for these tests.
(defmacro tst-out> (file body) `(dyn *stdout* (open ,file :create :truncate) ,body))
(test::assert-equal "string 50 test
" (str "string" " " 50 " " (syscall 'echo "test")))
(test::assert-equal "string 50 test2
" (str "string" " " 50 " " (tst-out> "/tmp/test-str-echo" (syscall 'echo "test2"))))
(test::assert-equal "string 50 " (str "string" " " 50 " " (do-unstr (tst-out> "/tmp/test-str-echo" (syscall 'echo "test"))))
str |
Type: Function |
root::str |
Usage: (str arg0 ... argN) -> string |
Make a new string with it’s arguments. Arguments will be turned into strings. If an argument is a process then the output of the process will be captured and put into the string.
Example:
(test::assert-equal "stringsome" (str "string" "some"))
(test::assert-equal "string" (str "string" ""))
(test::assert-equal "string 50" (str "string" " " 50))
(test::assert-equal "string 50 test
" (str "string" " " 50 " " (syscall 'echo "test")))
str-append |
Type: Function |
root::str-append |
Usage: (str-append string string) -> string |
Make a new string by appending two strings.
Example:
(test::assert-equal "stringsome" (str-append "string" "some"))
(test::assert-equal "string" (str-append "string" ""))
(test::assert-equal "string " (str-append "string" " "))
str-bytes |
Type: Function |
root::str-bytes |
Usage: (str-bytes string) -> int |
Return number of bytes in a string (may be more then length). Strings are utf8 so it chars and bytes may not be a one to one match.
Example:
(test::assert-equal 4 (str-bytes "Stau"))
(test::assert-equal 0 (str-bytes ""))
; Note 5 chars and 6 bytes because of the final char.
(test::assert-equal 6 (str-bytes "StauΣ"))
str-cat-list |
Type: Function |
root::str-cat-list |
Usage: (str-cat-list join-pattern sequence) -> string |
Build a string by concatting a sequence with a join string.
Example:
(test::assert-equal "stringxxxyyyxxxsome" (str-cat-list "xxx" '("string" "yyy" "some")))
(test::assert-equal "string yyy some" (str-cat-list " " '("string" "yyy" "some")))
(test::assert-equal "stringyyysome" (str-cat-list "" '("string" "yyy" "some")))
str-clear! |
Type: Function |
root::str-clear! |
Usage: (str-clear! string) -> string |
Clears a string. This is a destructive form. Returns the string it was given.
Example:
(test::assert-equal "" (str-clear! (str "string")))
(def test-str-clear (str "def-string"))
(test::assert-equal "" (str-clear! test-str-clear))
(test::assert-equal "" test-str-clear)
str-contains |
Type: Function |
root::str-contains |
Usage: (str-contains pattern string) -> t/nil |
True if string contains pattern (both strings).
Example:
(test::assert-true (str-contains "Stau" "Stausomething"))
(test::assert-false (str-contains "StaU" "Stausomething"))
(test::assert-true (str-contains "some" "Stausomething"))
(test::assert-false (str-contains "Some" "Stausomething"))
(test::assert-true (str-contains "thing" "Stausomething"))
(test::assert-false (str-contains "Thing" "Stausomething"))
(test::assert-true (str-contains "someΣ" "StausomeΣthing"))
str-empty? |
Type: Function |
root::str-empty? |
Usage: (str-empty? string) -> t/nil |
Is a string empty? Let’s find out…
Example:
(test::assert-true (str-empty? ""))
(test::assert-true (str-empty? (str-trim " ")))
(test::assert-false (str-empty? " "))
(test::assert-false (str-empty? "string"))
str-iter-empty? |
Type: Function |
root::str-iter-empty? |
Usage: (str-iter-empty? string) -> t/nil |
Returns true if the iterator for the string is empty or finished.
Example:
(def test-iter-start "test")
(test::assert-true (str-iter-empty? test-iter-start))
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-equal #\e (str-iter-next! test-iter-start))
(test::assert-equal #\s (str-iter-next! test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-true (str-iter-empty? test-iter-start))
(def test-iter-start "test")
(test::assert-true (str-iter-empty? test-iter-start))
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-equal #\e (str-iter-next! test-iter-start))
(str-push! test-iter-start "one")
(test::assert-true (str-iter-empty? test-iter-start))
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(str-clear! test-iter-start)
(test::assert-true (str-iter-empty? test-iter-start))
str-iter-next! |
Type: Function |
root::str-iter-next! |
Usage: (str-iter-next! string) -> char |
Returns the next char in the iterator for string. Returns nil if iteration is done.
Example:
(def test-iter-start "y̆ΛλΣσ")
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(def test-iter-one (str-iter-next! test-iter-start))
(test::assert-equal #\y̆ test-iter-one)
(test::assert-true (= #\y̆ test-iter-one))
(test::assert-false (= #\y test-iter-one))
(test::assert-equal #\Λ (str-iter-next! test-iter-start))
(test::assert-equal #\λ (str-iter-next! test-iter-start))
(test::assert-equal #\Σ (str-iter-next! test-iter-start))
(test::assert-equal #\σ (str-iter-next! test-iter-start))
(test::assert-true (str-iter-empty? test-iter-start))
str-iter-peek |
Type: Function |
root::str-iter-peek |
Usage: (str-iter-peek string) -> char |
Returns the char that next will return in the iterator for string. Returns nil if iteration is done. Does not advance the iterator.
Example:
(def test-iter-start "y̆ΛλΣσ")
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(def test-iter-one (str-iter-next! test-iter-start))
(test::assert-equal #\y̆ test-iter-one)
(test::assert-true (= #\y̆ test-iter-one))
(test::assert-false (= #\y test-iter-one))
(test::assert-equal #\Λ (str-iter-peek test-iter-start))
(test::assert-equal #\Λ (str-iter-next! test-iter-start))
(test::assert-equal #\λ (str-iter-peek test-iter-start))
(test::assert-equal #\λ (str-iter-next! test-iter-start))
(test::assert-equal #\Σ (str-iter-peek test-iter-start))
(test::assert-equal #\Σ (str-iter-next! test-iter-start))
(test::assert-equal #\σ (str-iter-peek test-iter-start))
(test::assert-equal #\σ (str-iter-next! test-iter-start))
(test::assert-true (str-iter-empty? test-iter-start))
str-iter-start |
Type: Function |
root::str-iter-start |
Usage: (str-iter-start string) -> string |
Starts or resets the iterator over a string. Returns the input string with it’s iteration start created and at the first position. Using the str-iter-* functions is the proper way to get the chars of a string (since they are UTF a char is not a fixed size so direct indexing is very inefficient).
Example:
(def test-iter-start "test")
(test::assert-true (str-iter-empty? test-iter-start))
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-equal #\e (str-iter-next! test-iter-start))
(test::assert-equal #\s (str-iter-next! test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-true (str-iter-empty? test-iter-start))
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-equal #\e (str-iter-next! test-iter-start))
(str-iter-start test-iter-start)
(test::assert-false (str-iter-empty? test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-equal #\e (str-iter-next! test-iter-start))
(test::assert-equal #\s (str-iter-next! test-iter-start))
(test::assert-equal #\t (str-iter-next! test-iter-start))
(test::assert-true (str-iter-empty? test-iter-start))
str-lower |
Type: Function |
root::str-lower |
Usage: (str-lower string) -> string |
Get all lower case string from a string.
Example:
(test::assert-equal "stau" (str-lower "STAU"))
(test::assert-equal "stau" (str-lower "stau"))
(test::assert-equal "stau" (str-lower "Stau"))
(test::assert-equal "stau" (str-lower "StaU"))
(test::assert-equal "stau" (str-lower "sTaU"))
str-ltrim |
Type: Function |
root::str-ltrim |
Usage: (str-ltrim string) -> string |
Trim left whitespace from string.
Example:
(test::assert-equal "some string" (str-ltrim " some string"))
(test::assert-equal "some string " (str-ltrim " some string "))
(test::assert-equal "some string " (str-ltrim (str " some string ")))
(test::assert-equal "some string " (str-ltrim "some string "))
(test::assert-equal "some string" (str-ltrim "some string"))
str-map |
Type: Function |
root::str-map |
Usage: (str-map lambda string) -> string |
Make a new string by applying lambda to each char.
Example:
(test::assert-equal "XstringXstrX" (str-map (fn (ch) (if (= #\x ch) #\X ch)) "xstringxstrx"))
(def test-str-map (str-map (fn (ch) (if (= #\x ch) #\X ch)) "xstringxstrx"))
(test::assert-equal "XstringXstrX" test-str-map)
(test::assert-true (string? test-str-map))
(def test-str-map (str-map (fn (ch) (if (= #\x ch) #\X ch)) (str "xstringxstrx")))
(test::assert-equal "XstringXstrX" test-str-map)
(test::assert-true (string? test-str-map))
str-nth |
Type: Function |
root::str-nth |
Usage: (str-nth n string) -> char |
Get the nth char of a string.
Example:
(test::assert-equal #\a (str-nth 2 "stau"))
(test::assert-equal #\s (str-nth 0 "stau"))
(test::assert-equal #\u (str-nth 3 "stau"))
str-push! |
Type: Function |
root::str-push! |
Usage: (str-push! string arg0 ... argN) -> string |
Push the args (as strings) onto the string. This is a destructive form. Arguments will be turned into strings. Returns the string it was given.
Example:
(test::assert-equal "stringsome" (str-push! (str "string") "some"))
(def test-str-push (str "def-string"))
(test::assert-equal "def-stringsome" (str-push! test-str-push "some"))
(test::assert-equal "def-stringsome" test-str-push)
str-replace |
Type: Function |
root::str-replace |
Usage: (str-replace string old-pattern new-pattern) -> string |
Replace occurances of second string with third in the first string.
Example:
(test::assert-equal "some yyy string" (str-replace "some xxx string" "xxx" "yyy"))
(test::assert-equal "some yyy string yyy" (str-replace "some xxx string xxx" "xxx" "yyy"))
(test::assert-equal "yyy some yyy string yyy" (str-replace "xxx some xxx string xxx" "xxx" "yyy"))
str-rsplit |
Type: Function |
root::str-rsplit |
Usage: (str-rsplit split-pattern string) -> vector |
Use a pattern to split a string into reverse order.
Example:
(test::assert-equal '("some" "yyy" "string") (str-rsplit "xxx" "stringxxxyyyxxxsome"))
(test::assert-equal '("" "some" "yyy" "string") (str-rsplit "xxx" "stringxxxyyyxxxsomexxx"))
(test::assert-equal '("some" "yyy" "string") (str-rsplit " " "string yyy some"))
(test::assert-equal '("somexxxyyyxxxstring") (str-rsplit :whitespace "somexxxyyyxxxstring"))
(test::assert-equal '("somexxxyyyxxxstring") (str-rsplit "zzz" "somexxxyyyxxxstring"))
str-rsplitn |
Type: Function |
root::str-rsplitn |
Usage: (str-rsplitn n split-pattern string) -> vector |
Use a pattern to split a string with at most n items returned in reverse order.
Example:
(test::assert-equal '("some" "yyy" "string") (str-rsplitn 3 "xxx" "stringxxxyyyxxxsome"))
(test::assert-equal '("some" "yyy" "string") (str-rsplitn 4 "xxx" "stringxxxyyyxxxsome"))
(test::assert-equal '("other" "string" "somexxxyyy") (str-rsplitn 3 "xxx" "somexxxyyyxxxstringxxxother"))
(test::assert-equal '("somexxxyyyxxxstringxxxother") (str-rsplitn 1 "xxx" "somexxxyyyxxxstringxxxother"))
(test::assert-equal '() (str-rsplitn 0 "xxx" "somexxxyyyxxxstringxxxzero"))
str-rtrim |
Type: Function |
root::str-rtrim |
Usage: (str-rtrim string) -> string |
Trim right whitespace from string.
Example:
(test::assert-equal " some string" (str-rtrim " some string"))
(test::assert-equal " some string" (str-rtrim " some string "))
(test::assert-equal " some string" (str-rtrim (str " some string ")))
(test::assert-equal "some string" (str-rtrim "some string "))
(test::assert-equal "some string" (str-rtrim "some string"))
str-split |
Type: Function |
root::str-split |
Usage: (str-split split-pattern string) -> vector |
Use a pattern to split a string (:whitespace to split on whitespace).
Example:
(test::assert-equal '("some" "yyy" "string") (str-split "xxx" "somexxxyyyxxxstring"))
(test::assert-equal '("some" "yyy" "string" "") (str-split "xxx" "somexxxyyyxxxstringxxx"))
(test::assert-equal '("" "some" "yyy" "string" "") (str-split "xxx" "xxxsomexxxyyyxxxstringxxx"))
(test::assert-equal '("some" "yyy" "string") (str-split :whitespace "some yyy string"))
(test::assert-equal '("somexxxyyyxxxstring") (str-split :whitespace "somexxxyyyxxxstring"))
(test::assert-equal '("somexxxyyyxxxstring") (str-split "zzz" "somexxxyyyxxxstring"))
str-splitn |
Type: Function |
root::str-splitn |
Usage: (str-splitn n split-pattern string) -> vector |
Use a pattern to split a string with at most n items.
Example:
(test::assert-equal '("some" "yyy" "string") (str-splitn 3 "xxx" "somexxxyyyxxxstring"))
(test::assert-equal '("some" "yyy" "string") (str-splitn 4 "xxx" "somexxxyyyxxxstring"))
(test::assert-equal '("some" "yyy" "stringxxxother") (str-splitn 3 "xxx" "somexxxyyyxxxstringxxxother"))
(test::assert-equal '("somexxxyyyxxxstringxxxother") (str-splitn 1 "xxx" "somexxxyyyxxxstringxxxother"))
(test::assert-equal '() (str-splitn 0 "xxx" "somexxxyyyxxxstringxxxzero"))
str-starts-with |
Type: Function |
root::str-starts-with |
Usage: (str-starts-with pattern string) -> t/nil |
True if string start with pattern (both strings).
Example:
(test::assert-true (str-starts-with "Stau" "Stausomething"))
(test::assert-false (str-starts-with "StaU" "Stausomething"))
str-sub |
Type: Function |
root::str-sub |
Usage: (str-sub string start [length]) -> string |
Return a substring from a string given start (0 based) and optional length. If length is 0 or not provided produces the rest of the string from start to string end.
Example:
(test::assert-equal "string" (str-sub "stringxxxyyyxxxsome" 0 6))
(test::assert-equal "some" (str-sub "stringxxxyyyxxxsome" 15 4))
(test::assert-equal "yyy" (str-sub "stringxxxyyyxxxsome" 9 3))
(test::assert-equal "some" (str-sub "stringxxxyyyxxxsome" 15))
str-trim |
Type: Function |
root::str-trim |
Usage: (str-trim string) -> string |
Trim right and left whitespace from string.
Example:
(test::assert-equal "some string" (str-trim " some string"))
(test::assert-equal "some string" (str-trim " some string "))
(test::assert-equal "some string" (str-trim (str " some string ")))
(test::assert-equal "some string" (str-trim "some string "))
(test::assert-equal "some string" (str-trim "some string"))
str-upper |
Type: Function |
root::str-upper |
Usage: (str-upper string) -> string |
Get all upper case string from a string.
Example:
(test::assert-equal "STAU" (str-upper "STAU"))
(test::assert-equal "STAU" (str-upper "stau"))
(test::assert-equal "STAU" (str-upper "Stau"))
(test::assert-equal "STAU" (str-upper "StaU"))
(test::assert-equal "STAU" (str-upper "sTaU"))
with-padding |
Type: Lambda |
root::with-padding |
Usage: (with-padding target padding padding-char &rest padding-keyword) |
Given a “target” string, a keyword specifying the type of padding, an integer length to pad to “padding”, and a character to use for padding “padding-char”, return a string with length equal to the specified padding length, only if the target string is less than the amount of padding specified. The resultant string defaults to right padding and is composed of the target string followed by “padding” number of “padding-char”. If left or center padding is desired pass one of the keywords :left or :center as the final argument to the function. For completeness, the keyword :right is also supported.
Example:
(test::assert-equal "test......" (with-padding "test" 10 "."))
(test::assert-equal "test......" (with-padding "test" 10 "." :right))
(test::assert-equal "......test" (with-padding "test" 10 "." :left))
(test::assert-equal "...test..." (with-padding "test" 10 "." :center))
(test::assert-equal "..tests..." (with-padding "tests" 10 "." :center))
Struct forms
defstruct |
Type: Macro |
struct::defstruct |
Usage: (defstruct name &rest fields) |
Define a structure. This produces a lambda with name that will create an instance. Each ‘field’ will add an attribute, method or trait. Use (attr-name doc-str? default? [:rw | :ro | :wo]?) if a final access modifier is not provided then it is private. NOTE: for attributes, if the default value is a string then doc-str is not optional (but can be empty). Use (:fn name doc-str? body) to add a method. Use (:impl trait) to add a trait.
Example:
(struct::defstruct test-struct
; fields
(a "a private attribute" nil)
(b "a read/write attribute" "bee" :rw)
(c "a read only attribute" "see" :ro)
(d "a write only attribute" "dee" :wo)
; methods
(:fn what-d (self) d)
(:fn what-a (self) a))
(def ts (test-struct))
(assert-equal nil (ts :what-a))
(assert-equal "dee" (ts :what-d))
(ts :set-d "something else")
(assert-equal "something else" (ts :what-d))
(assert-equal "bee" (ts :b))
(assert-equal "see" (ts :c))
(ts :set-b "queen")
(assert-equal "queen" (ts :b))
deftrait |
Type: Macro |
struct::deftrait |
Usage: (deftrait name &rest fields) |
Define a trait. Traits define methods that are added to structures (and usually require one or more methods in the struct. Use them to provide common functionality shared by different structures. Use (:fn name doc-str? body) to add a method.
Example:
(ns-push 'test-deftrait)
(struct::deftrait test-trait
; Require what-a and what-d in the structures that implement this trait.
(:fn aaa (self) (self :what-a))
(:fn ddd (self) (self :what-d)))
(struct::defstruct test-struct
; fields
(a "a private attribute" nil)
(b "a read/write attribute" "bee" :rw)
(c "a read only attribute" "see" :ro)
(d "a write only attribute" "dee" :wo)
; methods
(:fn what-d (self) d)
(:fn what-a (self) a)
(:impl test-deftrait::test-trait))
(def ts (test-struct))
(test::assert-equal nil (ts :aaa))
(test::assert-equal "dee" (ts :ddd))
(ts :set-d "something else")
(test::assert-equal "something else" (ts :ddd))
(test::assert-equal "bee" (ts :b))
(test::assert-equal "see" (ts :c))
(ts :set-b "queen")
(test::assert-equal "queen" (ts :b))
(ns-pop)
System forms
bg |
Type: Function |
root::bg |
Usage: (bg job-id?) |
Put a job in the background. If no job id is specified use the last job.
Example:
;(bg)
#t
exit |
Type: Function |
root::exit |
Usage: (exit code?) |
Exit shell with optional status code.
Example:
; Exit is overridden in the test harness...
;(test::assert-equal 10 (wait (fork (exit 10))))
;(test::assert-equal 11 (wait (fork (exit 11))))
;(test::assert-equal 12 (wait (fork (exit 12))))
#t
export |
Type: Function |
root::export |
Usage: (export symbol string) -> string |
Export a key and value to the shell environment. Second arg will be made a string and returned. Key can not contain the ‘=’ character.
Example:
(test::assert-equal "ONE" (export 'TEST_EXPORT_ONE "ONE"))
(test::assert-equal "ONE" $TEST_EXPORT_ONE))
(test::assert-equal "ONE1" (export 'TEST_EXPORT_ONE ONE1))
(test::assert-equal "ONE1" $TEST_EXPORT_ONE))
(test::assert-equal "TWO" (export "TEST_EXPORT_TWO" "TWO"))
(test::assert-equal "TWO" $TEST_EXPORT_TWO))
(test::assert-equal "THREE" $(export TEST_EXPORT_THREE THREE))
(test::assert-equal "THREE" $TEST_EXPORT_THREE))
(test::assert-error (export '=TEST_EXPORT_THREE "THREE"))
(test::assert-error (export 'TEST=EXPORT_THREE "THREE"))
(test::assert-error (export 'TEST_EXPORT_THREE= "THREE"))
(test::assert-error $(export TEST_EXPORT_THREE= THREE))
fg |
Type: Function |
root::fg |
Usage: (fg job-id?) |
Put a job in the foreground. If no job id is specified use the last job.
Example:
;(fg)
#t
fork |
Type: SpecialForm |
root::fork |
Usage: (fork exp) -> process |
Forks the provided expression in the background as a job and returns the process object. If the expression that is forked returns an integer (that fits an i32) then it will become the exit code. Calling exit explicitly will also set the exit code. Otherwise exit code is 0 for success and 1 for an error.
Example:
(def fork-test (fork (+ (* 11 5) 2)))
(test::assert-equal 57 (wait fork-test))
(def fork-time (time (wait (fork (sleep 1000)))))
(test::assert-true (> fork-time 1.0))
get-env |
Type: SpecialForm |
root::get-env |
Usage: (get_env key) -> string |
Lookup key in the system environment (env variable). Returns an empty sting if key does not exist. Note: key is not evaluated.
Example:
(test::assert-equal "ONE" (export 'TEST_EXPORT_ONE "ONE"))
(test::assert-equal "ONE" $TEST_EXPORT_ONE))
(test::assert-equal "ONE" (get-env TEST_EXPORT_ONE))
(test::assert-equal "" (get-env TEST_EXPORT_ONE_NA))
get-pid |
Type: Function |
root::get-pid |
Usage: (get-pid) |
Return the pid of running process (shell).
Example:
(test::assert-true (int? (get-pid)))
jobs |
Type: Function |
root::jobs |
Usage: (jobs) |
Print list of jobs with ids.
Example:
;(jobs)
#t
pid |
Type: Function |
root::pid |
Usage: (pid proc) |
Return the pid of a process.
Example:
(def pid-test (syscall 'echo "-n"))
(test::assert-true (int? (pid pid-test)))
(test::assert-true (int? (pid (fork ((fn () nil))))))
(test::assert-error (pid 1))
pipe |
Type: Function |
root::pipe |
Usage: (pipe [expression]+) |
Setup a pipe between processes or expressions. Pipe will take one or more expressions, each one but the last will be forked into a new process with it’s stdin being the output of the last expression. The first expression uses the current stdin and the last expression outputs to the current stdout. Pipe works with system commands as well as sl-sh forms (lambdas, etc). Note it connects the stdin/stdout of processes so if used with a lambda it should read stdin to get the previous output and write to stdout to pass to the next expression in the pipe (i.e. pipe will not interact with parameters or anything else). If pipe starts with :err then stderr will also be piped into the output, ie (pipe :err (…)(…)…). Pipes also support using a read file as the first expression (the file contents become stdin for the next form) and a write file as the last expression (previous output will be written to the file). For instance pipe can be used to copy a file with (pipe (open IN_FILE :read)(open OUT_FILE :create)), note this example does not close the files. Pipes can be nested including piping through a lambda that itself uses pipes. Pipe will return a multiple values, the first/primary is the final form for the pipe and the process objects for each part of the pipe are next (first element can be found with (values-nth 1 return-val), etc).
Example:
(def pipe-test (str (pipe (print "one
two
three")(syscall 'grep "two"))))
(test::assert-equal "two
" pipe-test)
(def pipe-test (str (pipe (pipe (syscall 'echo "one
two
twotwo
three")(syscall 'grep "two"))(syscall 'grep "twotwo"))))
(test::assert-equal "twotwo
" pipe-test)
(def pipe-test-dir (str (temp-dir)"/tst-pipe-dir"))
$(mkdir $pipe-test-dir)
(def tsync (open "${pipe-test-dir}/test1" :create))
(pipe (print "one
two
two2
three") (syscall 'grep "two") tsync)
(close tsync)
(def topen (open "${pipe-test-dir}/test1" :read))
(test::assert-equal "two
" (read-line topen))
(test::assert-equal "two2
" (read-line topen))
(test::assert-false (read-line topen))
(close topen)
(def topen (open "${pipe-test-dir}/test1" :read))
(def pipe-test (str (pipe topen (syscall 'grep "two2"))))
(close topen)
(test::assert-equal "two2
" pipe-test)
$(rm "${pipe-test-dir}/test1")
(let ((file-name "${pipe-test-dir}/pipe-err.test")
(fin))
(err> (open "${pipe-test-dir}/pipe-test.junk" :create) (do
(pipe (eprintln "error")(do (print *stdin*)(println "normal"))(open file-name :create :truncate))
(set! fin (open file-name :read))
(test::assert-equal "normal\n" (read-line fin))
(test::assert-equal nil (read-line fin))
(close fin)
(pipe :err (eprintln "error")(do (print *stdin*)(println "normal"))(open file-name :create :truncate))
(set! fin (open file-name :read))
(test::assert-equal "error\n" (read-line fin))
(test::assert-equal "normal\n" (read-line fin))
(close fin)))
$(rm "${pipe-test-dir}/pipe-test.junk")
$(rm $file-name)
)
$(rmdir $pipe-test-dir)
reap-jobs |
Type: Function |
root::reap-jobs |
Usage: (reap-jobs) -> nil |
Reaps any completed jobs. Only intended to be used by code implemeting the REPL loop or something similiar, this is probably not the form you are searching for.
Example:
;(reap-jobs)
#t
sleep |
Type: Function |
root::sleep |
Usage: (sleep milliseconds) -> nil |
Sleep for the provided milliseconds (must be a positive integer).
Example:
(def test-sleep-var (time (sleep 1000)))
(assert-true (> test-sleep-var 1.0))
syscall |
Type: Function |
root::syscall |
Usage: (syscall system-command arg0 ... argN) |
Execute the provided system command with the supplied arguments. System-command can evalute to a string or symbol. The args (0..n) are evaluated.
Example:
(def test-syscall-one (str (syscall "echo" "-n" "syscall-test")))
(test::assert-equal "syscall-test" test-syscall-one)
(def test-syscall-one (str (syscall 'echo "-n" "syscall-test2")))
(test::assert-equal "syscall-test2" test-syscall-one)
(def test-syscall-echo "echo")
(def test-syscall-one (str (syscall test-syscall-echo "-n" "syscall-test3")))
(test::assert-equal "syscall-test3" test-syscall-one)
time |
Type: Function |
root::time |
Usage: (time form) -> eval-time |
Evalutes the provided form and returns the seconds it ran for (as float with fractional part).
Example:
(def test-sleep-var (time (sleep 1100)))
(assert-true (> test-sleep-var 1.1))
umask |
Type: Function |
root::umask |
Usage: (umask [mask]) |
Takes 0 or 1 argument(s). If no arguments are provided the current file mode creation mask will be returned. The value returned is the new value of the mask as an octal string (which can be fed back into the umask form if needed). If an argument is provided that value will be interpreted as a mask, applied, and the new file mask creation mask will be returned. Specify mask as an integer in octal form, or a string in the form of a symbolic mode mask (see fig. a). When an integer is provided the value replaces the current value of the file creation mode mask. When a string is provided as a symbolic mode mask the current value of the system’s umask is used to generate the new mask according to the specifications of the provided permissions operator. By default most Linux distros will set it to 022 or 002. If provided mode begins with a digit, it is interpreted as an octal number; if not, it is interpreted as a symbolic mode mask. $> umask a+rw,go-x => 0011 ;;; all users can read and write, only user can execute. $> umask 027 => 0027 ;;; user can read, write and execute, group can read and write but not execute, and other has none. $> umask u-x => 0122 ;;; user can not execute, unspecified permissions are left unchanged from default, 0022. ;;; fig. a ;;; ;;; symbolic mode mask: ;;; - [user class symbol(s)][permissions operator][permission symbol(s)][,]… ;;; - valid user class symbols: ‘u’, ‘g’, ‘o’, ‘a’ ;;; - ‘u’: the owner user ;;; - ‘g’: the owner group ;;; - ‘o’: others (not ‘u’ or ‘g’) ;;; - ‘a’: all users ;;; - valid permissions operators: ‘+’, ‘-‘, ‘=’ ;;; - ‘+’: enables specified permissions for user classes and leaves unspecified permissions ;;; unchanged ;;; - ‘-‘: disables specified permissions for user classes and leaves unspecified permissions ;;; unchanged ;;; - ‘=’: allow the specified permisssions for the specified user classes, permissions for ;;; unspecified user class remain unchanged. ;;; - valid permission symbols: ‘r’, ‘w’, x’ ;;; - ‘r’ ;;; - file is viewble ;;; - directory’s contents can be viewed ;;; - ‘w’ ;;; - file can be created, edited, or deleted ;;; - directory allows file creation and deletion. ;;; - ‘x’ ;;; - file is executable ;;; - directory can be entered ‘cd’ or contents can be executed. ;;; - one of the user class symbols or valid permission symbols can be left blank to specify all ;;; symbols.
Example:
#t
unexport |
Type: Function |
root::unexport |
Usage: (unexport symbol) |
Remove a var from the current shell environment.
Example:
(test::assert-equal "ONE" (export 'TEST_EXPORT_ONE "ONE"))
(test::assert-equal "ONE" $TEST_EXPORT_ONE))
(unexport 'TEST_EXPORT_ONE)
(test::assert-equal "" $TEST_EXPORT_ONE))
wait |
Type: Function |
root::wait |
Usage: (wait proc-to-wait-for) |
Wait for a process to end and return it’s exit status. Wait can be called multiple times if it is given a process object (not just a numeric pid).
Example:
(def wait-test (wait (err>null (syscall 'ls "/does/not/exist/123"))))
(test::assert-true (> wait-test 0))
(def wait-test2 (fork (* 11 5)))
(test::assert-equal 55 (wait wait-test2))
(test::assert-equal 55 (wait wait-test2))
(test::assert-equal 55 (wait wait-test2))
Test forms
assert-equal |
Type: Lambda |
test::assert-equal |
Usage: (assert-equal expected-val right-val &rest args) |
Test expected-val and right-val for equality.
Example:
(test::assert-true (test::assert-equal 1 1))
(test::assert-false (test::assert-equal (list 1 2) (list 1)))
(test::assert-true (test:: assert-equal (list 1 2) (list 1 2)))
assert-error |
Type: Macro |
test::assert-error |
Usage: (assert-error form) |
Test asserts an error is thrown.
Example:
(test::assert-error (err "error thrown"))
assert-error-msg |
Type: Macro |
test::assert-error-msg |
Usage: (assert-error-msg form msg) |
Test asserts an error is thrown with a given message.
Example:
(test::assert-error-msg (err "error thrown") "error thrown")
assert-false |
Type: Lambda |
test::assert-false |
Usage: (assert-false value &rest args) |
Test for falsiness.
Example:
(test::assert-false #f)
(test::assert-false nil)
assert-not-equal |
Type: Lambda |
test::assert-not-equal |
Usage: (assert-not-equal expected-val right-val &rest args) |
Test expected-val and right-val are not equal.
Example:
(test::assert-false (test::assert-not-equal 1 1))
(test::assert-true (test::assert-not-equal 1 2))
(test::assert-false (test::assert-not-equal (list 1 2 3) (list 1 2 3))
assert-true |
Type: Lambda |
test::assert-true |
Usage: (assert-true value &rest args) |
Test for truthiness.
Example:
(test::assert-true #t)
run-example |
Type: Macro |
test::run-example |
Usage: (run-example sym) |
Given a symbol, run any tests found in example section if exists.
Threading-macros forms
-> |
Type: Macro |
root::-> |
Usage: (-> &rest args) |
inserts result of previous expression as second argument to current expression. First argument is not evaluated.
Example:
(assert-equal
(str "I go at the beginning.I'll be stuck in the middle.I'll be at the end.")
(-> "I go at the beginning."
(str "I'll be stuck in the middle.")
(str "I'll be at the end.")))
->> |
Type: Macro |
root::->> |
Usage: (->> &rest args) |
inserts result of previous expression as last argument to current expression. First argument is not evaluated.
Example:
(assert-equal
(str "I'll be at the beginning.I'll be more in the middle.I go at the end.")
(->> "I go at the end."
(str "I'll be more in the middle.")
(str "I'll be at the beginning.")))
chain |
Type: Macro |
root::chain |
Usage: (chain init arg0 &rest args) |
Inserts result of previous expression into place indicated by the _ symbol in the next expression. This macro is useful when nested actions need to occur but when a more sequential enumeration of steps is preferable. To demonstrate a sequence of operations: (fn (x) (delta (charlie (bravo (alpha x))))) can be unwound, and more idiomatically stated with the chain macro: (fn (x) (chain x (alpha _) (bravo _) (charlie _) (delta _))) The flexibility of using the _ symbol as a placeholder means subsequent results can be “threaded” into any desired place in a clause which is an advantage over the thread first, -> and thread last, -», macros
Example:
(test::assert-equal "Ordered sentence: I will become a properly worded statement."
(chain "a properly worded "
(str "will " "become " _)
(str "I " _ "statement.")
(str "Ordered sentence: " _)))
(test::assert-equal 3 (chain 7 (% _ 4)))
(test::assert-equal 9 (chain 7 (% _ 4) (+ 1 8)))
(test::assert-equal (list 6 12 18) (collect (chain 7
(% _ 4)
(range _ 10)
(map (fn (x) (* x 2)) _)
(filter (fn (x) (= 0 (% x 3))) _))))
chain-and |
Type: Macro |
root::chain-and |
Usage: (chain-and init arg0 &rest args) |
Evaluates each sexp, if true, inserts result of previous expression into place indicated by the _ symbol. This macro is useful when nested actions need to take place but the operations should stop and return nil if any step evaluates to false.
Example:
(test::assert-false (chain-and "howdy" (string? _) (= _ "howdy")))
(test::assert-true (chain-and "howdy" (str _ " partner") (= _ "howdy partner")))
(defn formatted? (alleged-time-str)
(let* ((do-fst (fn (tst start end)
(fn (orig-string)
(let ((result (get-error
(chain orig-string
(str-sub _ start (- end start))
(str->int _)
(tst _)))))
(if (= :ok (car result))
(if (cdr result) orig-string nil)
nil)))))
(valid-year? (do-fst (fn (x) (> x -1)) 0 4))
(valid-month? (do-fst (fn (x) (and (> x 0) (< x 13))) 4 6))
(valid-day? (do-fst (fn (x) (and (> x 0) (< x 32))) 6 8))
(valid-hour? (do-fst (fn (x) (and (> x 0) (< x 24))) 9 11))
(valid-minute? (do-fst (fn (x) (and (> x -1) (< x 60))) 11 13))
(valid-second? (do-fst (fn (x) (and (> x -1) (< x 60))) 13 15))
(is-zulu? (fn (orig-string) (= "Z" (str-sub orig-string 15 1)))))
(chain-and alleged-time-str
(valid-year? _)
(valid-month? _)
(valid-day? _)
(valid-hour? _)
(valid-minute? _)
(valid-second? _)
(is-zulu? _)
#t)))
(test::assert-true (formatted? "20210227T154705Z"))
(test::assert-false (formatted? "20210227T154705P"))
(test::assert-false (formatted? "2021022TT154705Z"))
(test::assert-false (formatted? "20210237T154705Z"))
(test::assert-false (formatted? "2021222TT154705Z"))
(test::assert-false (formatted? "20210227T254705Z"))
(test::assert-false (formatted? "20210227T158705Z"))
(test::assert-false (formatted? "20210227T154795Z"))
chain-when |
Type: Macro |
root::chain-when |
Usage: (chain-when init arg0 &rest args) |
Tests the car of each arg0/args pair. If true the cdr of the arg0/args pair is evaluated. The chaining component of this macro works by threading init through the cdr of each pair whose car evaluates to true. Useful for building or modifying an object based on a set of boolean conditions.
Example:
(defn add-number-attributes (n)
(chain-when (make-hash)
((not (= (% n 2) 0)) (hash-set! _ :property :odd))
((= (% n 2) 0) (hash-set! _ :property :even))
((= 0 n) (hash-set! _ :zero :zero))
((= 42 n) (err "N CAN NOT BE 42"))
((> n 0) (hash-set! _ :symmetry :positive))
((< n 0) (hash-set! _ :symmetry :negative))))
(test::assert-equal :odd (hash-get (add-number-attributes 3) :property))
(test::assert-equal :even (hash-get (add-number-attributes 4) :property))
(test::assert-false (hash-get (add-number-attributes 4) :zero))
(test::assert-equal :positive (hash-get (add-number-attributes 4) :symmetry))
(test::assert-equal :negative (hash-get (add-number-attributes -4) :symmetry))
(test::assert-equal :zero (hash-get (add-number-attributes 0) :zero))
(test::assert-error-msg (add-number-attributes 42) "N CAN NOT BE 42")
Type forms
These forms provide information/tests about an objects underlying type.
boolean? |
Type: Function |
root::boolean? |
Usage: (boolean? expression) |
True if the expression is true(#t) or false(#f), false otherwise.
Example:
(test::assert-true (boolean? #f))
(test::assert-true (boolean? #t))
(test::assert-false (boolean? nil))
(test::assert-false (boolean? nil))
(test::assert-false (boolean? 1))
(test::assert-false (boolean? "str"))
builtin? |
Type: Function |
root::builtin? |
Usage: (builtin? expression) |
True if the expression is a builtin function or special form, false otherwise.
Example:
(test::assert-true (builtin? type))
(test::assert-true (builtin? if))
(test::assert-false (builtin? (fn () ())))
(test::assert-false (builtin? caar))
(test::assert-false (builtin? 1))
char? |
Type: Function |
root::char? |
Usage: (char? expression) |
True if the expression is a char, false otherwise.
Example:
(test::assert-true (char? #\a))
(test::assert-false (char? 1))
(test::assert-false (char? "a"))
false? |
Type: Function |
root::false? |
Usage: (false? expression) |
True if the expression is false(#f) (false type NOT nil), false otherwise.
Example:
(test::assert-true (false? #f))
(test::assert-false (false? nil))
(test::assert-false (false? nil))
(test::assert-false (false? 1))
(test::assert-false (false? "str"))
falsey? |
Type: Function |
root::falsey? |
Usage: (falsey? under-test) -> bool |
Returns true if the expression under-test evaluates to nil or false.
Example:
(test::assert-true (falsey? nil))
(test::assert-true (falsey? #f))
(test::assert-false (falsey? #t))
(test::assert-false (falsey? "false"))
file? |
Type: Function |
root::file? |
"Usage: (file? expression) |
True if the expression is a file, false otherwise.
Example:
(test::assert-true (file? (open :stdout)))
(test::assert-false (file? (fn () ())))
(test::assert-false (file? caar))
(test::assert-false (file? 1))
float->int |
Type: Function |
root::float->int |
Usage: (float->int float) -> int |
Cast a float as an int. Narrows the float if necessary to the max allowable int. If float is NaN 0 is returned.
Example:
(test::assert-equal 0 (float->int 0.0))
(test::assert-equal 10 (float->int 10.0))
(test::assert-equal 10 (float->int 10.1))
(test::assert-equal 10 (float->int 10.5))
(test::assert-equal 10 (float->int 10.9))
(test::assert-equal -101 (float->int -101.99))
(test::assert-error (float->int "not int"))
float? |
Type: Function |
root::float? |
Usage: (float? expression) |
True if the expression is a float, false otherwise.
Example:
(test::assert-true (float? 1.5))
(test::assert-false (float? 1))
func? |
Type: Macro |
root::func? |
Usage: (func? to-test) |
True if the expression is a builtin?, a lambda?, or a macro?
Example:
(def func?-test 1)
(test::assert-false (func? func?-test))
(test::assert-true (func? car))
(test::assert-true (func? first))
(test::assert-true (func? let))
hash? |
Type: Function |
root::hash? |
Usage: (hash? expression) |
True if the expression is a hash map, false otherwise.
Example:
(test::assert-true (hash? (make-hash)) "make-vec")
(test::assert-false (hash? 1))
(test::assert-false (hash? '(1 2 3)))
(test::assert-false (hash? (list)))
(test::assert-false (hash? (vec)))
int->float |
Type: Function |
root::int->float |
Usage: (int->float int) -> float |
Cast an int as a float.
Example:
(test::assert-equal 0 (int->float 0))
(int->float 10))
(test::assert-equal -101 (int->float -101))
(test::assert-error (int->float "not int"))
int? |
Type: Function |
root::int? |
Usage: (int? expression) |
True if the expression is an int, false otherwise.
Example:
(test::assert-true (int? 1))
(test::assert-false (int? 1.5))
lambda? |
Type: Function |
root::lambda? |
Usage: (lambda? expression) |
True if the expression is a lambda, false otherwise.
Example:
(test::assert-true (lambda? (fn () ())))
(test::assert-true (lambda? caar))
(test::assert-false (lambda? 1))
(test::assert-false (lambda? if))
list? |
Type: Function |
root::list? |
Usage: (list? expression) |
True if the expression is a list, false otherwise.
Example:
(test::assert-true (list? '(1 2 3)) "reader macro")
(test::assert-true (list? (list 1 2 3)) "list")
(test::assert-false (list? 1))
(test::assert-false (list? '#(1 2 3)))
(test::assert-false (list? (vec)))
(test::assert-false (list? '(1 . 2)))
macro? |
Type: Function |
root::macro? |
Usage: (macro? expression) |
True if the expression is a macro, false otherwise.
Example:
(test::assert-true (macro? (macro () ())))
(test::assert-true (macro? defn))
(test::assert-false (macro? 1))
(test::assert-false (macro? if))
nil? |
Type: Function |
root::nil? |
Usage: (nil? expression) |
True if the expression is nil, false otherwise.
Example:
(test::assert-true (nil? nil))
(test::assert-false (nil? #t))
none? |
Type: Function |
root::none? |
Usage: (none? expression) |
True if the expression is nil (aka none/nothing), false otherwise.
Example:
(test::assert-true (none? nil))
(test::assert-true (none? '()))
(test::assert-false (none? #t))
(test::assert-false (none? '(1)))
pair? |
Type: Function |
root::pair? |
Usage: (pair? expression) |
True if the expression is a pair, false otherwise.
Example:
(test::assert-true (pair? '(1 . 2)) "reader macro")
(test::assert-true (pair? (join 1 2)) "join")
(test::assert-true (pair? '(1 2)))
(test::assert-false (pair? 1))
(test::assert-false (pair? '#(1 2 3)))
(test::assert-false (pair? (vec)))
process? |
Type: Function |
root::process? |
Usage: (process? expression) |
True if the expression is a process, false otherwise.
Example:
(test::assert-true (process? (syscall 'true)))
(test::assert-true (process? (fork ((fn () nil)))))
(test::assert-false (process? (fn () ())))
(test::assert-false (process? caar))
(test::assert-false (process? 1))
regex? |
Type: Function |
root::regex? |
Usage: (regex? expression) |
True if the expression is a regex, false otherwise.
Example:
(test::assert-true (regex? (make-regex "\d{2}-\d{2}-\d{4}")))
(test::assert-true (regex? #/[a-z]+/))
(test::assert-false (regex? 1.5))
some? |
Type: Function |
root::some? |
Usage: (some? expression) |
True if the expression is NOT nil (aka something), false otherwise. Note that anything other then nil (including false) is something.
Example:
(test::assert-false (some? nil))
(test::assert-false (some? '()))
(test::assert-true (some? #t))
(test::assert-true (some? '(1)))
str->float |
Type: Function |
root::str->float |
Usage: (str->float string) -> float |
If string is a valid representation of a float return that float. Error if not.
Example:
(test::assert-equal 0 (str->float "0"))
(test::assert-equal 10.0 (str->float "10.0"))
(test::assert-equal 10.5 (str->float "10.5"))
(test::assert-equal 101 (str->float "101"))
(test::assert-equal -101.95 (str->float "-101.95"))
(test::assert-error (str->float "not int"))
(test::assert-error (str->float "--10"))
str->int |
Type: Function |
root::str->int |
Usage: (str->int string) -> int |
If string is a valid representation of an integer return that int. Error if not.
Example:
(test::assert-equal 0 (str->int "0"))
(test::assert-equal 101 (str->int "101"))
(test::assert-equal -101 (str->int "-101"))
(test::assert-error (str->int "not int"))
(test::assert-error (str->int "10.0"))
(test::assert-error (str->int "--10"))
string? |
Type: Function |
root::string? |
Usage: (string? expression) |
True if the expression is a string, false otherwise.
Example:
(test::assert-true (string? "string"))
(test::assert-false (string? 1))
sym |
Type: Function |
root::sym |
Usage: (sym expression+) -> symbol |
Takes one or more forms, converts them to strings, concatenates them and returns a symbol with that name.
Example:
(def test-to-symbol-sym nil)
(test::assert-true (symbol? (sym 55)))
(test::assert-true (symbol? (sym 55.0)))
(test::assert-true (symbol? (sym "to-symbol-test-new-symbol")))
(test::assert-true (symbol? (sym (str "to-symbol-test-new-symbol-buf"))))
(test::assert-true (symbol? (sym 'test-to-symbol-sym)))
(set! test-to-symbol-sym "testing-sym")
(test::assert-equal "testing-sym" (sym->str (sym test-to-symbol-sym)))
(test::assert-true (symbol? (sym (sym->str 'test-to-symbol-sym))))
sym->str |
Type: Function |
root::sym->str |
Usage: (sym->str symbol) -> string |
Convert a symbol to the string representation representation of it’s name. The string will be the symbol name as a string.
Example:
(def test-sym->str-sym nil)
(test::assert-true (string? (sym->str 'test-sym->str-sym)))
(test::assert-equal "test-sym->str-sym" (sym->str 'test-sym->str-sym))
symbol? |
Type: Function |
root::symbol? |
Usage: (symbol? expression) |
True if the expression is a symbol, false otherwise.
Example:
(test::assert-true (symbol? 'symbol))
(test::assert-false (symbol? 1))
true? |
Type: Function |
root::true? |
Usage: (true? expression) |
True if the expression is true(#t) (true type NOT non-nil), false otherwise.
Example:
(test::assert-true (true? #t))
(test::assert-false (true? #f))
(test::assert-false (true? nil))
(test::assert-false (true? 1))
(test::assert-false (true? "str"))
type |
Type: Function |
root::type |
Usage: (type expression) |
Return the type of the given expression as a string. Types are: True False Float Int Symbol String Char Lambda Macro Process SpecialForm Function Vector Pair Nil HashMap File
Example:
(test::assert-equal "True" (type #t))
(test::assert-equal "False" (type #f))
(test::assert-equal "Float" (type 1.1))
(test::assert-equal "Int" (type 1))
(test::assert-equal "Symbol" (type 'symbol))
(def type-sym 'symbol)
(test::assert-equal "Symbol" (type type-sym))
(test::assert-equal "String" (type "string"))
(test::assert-equal "Char" (type #\a))
(test::assert-equal "Lambda" (type (fn () ())))
(test::assert-equal "Macro" (type (macro () ())))
(test::assert-equal "Process" (type (syscall 'true)))
(test::assert-equal "SpecialForm" (type if))
(test::assert-equal "Function" (type type))
(test::assert-equal "Vector" (type '#(1 2 3)))
(def type-vec '#(4 5 6))
(test::assert-equal "Vector" (type type-vec))
(test::assert-equal "Pair" (type '(1 . 2)))
(test::assert-equal "Pair" (type '(1 2 3)))
(test::assert-equal "Nil" (type nil))
(test::assert-equal "Nil" (type '()))
(test::assert-equal "HashMap" (type (make-hash)))
(test::assert-equal "File" (type (open :stdin)))
values? |
Type: Function |
root::values? |
Usage: (values? expression) |
True if the expression is multi values object, false otherwise. NOTE: A values object will ALSO be the type of its first value.
Example:
(test::assert-true (values? (values 1 "str" 5.5)))
(test::assert-false (values? '(1 2 3)))
(test::assert-false (values? '(1 . 3)))
(test::assert-false (values? 1))
(test::assert-true (int? (values 1 "str" 5.5)))
(test::assert-false (string? (values 1 "str" 5.5)))
(test::assert-false (float? (values 1 "str" 5.5)))
(def test-is-values (values 1 2 3 "string" 1.5))
(test::assert-true (values? test-is-values))
(test::assert-true (int? test-is-values))
(test::assert-false (string? test-is-values))
(test::assert-false (float? test-is-values))
vec? |
Type: Function |
root::vec? |
Usage: (vec? expression) |
True if the expression is a vector, false otherwise.
Example:
(test::assert-true (vec? '#(1 2 3)) "reader macro")
(test::assert-true (vec? (make-vec)) "make-vec")
(test::assert-true (vec? (vec 1 2 3)) "vec")
(test::assert-false (vec? 1))
(test::assert-false (vec? '(1 2 3)))
(test::assert-false (vec? (list)))
Vector forms
Forms ending in ‘!’ are destructive and change the underlying vector, other forms do not make changes to the the provided vector. They are usable in place of a list for purposes of lambda calls, parameters, etc (they work the same as a list made from pairs but are vectors not linked lists). Use #() to declare them in code (i.e. ‘#(1 2 3) or #(+ 1 2)).
make-vec |
Type: Function |
root::make-vec |
Usage: (make-vec capacity default) |
Make a new vector with capacity and default item(s).
Example:
(test::assert-equal '() (make-vec))
(test::assert-equal '(x x x) (make-vec 3 'x))
(test::assert-equal '(nil nil nil nil nil) (make-vec 5 nil))
(test::assert-equal '() (make-vec 5))
vec |
Type: Function |
root::vec |
Usage: (vec item1 item2 .. itemN) |
Make a new vector with items.
Example:
(test::assert-equal '() (vec))
(test::assert-equal '(1 2 3) (vec 1 2 3))
vec-clear! |
Type: Function |
root::vec-clear! |
Usage: (vec-clear! vector) |
Clears a vector. This is destructive!
Example:
(def test-clear-vec (vec 1 2 3))
(test::assert-false (vec-empty? test-clear-vec))
(vec-clear! test-clear-vec)
(test::assert-true (vec-empty? test-clear-vec))
vec-empty? |
Type: Function |
root::vec-empty? |
Usage: (vec-empty? vector) |
True if the vector is empty.
Example:
(test::assert-true (vec-empty? '#()))
(test::assert-false (vec-empty? '#(1 2 3)))
vec-insert! |
Type: Function |
root::vec-insert! |
Usage: (vec-insert! vector index new-element) -> vector |
Inserts new-element at index and moves following elements right in vector. This is destructive!
Example:
(def test-insert-nth-vec (vec 1 2 3))
(test::assert-equal '(1 2 3) test-insert-nth-vec)
(vec-insert! test-insert-nth-vec 1 5)
(test::assert-equal '(1 5 2 3) test-insert-nth-vec)
(vec-insert! test-insert-nth-vec 2 6)
(test::assert-equal '(1 5 6 2 3) test-insert-nth-vec)
(vec-insert! test-insert-nth-vec 0 4)
(test::assert-equal '(4 1 5 6 2 3) test-insert-nth-vec)
vec-nth |
Type: Function |
root::vec-nth |
Usage: (vec-nth vector index) -> object |
Get the nth element (0 based) of a vector. If you need the equivalent operation on a list use nth.
Example:
(test::assert-equal 5 (vec-nth '#(1 2 3 4 5 6) 4))
(test::assert-equal 1 (vec-nth '#(1 2 3 4 5 6) 0))
(test::assert-equal 3 (vec-nth '#(1 2 3 4 5 6) 2))
(test::assert-equal 6 (vec-nth '#(1 2 3 4 5 6) 5))
vec-pop! |
Type: Function |
root::vec-pop! |
Usage: (vec-pop! vector) -> object |
Pops the last object off of the end of the vector. This is destructive!
Example:
(def test-pop-vec (vec 1 2 3))
(test::assert-equal 3 (vec-pop! test-pop-vec))
(test::assert-equal '(1 2) test-pop-vec)
(test::assert-equal 2 (vec-pop! test-pop-vec))
(test::assert-equal '(1) test-pop-vec)
(test::assert-equal 1 (vec-pop! test-pop-vec))
(test::assert-equal '() test-pop-vec)
vec-push! |
Type: Function |
root::vec-push! |
Usage: (vec-push! vector object) -> vector |
Pushes the provided object onto the end of the vector. This is destructive!
Example:
(def test-push-vec (vec))
(test::assert-equal '(1) (vec-push! test-push-vec 1))
(test::assert-equal '(1) test-push-vec)
(test::assert-equal '(1 2) (vec-push! test-push-vec 2))
(test::assert-equal '(1 2) test-push-vec)
(test::assert-equal '(1 2 3) (vec-push! test-push-vec 3))
(test::assert-equal '(1 2 3) test-push-vec)
vec-remove! |
Type: Function |
root::vec-remove! |
Usage: (vec-remove! vector index) -> vector |
Remove the element at index from vector, shifting all elements after it to the left. This is destructive!
Example:
(def test-remove-nth-vec (vec 1 2 3))
(test::assert-equal '(1 2 3) test-remove-nth-vec)
(vec-remove! test-remove-nth-vec 1)
(test::assert-equal '(1 3) test-remove-nth-vec)
(vec-remove! test-remove-nth-vec 1)
(test::assert-equal '(1) test-remove-nth-vec)
(vec-remove! test-remove-nth-vec 0)
(test::assert-equal '() test-remove-nth-vec)
vec-set! |
Type: Function |
root::vec-set! |
Usage: (vec-set! vector index value) -> vector |
Set the nth index (0 based) of a vector to value. This is destructive! If you need the equivalent operation on a list use setnth!.
Example:
(def test-setnth-vec (vec 1 2 3))
(test::assert-equal '(1 5 3) (vec-set! test-setnth-vec 1 5))
(test::assert-equal '(7 5 3) (vec-set! test-setnth-vec 0 7))
(test::assert-equal '(7 5 9) (vec-set! test-setnth-vec 2 9))
vec-slice |
Type: Function |
root::vec-slice |
Usage: (vec-slice vector start end?) |
Returns a slice of a vector (0 based indexes, end is exclusive).
Example:
(test::assert-equal '(5 6) (vec-slice '#(1 2 3 4 5 6) 4 6))
(test::assert-equal '(1 2 3) (vec-slice '#(1 2 3 4 5 6) 0 3))
(test::assert-equal '(3 4 5) (vec-slice '#(1 2 3 4 5 6) 2 5))
(test::assert-equal '(3 4 5 6) (vec-slice '#(1 2 3 4 5 6) 2))
version: sl-sh 0.9.70 (master:83cd1c9+, release build, linux [x86_64], May 08 2023, 18:47:56 UTC [rustc 1.69.0 (84c898d65 2023-04-16)])