I just simplified the implementation for PRINT, using much less trickery and just being blunt.
print: procedure [
"Output processed value to STDOUT, with newline if any text is output"
value [
<opt> "no output (including no newline)"
text! "output text, empty string still outputs newline"
block! "uses SPACED on block (for no spaces, use PRINT UNSPACED [...])"
newline? "output just the single newline"
]
][
case [
not value [
noop
]
text? value [
write stdout value
write stdout newline
]
block? value [
if value: spaced value [
write stdout value
write stdout newline
]
]
newline? value [
write stdout newline
]
~(unreachable)~
]
]
Some Notable Aspects
-
This uses PROCEDURE so that it doesn't have to have
return: [trash!]in the spec. -
The VALUE argument has TEXT! documentation for each type in the type spec embedded in the type spec block, vs. trying to write a single string that explains the reactions to the types.
-
It uses NOOP instead of leaving the code block empty, while having the same effect. This helps make everything look intentional.
-
The
~(unreachable)~"hot potato" is a light way of making the CASE error out if it unexpectedly doesn't match any of the conditions.
If You've Seen PRINT In The Past, This May Surprise
PRINT used to be more complex, including things like:
(write stdout cond spaced line) then [
write stdout newline
]
That handles both TEXT! and BLOCK! (because SPACED passes thru text).
But is this cleverness really worth it? It feels like probably not.
Boring and obvious code carries benefits. I think if someone digs into the source for PRINT and finds "oh, I can read that!" it's a better place to start.