Should NOTHING and NIHIL be Offered as Named Actions?

Sometimes it's nice to say things like return blank instead of return _

It can just look better. So there are named versions of a few symbolic things, like BLANK and TRASH.

>> blank
== _

>> trash
== ~

But there are also named versions of NIHIL and NOTHING.

>> nothing  ; no console display

>> nihil
== ~[]~  ; anti

But how does that work? NIHIL can't be stored in a variable, it's an unstable isotope. And NOTHING represents an unset variable, so variables containing it would error.

So of course, these aren't variables holding the states... they're variables holding actions, and they return the state. So:

>> nada: nothing  ; I'd like to alias this for spanish, please...

>> nada
** Script Error: nada is ~ antiform (see ^(...) and GET/ANY)

And you might be surprised at the result of GET:

>> get $nihil
== ~#[frame! []]~ ; anti  (hey, that's not nihil!)

Does this sort of suggest that we're doing people a disservice by suggesting you can "name" these particular antiforms?

Would it be better if we just said you're supposed to use quasiforms if you want to generate these antiforms?

>> ~

>> ~[]~
== ~[]~  ; anti

It's easier to not name them now, and add the name later, vs. provide the name and take it away.

Also--not that it really matters--but it's faster. :slight_smile: The evaluator can tweak the quoting byte to antiform on those literals faster than making a function call.

I'm pretty strongly leaning toward thinking it is--indeed--a disservice.

I had some definitions that were useful during the time where everything was shifting around:

void': meta void
null': meta null
okay': meta okay
trash': meta trash
nothing': meta nothing  ; where NOTHING is a function
nihil': meta nihil  ; where NIHIL is a function

Today, you can effectively get void' by just saying ^void and it's not subject to any ambiguity.

(Ending a variable name in ' can mean anything you want. Leading a variable with ^ will fetch its meta version unconditionally.)

So I'd like to wipe these out and just use [^void ^null ^okay ^trash].

But this won't work for ^nihil or ^nothing, because you'd get a quasi-frame...since those are not states you can fetch from a value-bearing WORD!.

I think the disadvantages outweigh any possible advantages of defining functions that synthesize these states.

Just teach people what ~ and ~[]~ are, and that's that.

Technically you can still define NOTHING as just being an unset variable, but people could only use it as ^nothing or with get/any $nothing because it really is a variable that holds nothing...

Applying this change, I think it's an improvement. It makes the nihils stand out, and I think the symbol does a good job of calling attention to the unusual state. Despite being symbolic, the result is "lighter" in a way...and a quicker way to get the information.

Compare:

comment: func* [
    "Ignores the argument value, but does no evaluation (see also ELIDE)"

    return: [nihil?]
    @discarded "Literal value to be ignored"
        [any-list? any-utf8? binary! any-scalar?]
][
    return nihil
]

With:

comment: func* [
    "Ignores the argument value, but does no evaluation (see also ELIDE)"

    return: [~[]~]
    @discarded "Literal value to be ignored"
        [any-list? any-utf8? binary! any-scalar?]
][
    return ~[]~
]

If you've learned what it means, the latter is much easier to scan. And given NIHIL's somewhat odd properties (causing an error if you try to assign it to a variable) it's nice to see where they are.

So this doesn't mean that there can't be an arity-0 function that vaporizes.

We just don't want to call it "nihil" so it conflates with the official name of the state. It has to be something you expect to be a function.

What would an arity-0 comment be called that gives the connotation "I am a function that's running and vanishing"?

>> 1 + 2 xxx
== 3

>> action? get $xxx
== ~okay~  ; anti  ("and I expected that!")

Solve for XXX.

In practice, I don't know how often this would be used...just musing about what it would be called if it existed. I am okay calling it ~[]~ (the quasiform)

Maybe NO-OP ? (or just noop if that is common-enough terminology to where the hyphen is dumb, which probably is the case)

I don't know if no-op implies invisibility in particular. If not then it could be what generates nothing, instead.

>> 1 + 2 noop
== ~  ; anti

>> 1 + 2 noop
== 3

The second may be more surprising.

It may be missing a chance for being more informative with a tripwire:

>> 1 + 2 no-op
== ~<no-op>~  ; anti

That's kind of neat, in a "this space intentionally left blank" kind of way.

I might like the hyphenated form. Anyway, this doesn't solve the original question but does offer a way to make an ornery value with a single-arity word...which couldn't be fetched from a word reference...and yet you wouldn't be surprised that it is a function and not the value...

...although, the risk of people thinking it's a "no op value" is greater if it returns ~<no-op>~ than if it just returns nothing. We could help by not having a no-op? tester that says ~<no-op>~ is a "no-op". :face_with_diagonal_mouth:

Probably just returning plain nothing is the best way to avoid confusion. Anyway, I think I like that.

>> no-op
== ~  ; anti

Don't know about the hyphen. "literate" but as it's an abbreviation already, kind of annoying. We know what a noop is.

AI are usually very circumspect. But they were pretty much unanimous saying "programmers know what NOOP (or NOP) is, and this is industry-wide (e.g. jQuery.noop). The hyphen is noise, and if someone didn't know what 'noop' was they'd learn it quickly. Once they learned they would find the hyphen unnecessary."

I was motivated to finally pull the trigger on this due to the new rules for HIJACK. You can use NOOP here as a placeholder, just long enough to get a new identity... then use that identity in a derivation for the function you're going to hijack with.

Example:

let /panic-old: hijack panic/ noop/

hijack panic/ adapt panic-old/ [
    print "PANIC ACTION! is being triggered from a usermode call"
    print mold reason
    ;
    ; ...adaptation falls through to our copy of the original PANIC
]

Maybe a better placeholder would be some kind of UNREACHABLE that errors when called... if you forgot to fill it in. But, NOOP is at least not the worst choice.

(Actually, it occurs to me that if you could HIJACK with VOID, it could just leave the stub as a dummy... and then completely overwrite it with the subsequent HIJACK and just give back NULL to say nothing was there...thus not allocating anything extra. That's probably best.)