What to call the anti-DEFAULT?

DEFAULT exists to run a block of code to give something a value if it doesn't have one already.

 >> unset 'x
 >> x: default [10 + 20]
 >> print x
 30

 >> x: <some-tag>
 >> x: default [10 + 20]
 >> print x
 <some-tag>

With DEFAULT, the basic version treats both blanks and voids as "nothingness" and DEFAULT* only considers a void to be truly nothing, so it won't overwrite a blank.

@gchiu at one time asked for an "anti-default". Rather than make the decision of whether to overwrite or not based on the content of the variable and only sometimes evaluate the block...always evaluate the block, then decide whether to overwrite or not based on the result of that evaluation.

The name suggested for it was UPDATE:

>> x: <some-tag>
>> x: update [()]
>> print x
<some-tag>

 >> x: <some-tag>
 >> x: update [10 + 20]
 >> print x
 30

This seems very useful to me, especially when used with conditionals. While simple conditionals can move assignments into the block of code, e.g. x: if c [v] => if c [x: v], more complex instances might have several points they'd have to selectively do the same assignment:

number-of-variants: update [
   case [
       whatever1 [do some stuff | 1020] ;-- update for this case
       whatever2 [do some stuff | blank] ;-- don't update in this case
       whatever3 [do some stuff | 304] ;-- update for this case 
   ] ;-- don't update if no matches
]

As with DEFAULT it would ordinarily consider the right hand side evaluating to blank to be the same as void, e.g. not a new value, and a UPDATE* would overwrite even if it was blank...only not if void.

But what we noticed was that UPDATE has been taken for a somewhat esoteric port action that I don't think anyone is using at the moment.

This raises a bigger question about what exactly the plan is about taking generic global namespace words away from the language and generalizing them in case a port might want to use them. I said this:

What one notices with the "word space" in Rebol is that there has been a sort of ambition to take generic words and in the grammar prefix them before things. So if you say update X it can be polymorphic where x is a port or a string or whatever.

So it seems that swiping something like the word UPDATE for an enfixed operator is bad. But yet, even without enfixing, this genericity runs up against another Rebol policy of fixed arity. If arity is fixed, how many parameters does the UPDATE operation that works for all time take?

The cheat is to make it arity 2, and then worst comes to worst, you find some way to fit whatever you want to say into a block. Or add refinements that somehow only work for some targets and not others.

Having previously expressed skepticism of the refinement model and other things about ports, I really do wonder if DO is being overloaded with a task it is unfit for, in a language that's supposed to be about dialecting. Should there be a generic operator, like foo <- [ ... ] and it just writes instructions at ports, where they're expected to know their "language" and arity of instructions?

I'm suggesting something for the anti-default though

>> help something
something is a WORD! bound to a context, but has no value.

for the reason that something can not come out of nothing

Alternatives include becomes and be which aren't used.

UPDATE also is used for database manipulation.
TLUAFED as anti DEFAULT.
Or some other creative option, INGEST, TAKE-IN, TRY-ASSIGN
I like WHATEVER too.

@gchiu suggests MIGHT

I think I like it. Though one thought is that x: might [...] has the problem of it sounding a bit like the thing that might happen or not is the code in the block running, vs the assignment that might happen.

(Writing might x: [...] may make it look a bit more like it's the assignment which might happen, at the cost of making it look like it might assign the block literally. :-/)

Anyway, MIGHT is my favorite so far.

Use your magic wand
x: DIBBEDEEDABBEDEEBOO [...]

Yes MIGHT is a good candidate.
Introduce it and if a better option comes along it can always be replaced by that.

There's also PERHAPS to throw in this mix.

I actually think that MAYBE--which is currently used for other purposes--is probably better. Unfortunately, the purpose maybe is serving at the moment is important. It performs tests on a value via a little "testing dialect", and if the value passes the test, it is that value...else it is blank.

>> maybe [integer! string!] 10
== 10

>> maybe [integer! string!] <some-tag>
== _

>> maybe :even? 10
== 10

>> maybe :even? 3
== _

A stronger version of it is called REALLY which instead of returning blank, will error if the test fails.

It would seem x: maybe [...] is better than x: might [...] for the anti-default. I guess something about MAYBE makes me feel like it's single arity, whereas words like ENSURE make me think "ensure what about the value". ensure [integer! string!] foo seems natural to me, while maybe [integer! string!] foo is less natural.

So ENSURE and REALLY could switch places...it's just that can't think of a better name for today's MAYBE. Words like FILTER and their brethren have a lot of expectations built up on them about operating on data sets as opposed to just one value.

Since TRY(/EXCEPT) has been replaced by TRAP(/WITH), it might be repurposed. Could confuse people who have expectations set up around TRY, but it actually kind of makes sense:

 >> try :even? 10
 == 10

 >> try :even? 3
 == _

 >> ensure :even? 10
 == 10

 >> ensure :even? 3
 ** Script Error: 3 failed ENSURE test

Well, instead of maybe we could use could.