Basic tips
nil -> ()
(if(not a)b) -> (or a b) (if the return is not needed)
- Replace conditional blocks
{} with and or or chains if the return values allow it
- Spacing in ArkScript is much more flexible than in other Lisp-likes. For instance, a number can precede an identifier without a space, and lists don't need spaces around them.
(if(list:contains? lst val)...) -> (or(<(list:find lst val)0)...)
- Newlines can appear literally in strings
- Use a function call to replace multiple independent
let declarations
nil, 0, and empty containers are falsy
(while(!= a b)...) -> (while(- a b)...)
(while(len X)...) -> (while X ...)
let, mut, and set return the set value and can thus appear inside expressions
- Many of the
std.List builtins work on strings also. (You can check the implementation in the source: if it's based on a simple loop with len and @, it should work with a string.)
Importing
- Always use glob imports:
(import std.List) ... list:map -> (import std.List:*) ... map.
- Note the VM builtins and C++ builtins:
(import std.Sys:*) ... sys:args -> builtin__sys:args.
- If using functions from many files, try
(import std.Prelude), which provides all standard library files, but cannot be globbed.
- If you import
std.Prelude, you can use all the macros in std.Macros: ++, --, and until are very useful.
- The standard library is big, with many useful functions (e.g.
list:combinations, math:prime?, ...).
std.Range is never necessary; use list:map, list:iota, or list:range.
- Complex numbers require
math:complex- functions, which are expensive; simply implement them yourself using pairs of numbers.
Sequences
For sequence holes, recursion can often be used to avoid imports altogether. Additionally, you can often terminate via error to save bytes. For instance, compare the following ways to print the first 50 perfect squares:
(import std.List:*)(map(iota 1 50)(fun(n)(print(* n n)))) # 57 bytes, has import overhead
((let f(fun(n)(or(print(* n n))(< 49n)(f(+ 1n)))))1) # 52 bytes, uses recursion
((let f(fun(n)(f(+(or(print(* n n))(< 49n)n)1))))1) # 51 bytes, crashes because you can't add true to 1, saving a space
(mut n 0)(while(> 50n)(print(*(set n(+ 1n))n))) # 47 bytes, while loop still has potential sometimes