When to prefer $Failed over Failure objects?
Failure[]
objects in Wolfram Language may contain arguments that change for each iteration, so FixedPoint
will never return:
In[1]:=
Clear[remove];
remove[LeafNode[tag_, s_String /; StringContainsQ[s, "a"], data_]] := LeafNode[tag, StringReplace[s, "a" -> ""], data]
remove[args___] := Failure["Bad!!", <|"Arguments" -> {args}|>]
In[2]:= TimeConstrained[FixedPoint[remove, LeafNode[foo, "aaab", <||>]], 0.3, $TimeConstrainedReturned]
Out[2]= $TimeConstrainedReturned
In the above example, remove[LeafNode[foo, "b", <||>]]
is eventually called, and Failure["Bad!!", <|"Arguments" -> {LeafNode[foo, "b", <||>]}|>]
is returned.
And then remove[Failure["Bad!!", <|"Arguments" -> {LeafNode[foo, "b", <||>]}|>]]
is called, and Failure["Bad!!", <|"Arguments" -> {Failure["Bad!!", <|"Arguments" -> {LeafNode[foo, "b", <||>]}|>]}|>]
is returned.
And so on.
This is in infinite regress, and FixedPoint
will never return.
It would be better to simply return $Failed
in this case, so that FixedPoint
may return:
In[1]:=
Clear[remove];
remove[LeafNode[tag_, s_String /; StringContainsQ[s, "a"], data_]] := LeafNode[tag, StringReplace[s, "a" -> ""], data]
remove[___] := $Failed
In[2]:= FixedPoint[remove, LeafNode[foo, "aaab", <||>]]
Out[2]= $Failed