2
$\begingroup$

Please, consider

$Pre = If[go, #, Null] &;

Now, this

go = True;
a = 1;
b = 1;
go = TrueQ @ (b != 0);
a/b

returns 1, and this

go = True;
a = 1;
b = 0;
go = TrueQ @ (b != 0);
a/b

throws a Power::infy message. The reason is that: Unless $Pre is assigned to be a function which holds its arguments unevaluated, input expressions will be evaluated before $Pre is applied (from Documentation Center)

Let's consider, instead

    $Pre = If[go, #, Null] &;
    go = True;
    SetAttributes[$Pre, HoldAll];

This still give 1

go = True;
a = 1;
b = 1;
go = TrueQ @ (b != 0);
a/b

but this

go = True;
a = 1;
b = 0;
go = TrueQ @ (b != 0);
a/b

should give Null. On the contrary, the error message appears again. Can you, please, explain why ?

addendum

With

$Pre = Function[{arg}, If[go, arg, Null], HoldAll];

by

go = True;
a = 1;
b = 1;
go = TrueQ@(b != 0);
a/b

I get

If[go,go=True;,Null]
If[go,a=1;,Null]
If[go,b=1;,Null]
If[go,go=TrueQ[b!=0];,Null]
If[go,a/b,Null]

and

go = True;
a = 1;
b = 0;
go = TrueQ@(b != 0);
a/b

returns

If[go,go=True;,Null]
If[go,a=1;,Null]
If[go,b=0;,Null]
If[go,go=TrueQ[b!=0];,Null]
If[go,a/b,Null]
$\endgroup$
2
  • 3
    $\begingroup$ The value of $Pre should be a function with attribute HoldAll; in your case, you could try $Pre = Function[{arg}, If[go, arg, Null], HoldAll]. I haven't tested it yet though. $\endgroup$
    – MarcoB
    Commented Mar 27, 2016 at 22:20
  • $\begingroup$ Thanks for the reply. Please, see above. $\endgroup$ Commented Mar 28, 2016 at 8:17

1 Answer 1

2
$\begingroup$

First of all start a new kernel. The following evaluates without a problem:

go = True;
a = 1;
b = 1;
go = TrueQ@(b != 0);

So far so good, i.e. go == True. Now

$Pre = Function[{arg}, If[go, arg, Null], HoldAll];
a/b

evaluates to 1 which is correct. Now restart the kernel again, and type

go = True;
a = 1;
b = 0;
go = TrueQ@(b != 0);

Again everything is working, i.e. go == False. Now evaluate

$Pre = Function[{arg}, If[go, arg, Null], HoldAll];
a/b

and you will get Null. Again, this is the correct response. However you are doing something quite differently. You start by assigning a value to $Pre like this:

$Pre = Function[{arg}, If[go, arg, Null], HoldAll];

and then you do this:

go = True;
a = 1;
b = 1;
go = TrueQ@(b != 0);
a/b

and it's not working, because the function you assigned to $Pre is preventing the assignment of a value to go, and any subsequent assignment, from happening.

Function[{arg}, If[go, arg, Null], HoldAll][go = True]
-> (arguments are held) Function[{arg}, If[go, go = True, Null]]
-> If[go, go = True, Null] (cannot be evaluated, no assignment is happening)

If[go, ...] does not evaluate because go is neither true nor false.

What is happening in your first example, $Pre = If[go, #, Null] &;, is slightly different. Again reset your kernel and run the following:

$Pre = If[go, #, Null] &;
go = True;

What happened here? Mathematica did something like this:

If[go, #, Null]&[go = True] 
-> (the argument is not held) If[go, #, Null]&[True]

when the argument was evaluated, go was assigned a value as a side effect because the argument is not held. This actually solves the problem with the previous approach, but it has the new problem that you noticed: because arguments are not held, a/b is evaluated. The flow is like this:

If[go, #, Null]&[a/b]
-> If[go, #, Null]&[ComplexInfinity]
-> If[go, ComplexInfinity, Null]
-> Null

So the result is right, but because a/b was evaluated it will still print the error message. You can avoid the error message by typing Quiet[a/b].

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.