In realtà, la funzione ValueQ non è innocente, in quanto le perdite di valutazione per codice con effetti collaterali. Esempi:
ClearAll[f, g];
f[x_] := Print[x];
g[x_][0] := Print[x];
{ValueQ[f[1]],ValueQ[g[2][0]]}
Se si rimuove l'attributo di ReadProtected ValueQ e guarda il codice, si vedrà perché - il codice è molto semplice e fa un lavoro decente per solo OwnValues. Ecco una versione più complessa, che ho sviluppato per evitare questo problema (è possibile verificare che, almeno per gli esempi di cui sopra, non perde di valutazione):
ClearAll[symbolicHead];
SetAttributes[symbolicHead, HoldAllComplete];
symbolicHead[f_Symbol[___]] := f;
symbolicHead[f_[___]] := symbolicHead[f];
symbolicHead[f_] := Head[Unevaluated[f]];
ClearAll[partialEval];
SetAttributes[partialEval, HoldAllComplete];
partialEval[a_Symbol] /; OwnValues[a] =!= {} :=
Unevaluated[partialEval[a]] /. OwnValues[a];
partialEval[a : f_Symbol[___]] /; DownValues[f] =!= {} :=
With[{dv = DownValues[f]},
With[{eval = Hold[partialEval[a]] /. dv},
ReleaseHold[eval] /;
(First[Extract[eval, {{1, 1}}, HoldComplete]] =!=
HoldComplete[a])]];
partialEval[a_] :=
With[{sub = SubValues[Evaluate[symbolicHead[a]]]},
With[{eval = Hold[partialEval[a]] /. sub},
ReleaseHold[eval] /;
(First[Extract[eval, {{1, 1}}, HoldComplete]] =!=
HoldComplete[a])]];
ClearAll[valueQ];
SetAttributes[valueQ, HoldAllComplete];
valueQ[expr_] := partialEval[expr] =!= Unevaluated[partialEval[expr]];
Questo non è completa, giacché non è così account per UpValues, NValues e FormatValues, ma questo sembra essere sufficiente per le tue esigenze dichiarate, e anche, le regole per questi tre casi extra possono forse anche essere aggiunte lungo le stesse linee come sopra.
fonte
2011-01-07 00:53:55
Grande, sembra funzionare come previsto per tutti i 3 moduli –