I decided print newline
was clearer. It's the only character PRINT accepts (would be confusing otherwise as to whether it printed a single character or not).
print newline
prints a single newline (returns void)print {}
does the same (returns void)print _
prints nothing (returns null)print []
will print nothing (returns null)
If you look at the implementation of PRINT, it shows how the rules are lining up:
print: func [
{Textually output spaced line (evaluating elements if a block)}
return: "NULL if blank input or effectively empty block, otherwise VOID!"
[<opt> void!]
line "Line of text or block, blank or [] has NO output, newline allowed"
[<blank> char! text! block!]
][
if char? line [
if not equal? line newline [
fail "PRINT only allows CHAR! of newline (see WRITE-STDOUT)"
]
return write-stdout line
]
(write-stdout try spaced line) then [write-stdout newline]
]
Notice how SPACED of returns NULL, which TRY converts into blank, which WRITE-STDOUT takes to mean it should return NULL. The THEN notices whether write-stdout returns null or not...if it returns non-null (including void) it will follow up with writing a newline.
Because of the way that <blank>
works (name still being thought about), this has a nice behavior w.r.t. performance. A function receiving blank that has that parameter annotation won't even try to run.