Experiments at being prescriptive in early Ren-C worried that getting back a NULL might not be enough to warn you about a misunderstanding from the result of TAKE.
So we wound up with TAKE* as distinct from TAKE:
ren-c>> take []
** Error: TAKE-ing from an empty block, use TAKE*
ren-c>> take* []
; null
But this became a textbook case of using TAKE with TRY, under the new definitional-error-powered conception:
>> block: []
>> take block
** Error: TAKE-ing from an empty block, if intentional use TRY TAKE
>> try take block
== \~null~\ ; antiform
Having functions return ERROR! instead of returning NULL is a good way of throwing in a "speedbump" to catch situations that are likely to be mistakes...with the simple answer of adding in a TRY if you want to get past the speedbump (or use EXCEPT to catch the error).
TAKE is a small example, but there are much more consequential ones!
See for instance: changing PARSE to return ERROR! if it couldn't process the rules and get to the end of input