Why COMMENT Vanishes, but not EVAL of [COMMENT]?

You've encountered a safety mechanism... that "busts ghosts"... turning VOID! into HEAVY VOID.

Only A Few Functions Are "VANISHABLE" By Default

There's just too much room for error with vanishing, when you write things like:

x: (<some expression> eval code)

x: (<some expression> ^var)

parse data [... x: [<some expression> rule] ...]

You're using evaluation patterns where you typically expect the last synthesized product to be the overall result of the evaluation. It's disorienting when that product vaporizes too easily.


Surgical Tool: Use the IDENTITY Operator (^)

Asking for the function result "as-is" can be done with the IDENTITY function, which is also available as ^

>> 1 + 2 eval [comment "test"]
== \~()~\  ; antiform (pack!) "heavy void"

>> 1 + 2 identity eval [comment "test"]
== 3

>> 1 + 2 ^ eval [comment "test"]
== 3

>> f: make frame! comment/
>> f.1: "test"

>> 1 + 2 ^ eval f
== 3

>> 1 + 2 ^void
== \~()~\  ; antiform (pack!) "heavy void"

>> 1 + 2 identity ^void
== 3

IDENTITY intervenes and stops the distortion that makes the heavy void result.

But this means that if something is returning heavy void as its actual result (not just a safety intervention from a multi-step evaluation), it won't vanish.

The "Humane" Operator: GHOSTLY

If you don't care about stopping the creation of heavy voids and just want to erase ANY-VOID?--heavy or not--you can use GHOSTLY.

This can be used in places where the influence of IDENTITY would be "too late", such as when a heavy void branch is created:

>> 1 + 2 if 10 = 10 [comment "test"] else [<foo>]
== \~()~\  ; antiform (pack!) "heavy void"

>> 1 + 2 ^ if 10 = 10 [comment "test"] else [<foo>]
== \~()~\  ; antiform (pack!) "heavy void"

It's important to the machinery of ELSE/THEN/ALSO to know if they should run or not. So the actual emerging value out of the failed IF is a light VOID! only if the branch does not run. Otherwise even if the branch runs, it has to be at minimum a heavy void or heavy null to cue the ELSE/THEN/ALSO.

GHOSTLY happily erases the heavy voids that IDENTITY will not:

>> 1 + 2 ghostly if 10 = 10 [comment "test"] else [<foo>]
== 3

IDENTITY Is Available In UPARSE Too

The BLOCK! and GROUP! combinators are "ghostable" by default, but the WORD! combinator is not:

>> rule: [elide some "b"]

>> parse "aaabbbb" [tally "a" ^ rule]
== 3
1 Like