Functions

Function declarations, arrow functions, destructuring parameters, and rest parameters in Tish.

Named functions

fn add(a, b) {
    return a + b
}
 
fn double(x) = x * 2   // single-expression, implicit return

Both fn and function are supported.

Destructuring parameters

Formal parameters can be a plain identifier (with optional type and default) or an array or object destructuring pattern, same shapes as let / const destructuring. Each formal still consumes one argument from the call.

// Object props (e.g. component-style APIs)
export fn Sidebar({ width, children }) {
    return <div style={`width: ${width}px`}>{children}</div>
}
 
// Mix simple and destructuring formals
fn line({ x, y }, label) {
    console.log(label, x, y)
}

Arrow functions use the same rules inside parentheses (object patterns need parens so { is not parsed as a block):

let norm = (({ x, y }) => x * x + y * y)
let pair = ([a, b]) => a + b

Optional per-parameter type (: Type) and default (= expr) are allowed on destructuring formals, matching simple parameters.

Backends

  • Interpreter, Rust native codegen (--native-backend rust), and JavaScript compile target support destructuring parameters.
  • The bytecode VM (tish run --backend vm, and the Cranelift native path that lowers through bytecode) does not support destructuring parameters yet; use a single object argument and destructure in the body with let { ... } = arg instead.

Limitations (same as let destructuring): object rest ({ a, ...rest }) is not supported in patterns.

Arrow functions

// Single param, expression body
let doubled = nums.map(x => x * 2)
 
// Multiple params
let sum = nums.reduce((acc, x) => acc + x, 0)
 
// No params
let getHello = () => "Hello"
 
// Block body
let process = (x) => {
    let y = x * 2
    return y + 1
}

Note: Arrow functions work in interpreter mode. Compiler mode may require named functions for some use cases.

Rest parameters

fn sum(...args) {
    let total = 0
    for (let x of args) total += x
    return total
}

Closures

Functions capture variables by name with lexical scope:

fn makeCounter() {
    let count = 0
    fn inc() {
        count++
        return count
    }
    return inc
}

Async functions

Use async fn to declare asynchronous functions that can use await:

async fn fetchData(url) {
    let res = await fetchAsync(url)
    return res.ok ? res.body : null
}
 
async fn main() {
    let data = await fetchData("https://api.example.com/data")
    console.log(data)
}
 
main()

await pauses until the Promise settles. Use with fetchAsync, fetchAllAsync, or any Promise (requires the http feature).

No this

Tish has no this keyword. Pass explicit parameters instead.

Improve this documentation