Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching

An overview of the when statement: a flexible pattern matching structure in DeltaScript, and an alternative to switch


This content originally appeared on HackerNoon and was authored by Jordan Bunke

An overview of the when statement: a flexible pattern matching structure in DeltaScript, and an alternative to switch

\ I have spent over a year working obsessively to bring my vision of the perfect pixel art editor to life. The fruit of my labor is Stipple Effect, a program that lets users write scripts for a variety of use cases, including transforming the project for display in the preview window in real-time:

\ The rotating head animation is generated from the texture by a preview script

\ I was very particular about how I wanted the script-writing process to feel for users: quick, clear, painless, iterative. To achieve that, I designed and implemented my own scripting language rather than embedding Lua or another established scripting language in my program.

\ The result is DeltaScript, a scripting language "sketelon" designed to be extended for specific application domains. Stipple Effect's scripting API is one such extension.

\ I released the language specification for DeltaScript v0.1.0 last week (Jan 16, 2025), so I figured now is the perfect time to write about one of the features I am most excited about.


:::info Note: This blog post is adapted from the original on my website. Read it there to see the proper syntax highlighting for DeltaScript code snippets.

:::


Why when?

DeltaScript was always supposed to be a high-level interpreted language. As such, I wanted the language to have powerful, flexible control flow structures that could express complex logic concisely and still be readable and maintainable.

\ One of my biggest frustrations as a programmer is the limitations and the implementation philosophy of the traditional switch statement: limited to literals in case labels, fallthrough, etc.

\ I do most of my programming in Java, and I must say, recent Java language versions have drastically extended the functionality of switch and turned it into a near-perfect pattern-matching structure. I wanted to do something similar for DeltaScript.

How when works

My when statement supports three different kinds of non-trivial cases:

  • is - matches the control expression against one or more expressions, checking for equality
  • matches - uses the special identifier _ to replace the control expression and defines a pattern in the form of a boolean expression
  • passes - accepts a test function (predicate) of type (T -> bool), where T is the type of the control expression

\ These cases can be arranged inside a when statement in any order. Each case is checked in order until a case passes its check, at which point the case body is executed. There is no fallthrough; once the runtime execution identifies a successful match case and executes its body, the execution drops out of the when statement and executes the statement that follows it.

\ Consider this example:

(color c) {
  ~ string pfx = "The color is ";

  when (c) {
    matches _.alpha == 0 -> print(pfx + "transparent");
    is #000000 -> print(pfx + "black");
    is #ffffff -> print(pfx + "white");
    matches _.r == _.g && _.r == _.b && opaque(_) -> 
            print(pfx + "a shade of grey");
    is #ff0000, #00ff00, #0000ff -> print(pfx + "an RGB primary color");
    passes ::bright_opaque -> print("bright");
    otherwise -> print(pfx + "not a match");
  }
}

bright_opaque(color c -> bool) {
  int max = max([ c.r, c.g, c.b ]);
  return max == 0xff && opaque(c);
}

opaque(color c -> bool) -> c.alpha == 0xff

\ This logic cannot be expressed by a traditional switch statement. Expressing it with an ifelse if would look like this:

\

