2011-06-08 29 views
6

Cuando trying para simular el comportamiento de evaluación de RuleDelayed Me enfrenté al comportamiento inesperado de Unevaluated anidado. Consideremos:Pregunta sobre anidado No evaluado

In[1]:= f[Verbatim[Unevaluated][expr_]] := f[expr] 
f[Unevaluated[1 + 1]] 
f[[email protected][1 + 1]] 
f[[email protected]@Unevaluated[1 + 1]] 
f[[email protected]@[email protected][1 + 1]] 

Out[2]= f[Unevaluated[1 + 1]] 

Out[3]= f[2] 

Out[4]= f[Unevaluated[1 + 1]] 

Out[5]= f[2] 

Uno puede ver que sólo un número par de envoltorios anidados Unevaluated se eliminan por completo. ¿Por qué?

Respuesta

8

Uso Trace para ver por qué:

In[1]:= f[Verbatim[Unevaluated][expr_]]:=f[expr] 

In[2]:= f[Unevaluated[1+1]]//Trace 
Out[2]= {f[1+1],f[Unevaluated[1+1]]} 
  1. Debido a la característica especial de definición de la construcción Unevaluated idioma, f[Unevaluated[1 + 1]] evalúa al igual que f[1 + 1], excepto el 1 + 1 se deja sin evaluar.
  2. f[1 + 1] no coincide con la definición que usted dio para f.
  3. Por lo tanto, f[Unevaluated[1 + 1]] permanece sin evaluar.

Considerando lo siguiente:

In[3]:= f[[email protected][1 + 1]] // Trace 
Out[3]= {f[Unevaluated[1+1]],f[1+1],{1+1,2},f[2]} 
  1. Debido a la característica especial de definición de la construcción Unevaluated idioma, f[[email protected][1 + 1]] evalúa como f[Unevaluated[1 + 1]], excepto el Unevaluated[1 + 1] se deja sin evaluar.
  2. f[Unevaluated[1 + 1]] coincide con la definición que dio para f, y se evalúa como f[1 + 1].
  3. Por lo tanto, f[[email protected][1 + 1]] evalúa a f[2].
+0

Wow literalmente te gané a la respuesta por segundos =) –

+0

¡Sí! Buena coincidencia para una pregunta de una hora. Me gusta tu respuesta mejor en general. –

+0

Explicación muy clara, ¡gracias! Ambas respuestas son excelentes y se complementan entre sí, pero su explicación en forma de una secuencia de decisiones tomadas por el evaluador es más esquemática y más fácil de recordar. Entonces acepto tu respuesta. –

9

La clave es que, de hecho, una capa de Unevaluated se elimina antes de que la expresión coincida con el patrón. Desde el docs:

f[Unevaluated[expr]] funciona de manera efectiva por atributos de ajuste temporal de modo que f sostiene su argumento no evaluada, a continuación, evaluar f[expr].

Así, en el primer caso, f[Unevaluated[1 + 1]] se evalúa como f[1 + 1], pero restante sin evaluar durante coincidencia de patrones, aunque f carece de Hold* atributos, y puesto que nada coincide f[1 + 1], la original de expresión (pre-patronaje emparejamiento) se devuelve sin evaluar.

En el segundo caso, f[Unevaluated[Unevaluated[1 + 1]]] evalúa como f[Unevaluated[1 + 1]] en el patrón de coincidencias, que hace coincidir con un patrón de f, y luego f[1 + 1] se evalúa de forma recursiva, y por lo tanto presentamos lo mejor f[2].

En el tercer caso, f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]] se evalúa como f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]], coincide y se evalúa recursivamente como f[Unevaluated[1 + 1]], y volvemos al primer caso.

En el cuarto caso, f[Unevaluated[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]] coincide en f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]], evalúa recursivamente f[Unevaluated[Unevaluated[1 + 1]]], y volvemos al segundo caso.

HTH!