How to make an analog of InString[]? - wolfram-mathematica

I have discovered that InString[] does not work in MathLink mode when sending input with EnterExpressionPacket header. So I need to define my own function that returns previous input line. One way I have developed here does not work in some cases:
In[1]:= Unevaluated[2 + 2]
With[{line = $Line - 1}, HoldForm[In[line]]] /. (DownValues[In])
Out[1]= Unevaluated[2 + 2]
Out[2]= 2 + 2
This is because RuleDelayed has no HoldAllComplete attribute. Adding this attribute makes this OK:
In[1]:= Unprotect[RuleDelayed];
SetAttributes[RuleDelayed, HoldAllComplete];
Protect[RuleDelayed];
Unevaluated[2 + 2]
With[{line = $Line - 1}, HoldForm[In[line]]] /. DownValues[In]
Out[4]= Unevaluated[2 + 2]
Out[5]= Unevaluated[2 + 2]
But modifying built-in functions generally is not a good idea. Is there a better way to do this?

It seems that I have solved the problem. Here is the function:
In[1]:=
getLastInput := Module[{num, f},
f = Function[{u, v},
{u /. {In -> num, HoldPattern -> First}, HoldForm[v]}, HoldAllComplete];
First#Cases[
Block[{RuleDelayed = f}, DownValues[In]],
{$Line - 1, x_} -> x, {1}, 1]]
In[2]:=
Unevaluated[2+2]
getLastInput
Out[2]=
Unevaluated[2+2]
Out[3]=
Unevaluated[2+2]
And I just have got the answer to the question on InString in MathLink mode from Todd Gayley (Wolfram Research):
InString is only assigned when using
EnterTextPacket, not
EnterExpressionPacket. There is no
string form of the input when sending
EnterExpressionPacket (whose content
is, by definition, already an
expression).
EDIT:
I just have found that my code does not work with input expressions with head Evaluate. The solution is to replace HoldForm by HoldComplete in my code:
getLastInput := Module[{num, f},
f = Function[{u, v},
{u /. {In -> num, HoldPattern -> First}, HoldComplete[v]}, HoldAllComplete];
First#Cases[
Block[{RuleDelayed = f}, DownValues[In]],
{$Line - 1, x_} -> x, {1}, 1]]
This works well. Another approach would be to unprotect HoldForm and set up attribute HoldAllComplete on it. I'm wondering why HoldForm does not have this attribute by default?
EDIT 2:
In the comments for the main question Leonid Shifrin suggested much better solution:
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldComplete[In[line]]/.DownValues[In]]]
See comments for details.
EDIT 3:
The last code can be made even better for by replacing HoldComplete by double HoldForm:
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldForm#HoldForm[In[line]]/.DownValues[In]]]
The idea is taken from presentation by Robby Villegas of Wolfram Research at the 1999 Developer Conference. See subsection "HoldCompleteForm: a non-printing variant of HoldComplete (just as HoldForm is to Hold)" in "Working With Unevaluated Expressions" notebook posted here.

