Во-первых, я думаю, что вы выявили здесь ошибку.
Во-вторых, я думаю, что могу дать некоторое представление о том, почему это происходит, имея в виду, что мои знания о внутренностях математики ограничены.
Утверждение типа: f[z_] := 2 z в полной форме:
SetDelayed[f[Pattern[z, Blank[]]], 2 z]
Это устанавливает DownValue[f] в:
{HoldPattern[f[z_]] :> 2 z}
Затем позже, когда выражение, такое как f[2], оценивается позже, выполняется что-то вроде следующего:
f[2] /. HoldPattern[f[z_]] :> 2 z
Что будет оцениваться как 4. Теперь все это возможно, потому что сопоставление с образцом происходит с Pattern[z, Blank[]] из первого блока кода. Это работает, даже если вы ранее установили z на число. Другими словами.
z = 5;
f[z_] := 2*z
По-прежнему производит те же значения downvalue для f:
{HoldPattern[f[z_]] :> 2 z}
Это возможно, потому что Pattern имеет атрибут HoldFirst.
Атрибут HoldFirst не является достаточной защитой, если вы оцениваете его внутри модуля. Пример:
SetAttributes[tmp, HoldFirst];
Module[{expr},
expr = 2 z;
tmp[expr]
]
выходы:
tmp[expr$8129]
Я предлагаю, поскольку атрибут HoldFirst не обеспечивает иммунитет к правилу перезаписи переменных модуля, чтобы любой шаблон в правиле, содержащем локальную переменную, переписывал свои переменные шаблона. sym->Symbol[SymbolName[sym]~~"$"]
Module[{expr},
Hold[z_ -> (z; expr)]
]
(*Hold[z$_ -> (z$; expr$1391)]*)
z был переписан с обеих сторон правила в простом альфа-преобразовании.
Если правило не содержит локальной переменной, перезаписи не происходит:
Module[{expr},
Hold[z_ -> (z)]
]
(*Hold[z_ -> z]*)
Вместо того, чтобы искать, соответствует ли локальная переменная переменной правила, применяется вышеуказанное общее правило.
Итак, проблема в том, что локальное выражение не оценивается до того, как произойдет альфа-преобразование. Или, возможно, даже лучше было бы иметь expr, обернутое в лениво оцениваемое альфа-преобразование, которое потребуется для RuleDelayed.
В Block этого не происходит, потому что Block не перезаписывает ни одну из локальных переменных.
Любые другие идеи? Кто-нибудь видит дыры в моей логике?
person
Davorak
schedule
29.04.2010