Time to Meet Your MATCH... (...dialect)

MATCH is a handy tool for testing a value against some basic rules, and passing it through if they match...or evaluating to null if they don't.

It uses the "match dialect", which is the same thing that typechecking function parameters uses!

WORD!s match instances of the type constraint

>> match [integer! tag!] 1020
== 1020

>> match [integer! tag!] "this text value won't match"
== \~null~\  ; antiform

>> match [integer! tag!] <matches!>
== <matches!>

This works for functions, too (if they take a single argument and return a LOGIC)

>> match [even?] 1020
== 1020

>> match [odd?] 1020
== \~null~\  ; antiform

Quoted, Quasiform, or Sigil'd WORD! Matches The Decoration

If the decoration matches, it will run the constraint... and if both match, it matches:

>> match ['word!] first ['a]
== 'a

>> match [word!] first ['a]
== \~null~\  ; antiform

>> match [@even?] first [@1020]
== @1020

You can put literal matches in QUASI-BLOCK!s

It works just as in datatype specs:

>> match [~[on off]~] second [echo on]
== on

>> match [~[on off]~] first [potato]
== \~null~\  ; antiform

But as an added bonus, MATCH accepts SPLICE!, so you can use it without the enclosing block!

>> match ~[on off]~ second [echo on]
== on

MATCH has an automatic erroring form, called ENSURE

If you want a quick and dirty way to typecheck something and pass it through, but error otherwise, use ENSURE.

>> ensure [empty?] [a b]
** Script Error: ...

>> ensure [empty?] []
== []

There's also TYPECHECK which returns ~null~ or ~okay~

If you just want a yes or no answer, then you can use TYPECHECK

>> typecheck [integer! tag!] <abc>
== \~okay~\  ; antiform

>> typecheck [integer! tag!] [a b c]
== \~null~\  ; antiform

This is useful if you want to test for things like NULL itself, because MATCH gives an error in these cases:

>> match [<null> integer!] null
** Error: MATCH can't match null (reserved to mean non-match)

>> typecheck [<null> integer!] null
== \~okay~\  ; anti

The Opposite of MATCH is NON

>> non integer! <abc>
== <abc>

>> non integer! 1020
== \~null~\  ; antiform (logic!)

The negated analogue of ENSURE is PROHIBIT

>> prohibit tag! "abc"
== "abc"

>> prohibit tag! <abc>
** Error: PROHIBIT of TAG! received <abc>
1 Like

Very cool. Should be muy bueno for simple lexing and tokenizing values of a dialect-- as well as the handling of syntax errors.

3 posts were split to a new topic: Quirky Ideas From Original MATCH Dialect

So MATCH has evolved (and I've updated the descriptions above to account for it).

Note that previously this was done with quoting e.g. match ['on 'off]. But the interpretation of quoting as being used to have ['word!] match "LIT-WORD" just turned out to be more important.

Using quasi-blocks actually turned out to be better...because you aren't having to mentally subtract a quote level from what you're looking at:

old>> match [''a ''b] first ['a]  ; confusing!
== 'a

new>> match [~['a 'b]~] first ['a]  ; clearer!
== 'a

UPDATE: you can now omit the block entirely, since MATCH takes splices...even better!

>> match ~['a 'b]~ first ['a]  ; woo!
== 'a

(...and I've written elsewhere about how splices help with this "mental math" problem, which makes them a good way of talking about literal data more broadly.)

Decorations (Quote/Quasi/Sigil/Sequence) are "Taken"

One big area of what had to change is that things like CHAIN! and PATH! and TUPLE! are now matched as decorations. So [word!:] is destructured and matches things like foo:. Without this, we'd have to give everything a name to fabricate type constraints (/word!: would have to be a SET-RUN-WORD?, etc.)

This chews out a big chunk of the design space. WORD!, PATH!, TUPLE!, and CHAIN! all have their meanings sort of set-in-stone.

FENCE! and GROUP! are still left

I've thought that maybe FENCE! would be good for "AND"-ing type constraints, since BLOCK! does "OR"-ing by default.

GROUP! is used so often in composition that it's not always desirable to give it meaning in a dialect. But we could.

Decorated non-[word! path! tuple! chain!] are available

I wonder if the decoration should distribute, e.g. @[word! tuple!] as synonym for [@word! @tuple!] ?

1 Like