I would use $Pre and $Line for this; unlike $PreRead, it's applied to input expressions, not input strings or box forms. All you need is to assign it a function that has the HoldAllComplete attribute, like this one which I've adapted from the example in the documentation:
SetAttributes[saveinputs, HoldAllComplete];
saveinputs[new_] :=
With[{line = $Line},
inputs[line] = HoldComplete[new]; new]
$Pre = saveinputs;
I tested this with MathLink, and the behavior seems to be what you desired (I've elided some of the transcript to highlight the key point):
In[14]:= LinkWrite[link,
Unevaluated[
EnterExpressionPacket[
SetAttributes[saveinputs, HoldAllComplete];
saveinputs[new_] :=
With[{line = $Line},
inputs[line] = HoldComplete[new]; new];
$Pre = saveinputs;]]]
In[15]:= LinkRead[link]
Out[15]= InputNamePacket["In[2]:= "]
In[20]:= LinkWrite[link,
Unevaluated[EnterExpressionPacket[Evaluate[1 + 1]]]]
In[21]:= LinkRead[link]
Out[21]= OutputNamePacket["Out[2]= "]
In[21]:= LinkRead[link]
Out[21]= ReturnExpressionPacket[2]
In[24]:= LinkWrite[link, Unevaluated[EnterExpressionPacket[DownValues[inputs]]]]
In[26]:= LinkRead[link]
Out[26]= ReturnExpressionPacket[
{HoldPattern[inputs[2]] :> HoldComplete[Evaluate[1 + 1]],
HoldPattern[inputs[3]] :> HoldComplete[DownValues[inputs]]}]

I just have found simpler but dangerous way:
In[3]:= Unevaluated[2 + 2]
Trace[In[$Line - 1]] // Last
Trace[In[$Line - 1]] // Last
Out[3]= Unevaluated[2 + 2]
Out[4]= Unevaluated[2 + 2]
During evaluation of In[3]:= $RecursionLimit::reclim: Recursion depth of 256 exceeded. >>
During evaluation of In[3]:= $RecursionLimit::reclim: Recursion depth of 256 exceeded. >>
During evaluation of In[3]:= $IterationLimit::itlim: Iteration limit of 4096 exceeded. >>
Out[5]= Hold[In[$Line-1]]
Does anybody know a way to make it safe?

Related

Unevaluated form of a[[i]]

Consider following simple, illustrating example
cf = Block[{a, x, degree = 3},
With[{expr = Product[x - a[[i]], {i, degree}]},
Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr]
]
]
This is one of the possible ways to transfer code in the body of a Compile statement. It produces the Part::partd error, since a[[i]] is at the moment of evaluation not a list.
The easy solution is to just ignore this message or turn it off. There are of course other ways around it. For instance one could circumvent the evaluation of a[[i]] by replacing it inside the Compile-body before it is compiled
cf = ReleaseHold[Block[{a, x, degree = 3},
With[{expr = Product[x - a[i], {i, degree}]},
Hold[Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr]] /.
a[i_] :> a[[i]]]
]
]
If the compiled function a large bit of code, the Hold, Release and the replacement at the end goes a bit against my idea of beautiful code. Is there a short and nice solution I have not considered yet?
Answer to the post of Szabolcs
Could you tell me though why you are using With here?
Yes, and it has to do with the reason why I cannot use := here. I use With, to have something like a #define in C, which means a code-replacement at the place I need it. Using := in With delays the evaluation and what the body of Compile sees is not the final piece of code which it is supposed to compile. Therefore,
<< CompiledFunctionTools`
cf = Block[{a, x, degree = 3},
With[{expr := Product[x - a[[i]], {i, degree}]},
Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr]]];
CompilePrint[cf]
shows you, that there is a call to the Mathematica-kernel in the compiled function
I4 = MainEvaluate[ Function[{x, a}, degree][ R0, T(R1)0]]
This is bad because Compile should use only the local variables to calculate the result.
Update
Szabolcs solution works in this case but it leaves the whole expression unevaluated. Let me explain, why it is important that the expression is expanded before it is compiled. I have to admit, my toy-example was not the best. So lets try a better one using With and SetDelayed like in the solution of Szabolcs
Block[{a, x}, With[
{expr := D[Product[x - a[[i]], {i, 3}], x]},
Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr]
]
]
Say I have a polynomial of degree 3 and I need the derivative of it inside the Compile. In the above code I want Mathematica to calculate the derivative for unassigned roots a[[i]] so I can use the formula very often in the compiled code. Looking at the compiled code above
one sees, that the D[..] cannot be compiled as nicely as the Product and stays unevaluated
11 R1 = MainEvaluate[ Hold[D][ R5, R0]]
Therefore, my updated question is: Is it possible to evaluate a piece of code without evaluating the Part[]-accesses in it better/nicer than using
Block[{a, x}, With[
{expr = D[Quiet#Product[x - a[[i]], {i, 3}], x]},
Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr]
]
]
Edit: I put the Quiet to the place it belongs. I had it in front of code block to make it visible to everyone that I used Quiet here to suppress the warning. As Ruebenko pointed already out, it should in real code always be as close as possible to where it belongs. With this approach you probably don't miss other important warnings/errors.
Update 2
Since we're moving away from the original question, we should move this discussion maybe to a new thread. I don't know to whom I should give the best answer-award to my question since we discussed Mathematica and Scoping more than how to suppress the a[[i]] issue.
Update 3
To give the final solution: I simply suppress (unfortunately like I did all the time) the a[[i]] warning with Quiet. In a real example below, I have to use Quiet outside the complete Block to suppress the warning.
To inject the required code into the body of Compile I use a pure function and give the code to inline as argument. This is the same approach Michael Trott is using in, e.g. his Numerics book. This is a bit like the where clause in Haskell, where you define stuff you used afterwards.
newtonC = Function[{degree, f, df, colors},
Compile[{{x0, _Complex, 0}, {a, _Complex, 1}},
Block[{x = x0, xn = 0.0 + 0.0 I, i = 0, maxiter = 256,
eps = 10^(-6.), zeroId = 1, j = 1},
For[i = 0, i < maxiter, ++i,
xn = x - f/(df + eps);
If[Abs[xn - x] < eps,
Break[]
];
x = xn;
];
For[j = 1, j <= degree, ++j,
If[Abs[xn - a[[j]]] < eps*10^2,
zeroId = j + 1;
Break[];
];
];
colors[[zeroId]]*(1 - (i/maxiter)^0.3)*1.5
],
CompilationTarget -> "C", RuntimeAttributes -> {Listable},
RuntimeOptions -> "Speed", Parallelization -> True]]##
(Quiet#Block[{degree = 3, polynomial, a, x},
polynomial = HornerForm[Product[x - a[[i]], {i, degree}]];
{degree, polynomial, HornerForm[D[polynomial, x]],
List ### (ColorData[52, #] & /# Range[degree + 1])}])
And this function is now fast enough to calculate the Newton-fractal of a polynomial where the position of the roots is not fixed. Therefore, we can adjust the roots dynamically.
Feel free to adjust n. Here it runs up to n=756 fluently
(* ImageSize n*n, Complex plange from -b-I*b to b+I*b *)
With[{n = 256, b = 2.0},
DynamicModule[{
roots = RandomReal[{-b, b}, {3, 2}],
raster = Table[x + I y, {y, -b, b, 2 b/n}, {x, -b, b, 2 b/n}]},
LocatorPane[Dynamic[roots],
Dynamic[
Graphics[{Inset[
Image[Reverse#newtonC[raster, Complex ### roots], "Real"],
{-b, -b}, {1, 1}, 2 {b, b}]}, PlotRange -> {{-b, b}, {-
b, b}}, ImageSize -> {n, n}]], {{-b, -b}, {b, b}},
Appearance -> Style["\[Times]", Red, 20]
]
]
]
Teaser:
Ok, here is the very oversimplified version of the code generation framework I am using for various purposes:
ClearAll[symbolToHideQ]
SetAttributes[symbolToHideQ, HoldFirst];
symbolToHideQ[s_Symbol, expandedSymbs_] :=! MemberQ[expandedSymbs, Unevaluated[s]];
ClearAll[globalProperties]
globalProperties[] := {DownValues, SubValues, UpValues (*,OwnValues*)};
ClearAll[getSymbolsToHide];
Options[getSymbolsToHide] = {
Exceptions -> {List, Hold, HoldComplete,
HoldForm, HoldPattern, Blank, BlankSequence, BlankNullSequence,
Optional, Repeated, Verbatim, Pattern, RuleDelayed, Rule, True,
False, Integer, Real, Complex, Alternatives, String,
PatternTest,(*Note- this one is dangerous since it opens a hole
to evaluation leaks. But too good to be ingored *)
Condition, PatternSequence, Except
}
};
getSymbolsToHide[code_Hold, headsToExpand : {___Symbol}, opts : OptionsPattern[]] :=
Join ## Complement[
Cases[{
Flatten[Outer[Compose, globalProperties[], headsToExpand]], code},
s_Symbol /; symbolToHideQ[s, headsToExpand] :> Hold[s],
Infinity,
Heads -> True
],
Hold /# OptionValue[Exceptions]];
ClearAll[makeHidingSymbol]
SetAttributes[makeHidingSymbol, HoldAll];
makeHidingSymbol[s_Symbol] :=
Unique[hidingSymbol(*Unevaluated[s]*) (*,Attributes[s]*)];
ClearAll[makeHidingRules]
makeHidingRules[symbs : Hold[__Symbol]] :=
Thread[List ## Map[HoldPattern, symbs] -> List ## Map[makeHidingSymbol, symbs]];
ClearAll[reverseHidingRules];
reverseHidingRules[rules : {(_Rule | _RuleDelayed) ..}] :=
rules /. (Rule | RuleDelayed)[Verbatim[HoldPattern][lhs_], rhs_] :> (rhs :> lhs);
FrozenCodeEval[code_Hold, headsToEvaluate : {___Symbol}] :=
Module[{symbolsToHide, hidingRules, revHidingRules, result},
symbolsToHide = getSymbolsToHide[code, headsToEvaluate];
hidingRules = makeHidingRules[symbolsToHide];
revHidingRules = reverseHidingRules[hidingRules];
result =
Hold[Evaluate[ReleaseHold[code /. hidingRules]]] /. revHidingRules;
Apply[Remove, revHidingRules[[All, 1]]];
result];
The code works by temporarily hiding most symbols with some dummy ones, and allow certain symbols evaluate. Here is how this would work here:
In[80]:=
FrozenCodeEval[
Hold[Compile[{{x,_Real,0},{a,_Real,1}},D[Product[x-a[[i]],{i,3}],x]]],
{D,Product,Derivative,Plus}
]
Out[80]=
Hold[Compile[{{x,_Real,0},{a,_Real,1}},
(x-a[[1]]) (x-a[[2]])+(x-a[[1]]) (x-a[[3]])+(x-a[[2]]) (x-a[[3]])]]
So, to use it, you have to wrap your code in Hold and indicate which heads you want to evaluate. What remains here is just to apply ReleseHold to it. Note that the above code just illustrates the ideas, but is still quite limited. The full version of my method involves other steps which make it much more powerful but also more complex.
Edit
While the above code is still too limited to accomodate many really interesting cases, here is one additional neat example of what would be rather hard to achieve with the traditional tools of evaluation control:
In[102]:=
FrozenCodeEval[
Hold[f[x_, y_, z_] :=
With[Thread[{a, b, c} = Map[Sqrt, {x, y, z}]],
a + b + c]],
{Thread, Map}]
Out[102]=
Hold[
f[x_, y_, z_] :=
With[{a = Sqrt[x], b = Sqrt[y], c = Sqrt[z]}, a + b + c]]
EDIT -- Big warning!! Injecting code using With or Function into Compile that uses some of Compile's local variables is not reliable! Consider the following:
In[63]:= With[{y=x},Compile[x,y]]
Out[63]= CompiledFunction[{x$},x,-CompiledCode-]
In[64]:= With[{y=x},Compile[{{x,_Real}},y]]
Out[64]= CompiledFunction[{x},x,-CompiledCode-]
Note the renaming of x to x$ in the first case. I recommend you read about localization here and here. (Yes, this is confusing!) We can guess about why this only happens in the first case and not the second, but my point is that this behaviour might not be intended (call it a bug, dark corner or undefined behaviour), so relying on it is fragile ...
Replace-based solutions, like my withRules function do work though (this was not my intended use for that function, but it fits well here ...)
In[65]:= withRules[{y->x},Compile[x,y]]
Out[65]= CompiledFunction[{x},x,-CompiledCode-]
Original answers
You can use := in With, like so:
cf = Block[{a, x, degree = 3},
With[{expr := Product[x - a[[i]], {i, degree}]},
Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr]
]
]
It will avoid evaluating expr and the error from Part.
Generally, = and := work as expected in all of With, Module and Block.
Could you tell me though why you are using With here? (I'm sure you have a good reason, I just can't see it from this simplified example.)
Additional answer
Addressing #halirutan's concern about degree not being inlined during compilation
I see this as exactly the same situation as if we had a global variable defined that we use in Compile. Take for example:
In[18]:= global=1
Out[18]= 1
In[19]:= cf2=Compile[{},1+global]
Out[19]= CompiledFunction[{},1+global,-CompiledCode-]
In[20]:= CompilePrint[cf2]
Out[20]=
No argument
3 Integer registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
I0 = 1
Result = I2
1 I1 = MainEvaluate[ Function[{}, global][ ]]
2 I2 = I0 + I1
3 Return
This is a common issue. The solution is to tell Compile to inline globals, like so:
cf = Block[{a, x, degree = 3},
With[{expr := Product[x - a[[i]], {i, degree}]},
Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr,
CompilationOptions -> {"InlineExternalDefinitions" -> True}]]];
CompilePrint[cf]
You can check that now there's no callback to the main evaluator.
Alternatively you can inject the value of degree using an extra layer of With instead of Block. This will make you wish for something like this very much.
Macro expansion in Mathematica
This is somewhat unrelated, but you mention in your post that you use With for macro expansion. Here's my first (possibly buggy) go at implementing macro expansion in Mathematica. This is not well tested, feel free to try to break it and post a comment.
Clear[defineMacro, macros, expandMacros]
macros = Hold[];
SetAttributes[defineMacro, HoldAllComplete]
defineMacro[name_Symbol, value_] := (AppendTo[macros, name]; name := value)
SetAttributes[expandMacros, HoldAllComplete]
expandMacros[expr_] := Unevaluated[expr] //. Join ## (OwnValues /# macros)
Description:
macros is a (held) list of all symbols to be expanded.
defineMacro will make a new macro.
expandMacros will expand macro definitions in an expression.
Beware: I didn't implement macro-redefinition, this will not work while expansion is on using $Pre. Also beware of recursive macro definitions and infinite loops.
Usage:
Do macro expansion on all input by defining $Pre:
$Pre = expandMacros;
Define a to have the value 1:
defineMacro[a, 1]
Set a delayed definition for b:
b := a + 1
Note that the definition of b is not fully evaluated, but a is expanded.
?b
Global`b
b:=1+1
Turn off macro expansion ($Pre can be dangerous if there's a bug in my code):
$Pre =.
One way:
cf = Block[{a, x, degree = 3},
With[{expr = Quiet[Product[x - a[[i]], {i, degree}]]},
Compile[{{x, _Real, 0}, {a, _Real, 1}}, expr]]]
be careful though, it you really want this.
Original code:
newtonC = Function[{degree, f, df, colors},
Compile[{{x0, _Complex, 0}, {a, _Complex, 1}},
Block[{x = x0, xn = 0.0 + 0.0 I, i = 0, maxiter = 256,
...
RuntimeOptions -> "Speed", Parallelization -> True]]##
(Quiet#Block[{degree = 3, polynomial, a, x},
polynomial = HornerForm[Product[x - a[[i]], {i, degree}]];
...
Modified code:
newtonC = Function[{degree, f, df, colors},
Compile[{{x0, _Complex, 0}, {a, _Complex, 1}},
Block[{x = x0, xn = 0.0 + 0.0 I, i = 0, maxiter = 256,
...
RuntimeOptions -> "Speed", Parallelization -> True],HoldAllComplete]##
( (( (HoldComplete###)/.a[i_]:>a[[i]] )&)#Block[{degree = 3, polynomial, a, x},
polynomial = HornerForm[Product[x - a[i], {i, degree}]];
...
Add HoldAllComplete attribute to the function.
Write a[i] in place of a[[i]].
Replace Quiet with (( (HoldComplete###)/.a[i_]:>a[[i]] )&)
Produces the identical code, no Quiet, and all of the Hold stuff is in one place.

Simple power counting

How can one add the number of powers of x in expressions like the following?
x^2f[x]g[x^3]
or
x^2g[x^4]
or
x^2g[x^2f[x^2]]
The counting is such that all these examples must return 6.
I was thinking of using Count with some pattern, but I didn't manage to construct a pattern for this.
Here's my quick hack - some of the behaviour (see the final example) might not be quite what you want:
SetAttributes[countPowers, Listable]
countPowers[expr_, symb_] := Module[{a},
Cases[{expr} /. symb -> symb^a // PowerExpand, symb^n_ :> n,
Infinity] /. a -> 1 // Total]
Then
In[3]:= countPowers[{x^2 f[x] g[x^3], x^2 g[x^4], x^2 g[x^2 f[x^2]]}, x]
Out[3]= {6, 6, 6}
and
In[4]:= countPowers[{x^(2 I) g[x^3], g[x, x^4],
x^2 g[E^(2 Pi I x) , f[x]^x]}, x]
Out[4]= {3 + 2 I, 5, 5}
Since you want to count x as an implicit power of 1, you could use this:
powerCount[x_Symbol][expr_] :=
Tr # Reap[PowerExpand[expr] /. {x^n_ :> Sow[n], x :> Sow[1]}][[2,1]]
powerCount[x] /#
{
x^2f[x]g[x^3],
x^2g[x^4],
x^2g[x^2f[x^2]]
}
{6, 6, 6}
Alternatively, this could be written without Sow and Reap if that makes it easier to read:
powerCount[x_Symbol][expr_] :=
Module[{t = 0}, PowerExpand[expr] /. {x^n_ :> (t += n), x :> t++}; t]
Either form can be made more terse using vanishing patterns, at the possible expense of clarity:
powerCount[x_Symbol][expr_] :=
Tr # Reap[PowerExpand[expr] /. x^n_ | x :> Sow[1 n]][[2, 1]]

How to make DifferenceRoot and RecurrenceTable useful for non-numeric difference equations?

In answering a physics forum question this morning, I ran into really bad performance of DifferenceRoot and RecurrenceTable compared to calculating the expressions by naively taking derivatives of an exponential generating functional. A very small amount of digging showed that DifferenceRoot and RecurrenceTable do not simplify expressions as they go.
For example, look at the following output of RecurrenceTable and how it simplifies by just Expanding the result:
In[1]:= RecurrenceTable[f[n] == a f[n - 1] + (a - 1) f[n - 2] &&
f[0] == 0 && f[1] == 1,
f, {n, 6}]
% // Expand
Out[1]= {0, 1, a, -1+a+a^2, -a+a^2+a (-1+a+a^2), 1-a-a^2+a (-1+a+a^2)+a (-a+a^2+a (-1+a+a^2))}
Out[2]= {0, 1, a, -1+a+a^2, -2 a+2 a^2+a^3, 1-2 a-2 a^2+3 a^3+a^4}
This quickly gets out of hand, as the leaf count of the 20th iteration (calculated using DifferenceRoot) shows:
dr[k_] := DifferenceRoot[Function[{f, n},
{f[n] == a f[n - 1] + (a - 1) f[n - 2], f[0] == 0, f[1] == 1}]][k]
In[2]:= dr20 = dr[20]; // Timing
dr20Exp = Expand[dr20]; // Timing
Out[2]= {0.26, Null}
Out[3]= {2.39, Null}
In[4]:= {LeafCount[dr20], LeafCount[dr20Exp]}
Out[4]= {1188383, 92}
Which can be compared to the memoized implementation
In[1]:= mem[n_] := a mem[n-1] + (a-1) mem[n-2] // Expand
mem[0] = 0; mem[1] = 1;
In[3]:= mem20 = mem[20];//Timing
LeafCount[mem20]
Out[3]= {0.48, Null}
Out[4]= 92
So my question is:
Are there any options/tricks to get DifferenceRoot and RecurrenceTable to apply a (simplifying) function as they go and thus make them useful for non-numeric work?
Edit: A Sjoerd pointed out below, I foolishly chose an example with a RSolveable closed form solution. In this question I'm primarily concerned with the behaviour of DifferenceRoot and RecurrenceTable. If it helps, imagine the the f[n-2] term is multiplied by n, so that there is no simple closed form solution.
I can't really help with your question as I haven't used those functions until now, and the docs don't give a clue. But why don't you just use RSolve here? It gives a closed form solution for each of the table's elements:
sol = f /. RSolve[f[n] == a f[n - 1] + (a - 1) f[n - 2] &&
f[0] == 0 && f[1] == 1, f, n
][[1, 1]]
sol#Range[6] // Simplify

Why does Default behave like this?

One may set a Default value for the arguments of a function:
Default[f] = 5;
And then use:
f[a_, b_.] := {a, b}
f[1, 2]
f[1]
{1, 2}
{1, 5}
This creates the following Values:
DefaultValues[f]
DownValues[f]
{HoldPattern[Default[f]] :> 5}
{HoldPattern[f[a_, b_.]] :> {a, b}}
From this one might think that the value 5 is not fixed in the definition of f, but addresses the DefaultValues assignment. However, if we change the DefaultValues, either directly or using:
Default[f] = 9;
DefaultValues[f]
{HoldPattern[Default[f]] :> 9}
and use f again:
f[1]
{1, 5}
we see that the new value is not used.
Therefore, my questions are:
Why does the default value used by f[a_, b_.] := {a, b} not change with DefaultValues?
Where is the real default value (5) stored, since it does not appear in either DownValues or DefaultValues?
Not an answer, but:
Using the behaviour that the original default is kept until the function is redefined suggests a quick work-around:
Define a global variable for the Default before any other definitions are made.
In[1]:= Default[f]:=$f
In[2]:= f[a_.]:=a
In[3]:= f[]
Out[3]= $f
In[4]:= $f=5; f[]
Out[5]= 5
In[6]:= $f=6; f[]
Out[7]= 6
In[8]:= $f=.; f[]
Out[9]= $f
This also works for Optional
In[1]:= g[a_:$g] := a
In[2]:= g[]
Out[2]= $g
In[3]:= $g=1; g[]
Out[4]= 1
From the documentation,
The necessary values for Default[f] must always be defined before _. is used as an argument of f.
Redefining f after setting Default[f] = 9; uses the new default value. So my guess is it is defined internally the first time, f is defined, and doesn't change even if DefaultValue#f stores the new value.
I have found that this behavior in the case of local rules is due to specifics of internals of RuleDelayed.
Compare:
In[1]:= Default[f] = 5;
replaceAll[f[1],
f[a_, b_.] :> Unevaluated#{a, b}] /. (Default[f] = 9; replaceAll) ->
ReplaceAll
Default[f] = 5;
Block[{RuleDelayed},
replaceAll[f[1],
f[a_, b_.] :> Unevaluated#{a, b}] /. (Default[f] = 9;
replaceAll) -> ReplaceAll]
Out[2]= {1, 5}
Out[4]= Unevaluated[{1, 9}]
One can see that Blocking RuleDelayed makes local rules to behave as one could expect.

custom function with non-standard evaluation (behaves like Table)

I'd like a function AnyTrue[expr,{i,{i1,i2,...}}] which checks if expr is True for any of i1,i2... It should be as if AnyTrue was Table followed by Or##%, with the difference that it only evaluates expr until first True is found.
Short-circuiting part is optional, what I'd really like to know is the proper way to emulate Table's non-standard evaluation sequence.
Update 11/14
Here's a solution due to Michael, you can use it to chain "for all" and "there exists" checks
SetAttributes[AllTrue, HoldAll];
SetAttributes[AnyTrue, HoldAll];
AllTrue[{var_Symbol, lis_List}, expr_] :=
LengthWhile[lis,
TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]] &] ==
Length[lis];
AnyTrue[{var_Symbol, lis_List}, expr_] :=
LengthWhile[lis,
Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &] <
Length[lis];
AllTrue[{a, {1, 3, 5}}, AnyTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
AnyTrue[{a, {1, 3, 5}}, AllTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
How about this?
SetAttributes[AnyTrue, HoldAll];
AnyTrue[expr_, {var_Symbol, lis_List}] :=
LengthWhile[lis,
Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &
] < Length[lis]
Includes short-circuiting via LengthWhile and keeps everything held where necessary so that things work as expected with var has a value outside the function:
In[161]:= x = 777;
In[162]:= AnyTrue[Print["x=", x]; x == 3, {x, {1, 2, 3, 4, 5}}]
During evaluation of In[162]:= x=1
During evaluation of In[162]:= x=2
During evaluation of In[162]:= x=3
Out[162]= True
The built-in Or is short-circuiting, too, for what it's worth. (but I realize building up the unevaluated terms with e.g. Table is a pain):
In[173]:= Or[Print[1];True, Print[2];False]
During evaluation of In[173]:= 1
Out[173]= True
This doesn't match your spec but I often use the following utility functions, which are similar to what you have in mind (they use pure functions instead of expressions with a specified variable) and also do short-circuiting:
some[f_, l_List] := True === (* Whether f applied to some *)
Scan[If[f[#], Return[True]]&, l]; (* element of list is True. *)
every[f_, l_List] := Null === (* Similarly, And ## f/#l *)
Scan[If[!f[#], Return[False]]&, l]; (* (but with lazy evaluation). *)
For example, Michael Pilat's example would become this:
In[1]:= some[(Print["x=", #]; # == 3)&, {1, 2, 3, 4, 5}]
During evaluation of In[1]:= x=1
During evaluation of In[1]:= x=2
During evaluation of In[1]:= x=3
Out[1]= True

Resources