Postfix Assertions: SO, WAS, MATCHED


#1

Assertions are important, but some people want to write short code and feel the assertions can clutter it up.

But what if the assertion was as brief and to the point as a comment was? That inspired these postfix assert operators...

SO

Takes a condition on the left and treats that as a thing to assert on. It's variadic on the right and won't run the right to get the expression until the left has been shown as true.

>> x: 0

>> 1 = 2 so x: <changed>
** Script Error: assertion failure: [false so]
** Where: so console
** Near: [... = 2 so ~~ x: <changed>]

>> x
== 0  ; didn't change, the assignment didn't get a chance to run

>> 1 = 1 so x: <changed>
== <changed>

>> x
== <changed>  ; the right hand side once the left was shown true

WAS

The WAS word has been reclaimed from a previous purpose, now to assert "lax equality" (or IS-ness) of the left hand side to the right. But it passes on the value.

>> 10 + 10 was 5 + 15
== 20

>> 10 + 10 was 50 + 1000
** Script Error: assertion failure: [20 is 1050]
** Where: was console
** Near: [... 10 was 30 ~~]

MATCHED

Very similar to WAS, but a variant which uses the logic of the MATCH dialect, e.g. to test the datatype.

>> 10 + 10 matched integer!
== 20

>> 10 + 10 matched text!    
** Script Error: assertion failure: [20 matches text!]
** Where: matched console
** Near: [... 10 matched text! ~~]

Added Bonus: ASSERT is now invisible

Cool as these are, you still might want to use the plain old assert for something. If you do, know that it is now...invisible! So you can put it anywhere.

>> all [
    x: 1 + 1 
    assert [x > 1]
 ]
 == 2

>> all [
    x: 1 + 1 
    assert [x < 1]
 ]
** Script Error: assertion failure: [
    x < 1 ** false
]
** Where: _ assert all console
** Near: [[x < 1] ~~]

#2

Is it possible to have ASSERT have similar throwing abilities as FAIL/WHERE ? For example—with the following function:

foo: func [number [integer!]][
    assert [number > 40]
]

A subsequent error would be as much on the calling context (foo 1) as using an incompatible datatype (foo "Forty").


#3

Yup! FAIL's mechanisms are userspace and can/should probably be factored somehow: