Question about nested not rated

When trying to mimic the behavior of the RuleDelayed evaluation, I came across an unexpected behavior of nested Unevaluated . Consider:

 In[1]:= f[Verbatim[Unevaluated][expr_]] := f[expr] f[Unevaluated[1 + 1]] f[ Unevaluated@Unevaluated [1 + 1]] f[ Unevaluated@Unevaluated @Unevaluated[1 + 1]] f[ Unevaluated@Unevaluated @ Unevaluated@Unevaluated [1 + 1]] Out[2]= f[Unevaluated[1 + 1]] Out[3]= f[2] Out[4]= f[Unevaluated[1 + 1]] Out[5]= f[2] 

You can see that only an even number of nested Unevaluated shells Unevaluated completely removed. Why?

+6
source share
2 answers

Use Trace to find out why:

 In[1]:= f[Verbatim[Unevaluated][expr_]]:=f[expr] In[2]:= f[Unevaluated[1+1]]//Trace Out[2]= {f[1+1],f[Unevaluated[1+1]]} 
  • Due to the defining special property of the Unevaluated language Unevaluated , f[Unevaluated[1 + 1]] is evaluated in the same way as f[1 + 1] , except that 1 + 1 remains unvalued.
  • f[1 + 1] does not match the definition you specified for f .
  • Therefore, f[Unevaluated[1 + 1]] remains unsatisfactory.

While:

 In[3]:= f[ Unevaluated@Unevaluated [1 + 1]] // Trace Out[3]= {f[Unevaluated[1+1]],f[1+1],{1+1,2},f[2]} 
  • Due to the defining special property of the Unevaluated language Unevaluated , f[ Unevaluated@Unevaluated [1 + 1]] is evaluated in the same way as f[Unevaluated[1 + 1]] , except that Unevaluated[1 + 1] remains invaluable.
  • f[Unevaluated[1 + 1]] matches the definition you specified for f and evaluates to f[1 + 1] .
  • Therefore, f[ Unevaluated@Unevaluated [1 + 1]] is evaluated as f[2] .
+8
source

The key is that before the expression matches the pattern, one Unevaluated layer is Unevaluated . From docs :

f[Unevaluated[expr]] works effectively by temporarily setting attributes that f does not argue its argument, then evaluating f[expr] .

Thus, in the first case, f[Unevaluated[1 + 1]] is evaluated as f[1 + 1] , but remains unappreciated during pattern matching, even if f has no Hold* attributes, and since nothing matches f[1 + 1] , the original expression (pre -pattern-matching) is returned not evaluated.

In the second case, f[Unevaluated[Unevaluated[1 + 1]]] is evaluated as f[Unevaluated[1 + 1]] in the matching pattern that matches the pattern for f , and then f[1 + 1] is evaluated recursively, and so this way you get f[2] .

In the third case, f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]] evaluates to f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]] , matches and recursively evaluates to f[Unevaluated[1 + 1]] and we will return to the first case.

In the fourth case, f[Unevaluated[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]] coincides with f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]] , recursively evaluates f[Unevaluated[Unevaluated[1 + 1]]] , and we return to the second case.

NTN!

+9
source

Source: https://habr.com/ru/post/890021/


All Articles