We REALLY need a better name for... REALLY

If I've done my due diligence in reasoning through a world where NULL is normalized, then being able to have your code assert places where you didn't expect a NULL is pretty important.

TL;DR: The construct that has been committed is called MUST

>> must find "abc" "b"
== "bc"

>> must find "abc" "q"
** Error: MUST requires argument to not be NULL    

Once upon a time, this was called ENSURE:

>> append x ensure select [a 10 b 20] 'c
** Error: e.g. "Couldn't ENSURE you had a value, it was NULL""
** Near: ensure ** select [a 10 ... (blah blah

But that was retaken to be a 2-argument function: a variant of MATCH that triggers an error if the type doesn't match a type or set (e.g. ensure [text! integer!] 1 + 2). It passes the value through if it matches, and raises an error if it does not.

I used that all the time, whereas a single-arity function that checked against NULL seemed less useful. So long as you were throwing in a check, was "it's not null" the only thing you knew about the data? You could even say ensure any-value! ... if that was the case, and that wasn't too bad.

Still...for the heck of it, I went ahead and made a non-null checker and called it... REALLY. Yes, REALLY.

>> append x really select [a 10 b 20] 'c
** Error: e.g. "You REALLY wanted a value, but got back NULL"
** Near: really ** select [a 10 ... (blah blah

I didn't like the name, and never used it. Nulls caused enough problems in those days on their own.
But with Sometimes-Too-Friendly Nulls, callsites could REALLY use this now.

I'd be willing to shuffle names around. But ENSURE became quite entrenched. I'd be loathe to retake it unless a quite good replacement were found.

So, what've we got?

Hm, wait... GOT?

I just wrote that and wondered if it could work:

>> append x got select [a 10 b 20] 'c
** Error: e.g. "Thought you GOT a value, but you got nothin' (it was NULL)"
** Near: got ** select [a 10 ... (blah blah

It's weird, and has a bit of that problem of looking at a word where it doesn't look like a word. Then none of them do if you think too much. Interesting term to know: "semantic satiation"

The idea that GOT is an assertion, a la "I got this", is certainly odd. My leaning is that maybe that suggests it's better as a version of GET that ensures the lookup was not NULL? Otherwise you'd wind up writing oddities like got get. :-/

So this may play a role here in code that wishes to be more cautious about NULLs, as really get. That phrasing makes REALLY look a bit favorable. :-/

TRY would be nice (but it's taken)

I wish we had a short name like TRY available. That would look good:

>> append x try select [a 10 b 20] 'c
** Error: e.g. "You TRY'd but did not succeed, and got a NULL"
** Near: try ** select [a 10 ... (blah blah

But right now it's what powers the "blank in, null out" convention that helps long chains of expressions optimize yet gives error locality. That's pretty solid stuff, IMO (quick recap):

>> data: [a [b 1]]

>> select select data 'a 'b
== 1

>> select select data 'x 'b
** Script Error: select requires series argument to not be null
** Near: [... select data 'x ~~ 'b]

>> select try select data 'x 'b
; null

This fits into the angle of how NULL is still error-causing in many slots, and must be defused into blanks to be accepted in most parameters...(that aren't refinements!)

When it was an UNSET!=>NONE! converter, BrianH suggested TO-VALUE (which I independently proposed when I wanted the operation), and he also proposed DEFANG (weird, and also less appropriate in light of the premise here that NULL is fairly mild).

I don't know what decent name TRY could be pushed to in order to retake it. DENULL sucks. BLANKIFY sucks. REIFY is awfully grandiose.

What's nice about TRY here i.m.o. is how it reads at the callsite. You don't have to know that it turns nulls into blanks, you just sort of see it in a chain mitigating an error. There is MAYBE:

>> select maybe select data 'x 'b
; null

I don't like it as much for this, and think the MAYBE operation is a lot cooler for what it does right now.

DID would also be nice (but also taken)

>> append x did select [a 10 b 20] 'c
** Error: Thought you DID get a value, but you didn't, it was NULL
** Near: try ** select [a 10 ... (blah blah

DID is serving a good purpose as a complement to NOT, and I'm quite attached to it. It has also made it into the C sources (replacing the !! "operator")

We Never Figured Out The ? Operator

Maybe this is common enough that the ? operator could be taken for it...

>> append x ? select [a 10 b 20] 'c
** Error: e.g. "Asked the big question 'are you a value?' and it wasn't"
** Near: ? ** select [a 10 ... (blah blah

Perhaps not... but it does raise the point that we are asking for sort of a general evaluator operation or something at the callsite to say "I don't want this to be a NULL, here". Maybe unicode or emoji... check mark?

>> append x ✓ select [a 10 b 20] 'c

In fact, just calling it CHECK is an option...though that sounds like something that would be more generic. Or VERIFY? Those sound awfully more grandiose and parameterized than simply seeing if something is null or not. But rebol's fluidity is about letting you name any of these things out of the way if you find them objectionable.

Anyway, REALLY isn't going to get used for anything else (at least no time soon) so it's not like it's hurting anything. I'm just afraid that if it's too gnarly to use that people won't get into the habit of supplementing their code with a nice annotation saying "I expect this to succeed".

The floor is open for thoughts. Short words preferred. Might this be the mysterious use for BE?

>> be 300 + 4
== 304

>> be "I'm an ANY-VALUE!, therefore I am."
== "I'm an ANY-VALUE!, therefore I am."

Doesn't make as much sense at the callsite, though:

>> append x be select [a 10 b 20] 'c
** Script Error: e.g. "A NULL is nothing, and thus cannot BE"
** Near: be ** select [a 10 ... (blah blah


>> append x can select [a 10 b 20] 'c
** Script Error: e.g. "Thought you could get a non-NULL, but you COULDN'T"
** Near: can ** select [a 10 ... (blah blah

Problem being it sounds a little like a question word. append x can any [ ].

Another one I had wondered about was THE. Probably better than BE, but still a bit obtuse.

>> append x the select [a 10 b 20] 'c
** Script Error: e.g. "Can't use THE to refer to something that's not there"
** Near: the ** select [a 10 ... (blah blah

>> y: null
>> append x the y
** Script Error: e.g. "Can't use THE to refer to something that's not there"
** Near: the ** y

That's...maybe not objectively awful.

Urg. Opinions?

After reading my list, I started feeling like nothing seemed to rival ENSURE. Which gave me the idea of retaking it for ensuring something's not NULL and then doing the match in two steps. So instead of just saying ensure [integer! text!] thing you'd say ensure match [integer! text!] thing.

That looks pretty good to the casual observer, because all failed MATCH returns NULL, right? It's a little more typing, but it's literate--and you can abbreviate it if you do it a lot. (matches: chain [:match | :ensure]) Then you have a fully generic ENSURE as its own part.

Then I tried it and remembered why you can't do it this way. MATCH can be given falsey things to test, like BLANK! or LOGIC! false, or even <opt> to pass NULL itself. When that happens and it matches, the result is converted to VOID!. See the section here: "How MATCH uses VOID! to warn you of a tricky case"

This means that REALLY MATCH (or after the theorized renaming to ENSURE MATCH) is not a substitute for today's ENSURE behavior. To illustrate the situation as it looks right now:

block: [1 _ 3]

if ensure [blank! integer!] second block [
   print "Why would you test something that FAILs if it doesn't succeed?"
   print "You wouldn't, so no one writes this pattern!"
   print "So no need to worry about VOID!ing a blank"

if match [blank! integer!] second block [
    print "...but you might easily write something like this.  :-("
    print "It's good to catch if you do via VOID!"
    print "To mitigate it, you can say `if value? match [...]`"
    print "And there's EITHER-MATCH if your use was more complex"

data: really match [blank! integer!] second block
; ^-- you just got VOID! and not the BLANK you wanted :-/

I might try to say this fell into the category of me overthinking things, except this is a really easy mistake to make with a matching dialect. And for a double whammy, look at this:

 >> x: really match <opt> null
 == #[void]

There you have two problems compounded. Firstly MATCH didn't want to give a deceptively falsey result (it did match) so it helped you know with VOID!. But even if it had given you a falsey result, REALLY would have rejected it...because the input you are matching was NULL. Yet REALLY-MATCH can do this just fine due to understanding the combination:

 >> x: really-match <opt> null
 ; null

Long story short: ENSURE is probably good how it is. VOID! may no longer make sense for MATCH on falsey input vs. raising an error, though. Like I said--these are hard puzzles to fit together.

So maybe keep brainstorming.

>> append x non-null select [a 10 b 20] 'c
** Script Error: e.g. "Being outright literal might not be the worst idea"
** Near: non-null ** select [a 10 ... (blah blah

For that matter, NON could be an anti-ENSURE that is generic.

>> non integer! <foo>
== <foo>

>> non integer! 3
** Script Error: e.g. "you said it was not an integer and it was!"

So non null x would be just an instance of this generalized check. really is 6 characters to that 8, but that's a much more powerful concept, and reads rather unambiguously.

So far I'm liking:

  • NON as the anti-ENSURE, providing non null as one option (along with being generalized)
  • THE as a potential shorthand for non null, which would be used by those in the know who have absorbed what it means
  • GOT as a shorthand for non null get

After thinking about it, REALLY is probably not as bad as I've made it out to be--but given that it's not as patently obvious as non null you'd have to look it up. By which point, you might as well have looked up THE and learned something much shorter that does the same thing.

1 Like

Anything that is not on a 'standard' keyboard does not belong in code (/ language) unless it is something that is to be printed.

Really no happy alternative here unless perhaps OUTCOME.

>> append x outcome select [a 10 b 20] 'c

With editors, search and replace, macros/etc. I feel it's a bit of a waste of UTF-8 support to not be willing to entertain the idea that there are alternative spellings for things that use symbols. APL is precedent, and being able to "go there" is a strength of Rebol.

That said, I like my proposal as explained. non null xthe x. NON seems like a very useful inverse ENSURE to me. THE might be a little weird but it's short and not entirely nonsensical; so it's better than REALLY.

If someone were inclined to say ✓: :the then that should be considered within the scope of the free choice that Rebol seeks to give you.

I do not think it should not be possible to use utf-8 code like that. It should be possible.
Not really suitable for use in the standard codebase of the project or standard functions.
What users / developers do for their code they must know for themselves. I do not consider it really convenient to use.

How about affirm ? Could also do where, expect, assume, presume, suppose, must, need.

1 Like

Hmm, MUST is pretty good, hadn't thought of that!

append data must select block item

One thing I've sort of flipped about on is the difference in attitudes between "English can't be a language of relevance in the post-singularity future" vs. "The advent of the Internet and Wikipedia, and English-dominance in programming culture, is hardening the language more firmly than before." Time will tell.

A mixed bag of other options: valid, extant, real, usable, impose

1 Like

VALID seems like it should be used for something. Maybe not this, though.

At the moment I'm liking how THE looks and its brevity, but MUST conveys a bit more of the meaning from REALLY.

viable, must-have, must-be

THE has a purpose that now seems obvious: literally the thing you are saying. (e.g. Rebol2's QUOTE):

>> the x
== x

This means MUST is looking to be victorious, for those who want it.

>> must find "abc" "b"
== "bc"

>> must find "abc" "q"
** Error: MUST requires argument to not be NULL    

But an issue that should make everyone happier is that NULL is becoming accepted fewer places. For instance, you can no longer APPEND a NULL. You have to TRY it to turn it into a BLANK!...

>> append [a b c] find "abc" "q"
** Script Error: append requires value argument to not be null

>> append [a b c] try find "abc" "q"
== [a b c]

NULL's emphasis is on being a semi-ornery value that permits word access and is falsey, but isn't really accepted most places...including not being able to be put in blocks. So there should be fewer MUST needed, maybe even more about getting error locality than being necessary to trigger an error ultimately.