Functions

Functions

Every function is a function of the module. There are no function values, no environment to close over and no call stack.

  • Shadowing a module value

    A parameter or body local can use the name of a module value. Closures resolve the nearest declaration; duplicates in the same scope remain errors.

    TypeScript
    const gain: f32 = 0.25;
    function scale(gain: f32): f32 { return gain * 2.; }
    export function answer(): f32 {
    const gain: f32 = 1.;
    return scale(gain);
    }
    Emitted WGSL
    fn scale(gain: f32) -> f32 {
    return (gain * 2.0);
    }
    fn answer() -> f32 {
    return scale(1.0);
    }
  • Parameter reassignment

    A local copy receives the input value. Reassigning it leaves the caller’s value unchanged.

    TypeScript
    export function brighter(value: f32): f32 {
    value += 0.25;
    return value;
    }
    Emitted WGSL
    fn brighter(value: f32) -> f32 {
    var value_1: f32 = value;
    value_1 += 0.25;
    return value_1;
    }
  • Top-level function

    A module function of the same name, parameters and return type.

    TypeScript
    export function lum(c: vec3): f32 {
    return dot(c, vec3(0.2126, 0.7152, 0.0722))
    }
    Emitted WGSL
    fn lum(c: vec3<f32>) -> f32 {
    return dot(c, vec3<f32>(0.2126, 0.7152, 0.0722));
    }
  • Local function

    A function of the module, named after the function that declares it.

    TypeScript
    export function ramp(x: f32): f32 {
    const twice = (v: f32): f32 => v * 2.
    return twice(x)
    }
    Emitted WGSL
    fn ramp_twice(v: f32) -> f32 {
    return (v * 2.0);
    }
    fn ramp(x: f32) -> f32 {
    return ramp_twice(x);
    }
  • Closure over a name

    The local function takes each name it reads from the function around it as a parameter, and a name it writes by reference.

    TypeScript
    export function ramp(x: f32): f32 {
    const twice = (v: f32): f32 => v * x
    return twice(x)
    }
    Emitted WGSL
    fn ramp_twice(x: f32, v: f32) -> f32 {
    return (v * x);
    }
    fn ramp(x: f32) -> f32 {
    return ramp_twice(x, x);
    }
  • Default argument

    Every parameter stays, and the argument left out is written at the call. default-args

    TypeScript
    function vignette(
    uv: vec2, strength: f32 = 0.8
    ): f32 {
    return 1. - length(uv) * strength
    }
    Emitted WGSL
    fn vignette(uv: vec2<f32>, strength: f32) -> f32 {
    return (1.0 - (length(uv) * strength));
    }
    fn shade(uv: vec2<f32>) -> f32 {
    return vignette(uv, 0.8);
    }
  • Overload signature

    The signatures are skipped and the implementation is lowered once.

    TypeScript
    export function lum(c: vec3): f32
    export function lum(c: vec3): f32 {
    return dot(c, vec3(0.2126, 0.7152, 0.0722))
    }
    Emitted WGSL
    fn lum(c: vec3<f32>) -> f32 {
    return dot(c, vec3<f32>(0.2126, 0.7152, 0.0722));
    }
  • Recursive call

    Refused

    WGSL has no call stack, and the check reads the call graph.

    TypeScript
    export function fall(x: f32): f32 {
    return fall(x * 0.5)
    }

    Compiler diagnostic

    TS8031 Recursive call: "fall" -> "fall". WGSL has no call stack, so a function must not take part in a call cycle.

  • Call as a statement

    A statement of its own. A value-returning builtin standing alone computes nothing, so the optimizer drops it.

    TypeScript
    @compute([64, 1, 1])
    export function main_k(
    @builtin("global_invocation_id") gid: vec3u
    ): void {
    store(gid.x, 1.)
    }
    Emitted WGSL
    @compute @workgroup_size(64)
    fn main_k(@builtin(global_invocation_id) gid: vec3<u32>) {
    store(gid.x, 1.0);
    }
  • Call with an effect

    A builtin that returns a value and has an effect takes WGSL's phony assignment, _ =, since Tint treats it as must-use. atomic-histogram

    TypeScript
    @compute([64, 1, 1])
    export function main_k(
    @builtin("global_invocation_id") gid: vec3u
    ): void {
    atomicAdd(hits[gid.x], 1)
    }
    Emitted WGSL
    @compute @workgroup_size(64)
    fn main_k(@builtin(global_invocation_id) gid: vec3<u32>) {
    _ = atomicAdd(&hits[gid.x], 1u);
    }
  • Math names

    Math.sin is the same builtin as sin, and Math.PI folds to its value.

    TypeScript
    export function wave(x: f32): f32 {
    return Math.sin(x * Math.PI)
    }
    Emitted WGSL
    fn wave(x: f32) -> f32 {
    return sin((x * 3.141592653589793));
    }

Edit this page Report a problem