I proposed this idea a year ago and have used it as an example many times, in explaining things that could be done with definitional errors (e.g. changing PARSE to RAISE an error if it couldn't process the rules and get to the end of input)...
...but I hadn't gotten around to switching TAKE to actually use the mechanism.
Today I've done it, and I think it's a good choice. Having functions RAISE errors 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).
This is really only possible due to definitional errors!!
If you tried to make TAKE cause an error in Rebol2/R3-Alpha/Red, you would have to trap it via the closest thing they have to Ren-C's TRY (called ATTEMPT) which would put the call in a block:
rebol2>> attempt [take []]
== #[none]
But this would be very dangerous, as it would trap errors that weren't being emitted specifically by the TAKE. For instance, a typo:
rebol2>> block: [a b c]
rebol2>> attempt [take blockk] ; typo
== #[none]
Or it would gloss over a variable being of the wrong type:
rebol2>> data: 1020
rebol2>> attempt [take data] ; taking an integer!
== #[none]
These are simple examples, but there's no limit to how dangerous this is.
But with definitional errors, Ren-C can safely react to errors that are specifically emitted by TAKE...