Duso draws ideas from many other scripting languages. It looks the most like lua, but there are some important differences:
- String templates Duso uses
{{expr}}syntax for embedding expressions in strings; Lua doesn't have native templates - Multi-line strings Duso's
"""..."""syntax preserves newlines and automatically strips matching indentation; Lua uses[[...]]without indentation handling - Comments Duso uses
//for single-line and/* */for multi-line (with nesting) - Named function arguments Duso supports optional
func(name = value)syntax - For loops with ranges Duso uses
for i = 1, 5 do...endlike Lua, but also supportsfor item in arrayfor iteration - Object methods Duso methods auto-bind the object as context at invocation; Lua requires explicit
selfparameter - Objects as constructors Duso objects and arrays can be called to create shallow copies with optional overrides; Lua doesn't have this pattern
- Variable scoping Duso allows optional
varkeyword for local variables; Lua useslocalkeyword - Concurreny model Is completely different, intuitively thread-safe (see
spawn()andrun(), andparallel()) - Integrated debugging Duso has an integrated debugger that handles concurrent processes and can work over HTTP
- Numbers Duso uses floating-point numbers exclusively internally
- Arrays Are 0-indexed in Duso (1-indexed in Lua)
- Regular Expressions are more standard (based on Go's) and denoted with
~...~; lua has its own limited set and uses regular strings - Code values First-class code type created by
parse(), can be executed or persisted - Error values First-class error type with message and stack trace, returned by
parse()or caught in try/catch - Deep copy Duso has
deep_copy()built-in that safely removes functions for scope boundaries (eg. callingspawn()orexit())
- Higher-order functions Both support closures and lexical scoping similarly
- Array functions Duso has
map(),filter(),reduce()as builtins; Lua doesn't have these standard - Closure safety Duso automatically handles closure safety in concurrent contexts
ifConditional statementthenPart of if statementelseElse branch of if statementelseifAdditional condition in if statementendCloses function, if, while, for, try blockswhileLoop while condition is truedoPart of while loop (optional)forLoop with iterationinPart of for loop (iteration)functionDefine a functionreturnReturn from functionbreakExit loop earlycontinueSkip to next iterationtryTry-catch error handlingcatchCatch errors from try blockandLogical ANDorLogical ORnotLogical NOTvarVariable declarationrawRaw string/template modifier
trueBoolean truefalseBoolean falsenilNull/nil value
+Addition-Subtraction*Multiplication/Division%Modulo
==Equal!=Not Equal<Less Than>Greater Than<=Less Than or Equal>=Greater Than or Equal
=Simple assign+=Add-assign-=Subtract-assign*=Multiply-assign/=Divide-assign%=Modulo-assign
++Increment--Decrement
(...)Function calls, grouping expressions[...]Array indexing, array literals{...}Object literals, code blocks,Separator for arguments, array elements.Property access:Object key-value separator?Ternary conditional operator~...~Regex pattern delimiter
Duso comes ready-to-run with its own runtime written in Go. It has a wide array of built-in functions along with a few that are hugely convenient (datatstore(), http_server(), and fetch())
contains(str, pattern [, ignore_case])check if contains pattern (supports regex withpatternsyntax)ends_with(str, suffix [, ignore_case])check if string ends with suffixfind(str, pattern [, ignore_case])find all matches, returns array of {text, pos, len} objects (supports regex)join(array, separator)join array elements into single stringlen(str)number of charactes in stringlower(str)convert to lowercaserepeat(str, count)repeat string multiple timesreplace(str, pattern, replacement [, ignore_case])replace all matches of pattern with replacement string or function result (supports regex)split(str, separator)split string into array by separatorstarts_with(str, prefix [, ignore_case])check if string starts with prefixsubstr(str, pos [, length])get text, supports -lengthtemplate(str)create reusable template function from string with {{expression}} syntaxtrim(str)remove leading and trailing whitespaceupper(str)convert to uppercase
deep_copy(value)deep copy of arrays/objects; functions removed (safety for scope boundaries)filter(array, function)keep only elements matching predicatekeys(object)get array of all object keyslen(array | object | string)get length or sizemap(array, function)transform each element with functionpop(array)remove and return last elementpush(array, value...)add elements to end, returns new lengthrange(start, end [, step])create array of numbers in sequencereduce(array, function, initial_value)combine array into single valueshift(array)remove and return first elementsort(array [, comparison_function])sort array in ascending orderunshift(array, value...)add elements to beginning, returns new lengthvalues(object)get array of all object values
abs(n)absolute valueceil(n)round up to nearest integerclamp(value, min, max)constrain value between min and maxfloor(n)round down to nearest integermax(...ns)find maximum valuemin(...ns)find minimum valuepow(base, exponent)raise to power (exponentiation)random()get random float between 0 and 1 (seeded per invocation)round(n)round to nearest integersqrt(n)square root
All trigonometric functions work with angles in radians. Use pi() for π.
acos(x)inverse cosine (arccosine), x between -1 and 1, returns radiansasin(x)inverse sine (arcsine), x between -1 and 1, returns radiansatan(x)inverse tangent (arctangent), returns radiansatan2(y, x)inverse tangent with quadrant correction, returns radianssin(angle)sine of angle in radianscos(angle)cosine of angle in radianstan(angle)tangent of angle in radians
exp(x)e raised to the power xlog(x)logarithm base 10ln(x)natural logarithm (base e)pi()mathematical constant π (3.14159...)
uuid()generate RFC 9562 UUID v7 (time-ordered, sortable unique identifier)
busy(message)display animated spinner with status messagefetch(url [, options])make HTTP requests (JavaScript-style fetch API)input([prompt])read line from stdin, optionally display prompthttp_server([config])create HTTP server for handling requestsprint(...args)output values to stdout, separated by spaceswrite(...args)output values to stdout without newline at the end
load(filename)read file contents as stringsave(filename, str)write string to file (create/overwrite)append_file(path, content)append content to file (create if needed)copy_file(src, dst)copy file (supports /EMBED/ for embedded files)move_file(src, dst)move file from source to destinationrename_file(old, new)rename or move a fileremove_file(path)delete a filelist_dir(path)list directory contents with {name, is_dir}make_dir(path)create directory (including parent directories)remove_dir(path)remove empty directoryfile_exists(path)check if file or directory existsfile_type(path)get file type ("file" or "directory")current_dir()get current working directorywatch(path [, timeout])monitor file or directory for changes
format_time(timestamp [, format])format timestamp to stringnow()get current Unix timestamp in local timezonetimestamp([timezone])get current Unix timestamp in UTC or a specific timezone/offsettimer()get current time with sub-second precision for benchmarkingparse_time(string [, format])parse time string to timestampsleep([duration])pause execution for duration in seconds (default: 1)
format_json(value [, indent])convert value to JSON string (stringifies binary, functions, errors)parse_json(str)parse JSON string
encode_base64(str | binary)encode string or binary to base64decode_base64(str)decode base64 string to binarymarkdown_html(text, options)render markdown to HTMLmarkdown_ansi(text, theme)render markdown to ANSI terminal output with colors
hash(algo, data)compute cryptographic hash of string or binary (sha256, sha512, sha1, md5)hash_password(password [, cost])hash password with bcrypt for secure storageverify_password(password, hash)verify password against bcrypt hashsign_rsa(data, private_key_pem)sign data with RSA private key (SHA256-PKCS1v15)verify_rsa(data, signature, public_key_pem)verify RSA signaturersa_from_jwk(n, e)convert JWK modulus and exponent to PEM-encoded RSA public keysign_ec(data, private_key_pem)sign data with EC private key (ES256, P-256 curve)verify_ec(data, signature, public_key_pem)verify EC signature (ES256, P-256 curve)ec_from_jwk(x, y)convert JWK x,y coordinates to PEM-encoded EC public key (P-256)
include(filename)execute script in current scoperequire(module)load module in isolated scope, return exports
tobool(value)convert to booleantonumber(value)convert to numbertostring(value)convert to stringtype(value)get type name of variable
context()get runtime context for a scripts or nil if unavailableexit(value)exit script with optional return valueparallel(...functions | array | object)execute functions concurrentlyparse(source [, metadata])parse code string into code or error value (never throws)run(script | code [, context])execute script or code value synchronously and return resultspawn(script | code [, context])run script or code value in background goroutine and return numeric process IDkill(pid)terminate a spawned process by PID
breakpoint([args...])pause execution and enter debug mode (enable with-debug)throw(message)throw an error with call stack informationwatch(expr, ...)monitor expression values and break on changes (enable with-debug)
datastore(namespace [, config])access a named thread-safe in-memory key/value store with optional persistencedoc(str)access documentation for modules and builtinsenv(str)read environment variablesys(key)access system information and CLI flags
duso -readList and browse any embedded doc or fileduso -doc TOPICfor details with examples for keywords, built-ins, and modules (eg. ansi, markdown, claude)duso -docserverto start a local web server with all docs- Learning Duso - Tutorial and examples
- Internals - Deep dive into Duso's architecture