Function Repository Resource:

SetUnless

Source Notebook

Initialize a value unless it already satisfies a given condition

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["SetUnless"][expr,val,test]

evaluates expr=val if test[expr] does not return True.

ResourceFunction["SetUnless"][val,test]

represents an operator form of ResourceFunction["SetUnless"].

ResourceFunction["SetUnless"][test]

represents an operator form of ResourceFunction["SetUnless"].

Details and Options

In ResourceFunction["SetUnless"][expr,val,f], the value of expr will be set to val if f[expr] returns anything other than True.
The following forms are equivalent:
ResourceFunction["SetUnless"][expr,val,test]
ResourceFunction["SetUnless"][test][expr,val]
ResourceFunction["SetUnless"][val,test][expr]
ResourceFunction["SetUnless"][test][val][expr]
ResourceFunction["SetUnless"] has the attributes HoldFirst and SequenceHold.

Examples

Basic Examples (3) 

Initialize a symbol:

In[1]:=
ResourceFunction["SetUnless"][x, 1, IntegerQ]
Out[1]=

The value is not set if it already satisfies the given criteria:

In[2]:=
ResourceFunction["SetUnless"][x, 2, IntegerQ]
Out[2]=
In[3]:=
x
Out[3]=

The expr does not need to be a symbol:

In[4]:=
ResourceFunction["SetUnless"][f[1], Pi, NumericQ]
Out[4]=
In[5]:=
ResourceFunction["SetUnless"][f[1], E, NumericQ]
Out[5]=
In[6]:=
f[1]
Out[6]=

Use the operator forms:

In[7]:=
ResourceFunction["SetUnless"][StringQ][a, "hello"]
Out[7]=
In[8]:=
ResourceFunction["SetUnless"][StringQ][a, "world"]
Out[8]=
In[9]:=
a
Out[9]=
In[10]:=
ResourceFunction["SetUnless"][123, IntegerQ][b]
Out[10]=
In[11]:=
ResourceFunction["SetUnless"][456, IntegerQ][b]
Out[11]=
In[12]:=
b
Out[12]=
In[13]:=
ResourceFunction["SetUnless"][ListQ][{1, 2, 3}][c]
Out[13]=
In[14]:=
ResourceFunction["SetUnless"][ListQ][{4, 5, 6}][c]
Out[14]=
In[15]:=
c
Out[15]=

Scope (2) 

Use Unevaluated to prevent evaluation of the second argument unless needed:

In[16]:=
file = FileNameJoin@{$TemporaryDirectory, CreateUUID[]}
Out[16]=
In[17]:=
ResourceFunction["SetUnless"][file, Unevaluated[Echo[CreateFile[]]], FileExistsQ]
Out[17]=
In[18]:=
ResourceFunction["SetUnless"][file, Unevaluated[Echo[CreateFile[]]], FileExistsQ]
Out[18]=

Without using Unevaluated, the second argument will evaluate, even if not being used:

In[19]:=
ResourceFunction["SetUnless"][file, Echo[CreateFile[]], FileExistsQ]
Out[19]=

Use an additional Unevaluated to get the same behavior as SetDelayed:

In[20]:=
ResourceFunction["SetUnless"][x, Unevaluated[Unevaluated[Echo["evaluated"]]], False &]
In[21]:=
Definition[x]
Out[21]=

Applications (2) 

Initialize a counter if it doesn’t already exist before incrementing:

In[22]:=
Do[ResourceFunction["SetUnless"][counter, 0, IntegerQ]; counter++, 10];
counter
Out[21]=

If the counter ends up with an invalid value, Increment will no longer return an integer:

In[23]:=
counter = "bad value"
Out[23]=
In[24]:=
counter++
Out[24]=

Use SetUnless to ensure a valid value before incrementing:

In[25]:=
Do[ResourceFunction["SetUnless"][counter, 0, IntegerQ]; counter++, 25];
counter
Out[12]=

Create a function that stores data in an association and initializes it if necessary:

In[26]:=
save[key_, expr_] := (
   ResourceFunction["SetUnless"][$saved, <||>, AssociationQ];
   $saved[key] = expr
   );
In[27]:=
save["a", 1]
Out[27]=
In[28]:=
save["b", 2]
Out[28]=

Check the data:

In[29]:=
$saved
Out[29]=

Clear the data:

In[30]:=
Clear[$saved]

Now save will reinitialize the association and start again:

In[31]:=
save["c", 3]
Out[31]=
In[32]:=
$saved
Out[32]=

Saving will reset the association if it is no longer valid:

In[33]:=
AppendTo[$saved, "corrupted"]
Out[33]=
In[34]:=
$saved["d"] = 4
Out[34]=
In[35]:=
$saved
Out[35]=
In[36]:=
save["e", 5]
Out[36]=
In[37]:=
$saved
Out[37]=

Properties and Relations (2) 

If test[expr] does not explicitly yield True, it will be considered False:

In[38]:=
ResourceFunction["SetUnless"][x, "value", f]
Out[38]=
In[39]:=
x
Out[39]=

SetUnless has the SequenceHold attribute:

In[40]:=
ResourceFunction["SetUnless"][x, Sequence[1, 2, 3], False &]
Out[40]=
In[41]:=
x
Out[41]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Version History

  • 1.0.0 – 17 April 2019

Related Resources

License Information