(color c) {
  ~ string pfx = "The color is ";

  if (c.alpha == 0) print(pfx + "transparent");
  else if (c == #000000) print(pfx + "black");
  else if (c == #ffffff) print(pfx + "white");
  else if (c.r == c.g && c.r == c.b && opaque(c))
    print(pfx + "a shade of grey");
  else if (c == #ff0000 || c == #00ff00 || c == #0000ff)
    print(pfx + "an RGB primary color");
  else if (bright_opaque(c)) print("bright");
  else print(pfx + "not a match");
}

bright_opaque(color c -> bool) {
  int max = max([ c.r, c.g, c.b ]);
  return max == 0xff && opaque(c);
}

opaque(color c -> bool) -> c.alpha == 0xff

\ You can read the full semantics of the when statement in the language specification.

\ I'll leave you with this long-form example that shows off a few additional language features of interest:

\

() {
    string[] words = [
        "Racecar", "Pilot", "Madam", 
        "Able was I ere I saw Elba", 
        "Nurses run", "Highway 61", 
        "A man, a plan, a canal - Panama"
    ];

    (string -> bool) no_whitespace_palindrome = 
                    (s -> palindrome(no_whitespace(s)));

    for (word in words) {
        when (word) {
            passes ::palindrome -> print("\"" + _ + "\" is a pure palindrome!");
            passes no_whitespace_palindrome -> 
                            print("\"" + _ + "\" is a palindrome if whitespace is ignored");
            passes (s -> palindrome(only_letters(s))) -> 
                            print("\"" + _ + "\" is a palindrome if whitespace and punctuation are ignored");
            otherwise -> print("\"" + _ + "\" is not a palindrome");
        }
    }
}

palindrome(string s -> bool) {
    string lc = lowercase(s);
    return lc == reverse(lc);
}

reverse(string s -> string) {
    string res = "";

    for (c in s)
        res = c + res;

    return res;
}

lowercase(string s -> string) {
    string res = "";

    for (c in s) {
        int unicode = (int) c;

        if (uppercase_letter(c))
            res += (char) ((int) 'a' + (unicode - (int) 'A'))
        else
            res += c;
    }

    return res;
}

no_whitespace(string s -> string) {
    ~ char{} WHITESPACE = { ' ', '\t' '\n' };
    string res = "";

    for (c in s)
        if (!WHITESPACE.has(c))
            res += c;

    return res;
}

only_letters(string s -> string) {
    string res = "";

    for (c in s)
        if (uppercase_letter(c) || lowercase_letter(c))
            res += c;

    return res;
}

uppercase_letter(char c -> bool) {
    int unicode = (int) c;
    return unicode >= (int) 'A' && unicode <= (int) 'Z';
}

lowercase_letter(char c -> bool) {
    int unicode = (int) c;
    return unicode >= (int) 'a' && unicode <= (int) 'z';
}

\ This script produces the following output:

"Racecar" is a pure palindrome!
"Pilot" is not a palindrome
"Madam" is a pure palindrome!
"Able was I ere I saw Elba" is a pure palindrome!
"Nurses run" is a palindrome if whitespace is ignored
"Highway 61" is not a palindrome
"A man, a plan, a canal - Panama" is a palindrome if whitespace and punctuation are ignored

\


This content originally appeared on HackerNoon and was authored by Jordan Bunke


Print Share Comment Cite Upload Translate Updates
APA

Jordan Bunke | Sciencx (2025-01-28T11:25:05+00:00) Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching. Retrieved from https://www.scien.cx/2025/01/28/knowing-when-to-switch-a-glimpse-into-the-future-of-pattern-matching/

MLA
" » Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching." Jordan Bunke | Sciencx - Tuesday January 28, 2025, https://www.scien.cx/2025/01/28/knowing-when-to-switch-a-glimpse-into-the-future-of-pattern-matching/
HARVARD
Jordan Bunke | Sciencx Tuesday January 28, 2025 » Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching., viewed ,<https://www.scien.cx/2025/01/28/knowing-when-to-switch-a-glimpse-into-the-future-of-pattern-matching/>
VANCOUVER
Jordan Bunke | Sciencx - » Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/28/knowing-when-to-switch-a-glimpse-into-the-future-of-pattern-matching/
CHICAGO
" » Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching." Jordan Bunke | Sciencx - Accessed . https://www.scien.cx/2025/01/28/knowing-when-to-switch-a-glimpse-into-the-future-of-pattern-matching/
IEEE
" » Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching." Jordan Bunke | Sciencx [Online]. Available: https://www.scien.cx/2025/01/28/knowing-when-to-switch-a-glimpse-into-the-future-of-pattern-matching/. [Accessed: ]
rf:citation
» Knowing ‘When’ to Switch: A Glimpse into the Future of Pattern Matching | Jordan Bunke | Sciencx | https://www.scien.cx/2025/01/28/knowing-when-to-switch-a-glimpse-into-the-future-of-pattern-matching/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.