Postfix Assertions: SO, WAS, MATCHED

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] ~~]
1 Like

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").

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

There's a bit of a glitch with how this one was being implemented, relating to how MATCH has changed...and how EITHER-MATCH was killed off.

Rather than fix the somewhat esoteric MATCHED function I'd rather just post the test to explain the feature and kill off supporting it for now:

; MATCHED POSTFIX
; Checks for MATCHES of the left to the right
(
    20 = (10 + 10 matched integer!)
)(
    e: trap [10 + 10 matched text!]
    e/id = 'assertion-failure
)

It doesn't demonstrate anything in particular that WAS or SO don't show off...it just is entangled in parameter order manipulation and issues that need to be worked out with MATCH's test parameter, which are higher priority problems.