En primer lugar creo que ha expuesto un error aquí.
En segundo lugar, creo que puedo ofrecer una idea de por qué sucede esto, teniendo en cuenta que mi conocimiento de los aspectos internos de las matemáticas es limitado.
Una declaración como: f [z_]: = 2 z en forma completa es:
SetDelayed[f[Pattern[z, Blank[]]], 2 z]
Esto establece el DownValue [f] a:
{HoldPattern[f[z_]] :> 2 z}
Luego, más tarde cuando una expresión, como f [2], es posteriormente se evalúa algo así como que se está preformado siguientes:
f[2] /. HoldPattern[f[z_]] :> 2 z
cual sería evaluar a 4. Ahora bien, esto es todo lo po Es posible porque la coincidencia de patrones está ocurriendo con el Patrón [z, Blanco []] del primer bloque de códigos. Esto funciona incluso si ha establecido perviously z en un número. En otras palabras.
z = 5;
f[z_] := 2*z
todavía produce los mismos downvalues para f:
{HoldPattern[f[z_]] :> 2 z}
Esto es posible porque patrón tiene el atributo HoldFirst.
El atributo HoldFirst no es suficiente protección si evalúa esto dentro de un Módulo. Ejemplo:
SetAttributes[tmp, HoldFirst];
Module[{expr},
expr = 2 z;
tmp[expr]
]
salidas:
tmp[expr$8129]
propongo porque HoldFirst Atributo no proporciona inmunidad a la regla de reescritura variables de módulo que cualquier patrón en una regla que contiene una variable local han reescrito sus variables del patrón . sim-> Símbolo [SymbolName [SYM] ~~ "$"]
Module[{expr},
Hold[z_ -> (z; expr)]
]
(*Hold[z$_ -> (z$; expr$1391)]*)
z ha ser reescrito en ambos lados de la regla en una simple conversión alfa.
Si la regla no contiene una variable local sin reescritura sucede:
Module[{expr},
Hold[z_ -> (z)]
]
(*Hold[z_ -> z]*)
En lugar de buscar para ver si una variable local coincida con una variable regla se aplica la regla de la manta por encima.
Así que el problema es que el expr local no se evalúa antes de que tenga lugar la conversión alfa. O quizás sería aún mejor tener expr envuelto en una conversión alfa evaluada de forma perezosa que se requeriría para RuleDelayed.
Esto no ocurre en Bloque porque el Bloque no reescribe ninguna de las variables locales.
¿Alguna otra idea? ¿Alguien ve algún agujero en mi lógica?
Guau, ¡no es lo que yo llamaría una bonita solución para el trabajo, pero es impresionante saberlo! – dreeves
Es por eso que vuelvo a SO todos los días. Me aprende algo: **. – Timo
Prefiero tomar el golpe de rendimiento inesperado de tener expr envuelto en una conversión alfa perezosa en lugar de lidiar con la sintaxis inconsistente. ¿Qué consideraciones de diseño del lenguaje están entrando para jugar aquí? – Davorak