# Weird behaviour of If inside of Block definitions?

I am on Mathematica 9 and I have discovered, that, when I use If inside of the definitions of the Block variables, then other, previously defined Block variables don't seem to be replaced correctly in the second argument of If:

test[a_] = Block[{b = a, c = If[b > 0, b, 0]}, c]


Will return

If[a > 0, b, 0]


I would have expected it to return If[a > 0, a, 0]. Is this a bug? If not, can I understand, why this happens? Is there a general workaround for this?

PS: I'm not sure about the tagging for this question, maybe someone knows a better fitting tag.

• @Kuba: I see. And I see why this would be useful for an If. I'm using Piecewise instead now, where everything gets evaluated. Commented Jun 23, 2017 at 9:03
• My answer is quite dense, should be clear if you follow links though. But let me know if anything is not clear.
– Kuba
Commented Jun 23, 2017 at 9:07

No it is not, a>0 isn't True or False so it does not evaluate subsequent arguments of If.

Also, notice that c = If[b > 0, b, 0] can't use b = a and the replacement happens when the body of Block, is evaluated, which is a subtle difference. Check the second link and related topics. See:

Block[{b = a, c = If[b > 0, b, 0]}, Hold[c] /. OwnValues[c]]

Hold[If[b > 0, b, 0]]


A tip, unless you know you need Block you should not use it, it may have subtle implications. Use With/Module, check the first link to compare.

Also check the last link to understand = vs :=.

At the end I'd rewrite it:

test[a_] := Module[{b = a, c }, c = If[b > 0, b, 0]; c]


• I always preferred Block over Module and With, because I can do things like f[x_] = Block[{a = x*x, b = 2x}, a + b]. Would you say that I'm better off always using Module and doing f[x_] := Module[{a,b}, a = x*x; b = 2x; a + b]? Commented Jun 23, 2017 at 9:22
• @Wauzl that is indeed useful but Block scopes 'more than you see', which is not generally a problem but can be. mathematica.stackexchange.com/q/25673/5478