Recovering Values From A Raised Definitional Error

So TRY is a way to convert definitional errors into soft failure, e.g. a NULL

>> first null
** Error: FIRST on NULL requires use of TRY

>> try first null
== ~null~  ; anti

I had a thought that instead of just always returning NULL, there might be a way to have constructs raise errors that carried a payload... which would give a "fallback" value that represented something you might want vs. NULL in the case of acknowledging the error. (The only rule would be that a function emitting such an error should not have any side effects if it emits one of these errors.)

So various constructs could offer meanings for what the TRY actually does:

>> unquote first ['abc]
== abc

>> unquote first [def]
** Error: Can't Unquote Plain WORD!, use TRY if Intentional

>> try unquote first [def]
== def

Another application: at one point I suggested it would be nice to be able to have a COLLECT that didn't actually KEEP anything return NULL, so it could be ELSE-reactive. That meant if you really wanted an empty block, you'd have to do something like any [collect [...], copy []] which was ugly. But the error could hold a freshly-copied block to be the result of a TRY:

>> collect [keep if false [<not kept>]]
** Error: COLLECT didn't KEEP anything, use TRY if intended

>> try collect [keep if false [<not kept>]]
== []

There are various technical reasons why ELSE can't be reactive to TRY-style errors. One fairly important one would be that if you used ELSE with a branching construct, it wouldn't be able to tell the difference between a branch that had a TRY-error and no branch taken:

>> case [true [unquote first [def]]] else [print "Took branch, runs due to UNQUOTE"]
Took branch, runs due to UNQUOTE  ; this would be bad

But... maybe the trick could be that if you pass ELSE a function that takes an argument, it assumes that means you handle TRY-style errors? (Because otherwise it could only be void/null... why take an arg?)

>> (unquote first [def]) else arg -> [print ["TRY error" arg]]
TRY error def

It's a weird thought. Anyway, just wanted to write up this parallel-universe TRY concept...

1 Like

Having now clocked some time with TRY, I like it how it is. I don't really want it to do anything besides convert definitional errors to ~null~ antiforms...and maybe a particular definitional error to a ~NaN~ antiform. But I want what it gives back to be falsey if it traps an error.

That doesn't mean there isn't some kind of good idea here. Perhaps a good enough idea to retake another word like ATTEMPT for it.