When Destructuring

The @when macro was introduced to work with the scenarios where @match leads to heavy syntax.

It’s similar to if-let construct in Rust language.

There are three distinct syntaxes for @when.

Allow Destructuring in Let-Binding

tp = (2, 3)
x = 2

@assert 5 ===
    @when let (2, a) = tp,
                  b  = x
        a + b
    end

@assert nothing ===
    @when let (2, a) = 1,
                   b = x
        a + b
    end

Note that only the binding formed as $a = $b would be treated as destructuring.

@data S begin
    S1(Int)
    S2(Int)
end

s = S1(5)

@assert 500 ===
    @when let S1(x) = s,
              @inline fn(x) = 100x
        fn(x)
    end

In the above snippet, @inline fn(x) = 100x is not regarded as destructuring.

Sole Destructuring

However, a let-binding could be also heavy when you just want to solely destructure something.

Finally, we allowed another syntax for @when.

s = S1(5)
@assert 5 === @when S1(x) = s x
@assert 10 === @when S1(x) = s begin
    2x
end
@assert nothing === @when S1(x) = S2(10) x

Multiple Branches

Sometimes we might have this kind of logic:

  • If a matches pattern A, then do Aa

  • else if b matches pattern B, then do Bb

  • otherwise do Cc

As there is currently no pattern matching support for if-else, we cannot represent above logic literally in vallina Julia.

MLStyle provides this, with the following syntax:

@when let A = a
    Aa
@when B = b
    Bb
@otherwise
    Cc
end

Also, predicates can be used here, thus it can be seen as superior to if-else:

@when let A = a,
          condA.? # or if condA end
    Aa
@when begin B = b
            condB.? # or `if condB end`
      end
    Bb
@otherwise
    Cc
end

A concrete example is presented below:

a = 1
b = 2
@when let (t1, t2) = a, (t1 > 1).?
    t2
@when begin a::Int = b; (b < 10).? end
    0
end # => 0