PistonDevelopers/dyon

Unpack / swizzle design

bvssvni opened this issue · 0 comments

Dyon has a short notation for unpacking/swizzling vector components.

Swizzle vector components

Instead of writing:

a := (1, 2)
b := (3, 4)
(x(a), y(a), y(b), x(b))
println(c) // prints `(1, 2, 4, 3)`

You can write:

a := (1, 2)
b := (3, 4)
c := (xy a, yx b)
println(c) // prints `(1, 2, 4, 3)`

When swizzling all vector components, you must use , at the end for clarity:

a := (1, 2, 3, 4)
b := (wzyx a,) // <--- `,` helps people understand this is a vector
println(b) // prints `(4, 3, 2, 1)`

You can also repeat a component more than one, for example (xxy a,).

Unpack to number arguments

Numbers in Dyon have f64 precision, while vec4 only has f32 precision. To take advantage of f64 precision in computing, you can write functions taking numbers, and then unpack a vector when calling it:

fn foo(x: f64, b: f64) -> f64 { ... }

v := (0, 0)
println(foo(xy v))

You can also use unpacking with other arguments to a function:

mass := 0.2
v := (1, 0, 0)
foo(mass, xyz v)

When calling a function with named arguments, remember that Dyon joins argument names with _.

For example, you can create a function multiply_mat_pos and use it like this:

fn multiply_mat_x_y_z(mat: [[f64]], x: f64, y: f64, z: f64) -> vec4 { ... }

// Call with a vector.
new_pos := multiply(mat: m, x_y_z: xyz pos)

// Call with numbers.
new_pos := multiply(mat: m, x: x(pos), y: y(pos), z: z(pos))

Motivation

The vec2/vec3/vec4 un-loops are frequently used when components of a vector is a function of an index counter.

For example:

(0, 0, 0, 1)

Can be written as:

vec4 i (if i == 3 { 1 } else { 0 })

This is handy when the expression is part of larger loop, and the condition for putting 1 in the vector changes.

The problem is when you want to call a function that takes numbers as arguments. Without the unpack notation, you would have to declare a variable:

v := vec4 i (if i == 3 { 1 } else { 0 })
f(x(v), y(v), z(v))

With the unpack notation, you can write the expression on a single line:

f(xyz vec4 i (if i == 3 { 1 } else { 0 }))

These rules are design for:

  • Reduce typing
  • Reduce bugs
  • Improve readability