# The built-in function If behaves strangely in a procedure/function [closed]

Inside a procedure or user-defined function, If doesn't do as it should. Long ago, I found out that I should use === instead of == in a procedure in order to make the decision appear at real time. But what should I do with If? Thanks a lot.

=== edit ====

This is my program to generate sequences of "1", "2" and "3" with no equal consecutive pairs. "If" doesn't seem to work properly, or I really miss something. (allow at most 3 copies of each number.)

add[seq_, n1_, n2_, n3_] :=
Do[
Block[{nn1, nn2, nn3, vn, vv = Sort[{seq[[i]], seq[[i + 1]]}]},
Print["between ", vv];
If[vv == {2, 3}, If[n1 >= 3, Goto[next], nn1 = n1 + 1; vn = 1],
If[vv == {1, 3}, If[n2 >= 3, Goto[next], nn2 = n2 + 1; vn = 2],
If[vv == {1, 2}, If[n3 >= 3, Goto[next], nn3 = n3 + 1; vn = 3],
Print["error"]]]];
Print["Insert ", vn, " to ", seq];
add[Insert[seq, vn, i + 1], nn1, nn2, nn3];
Label[next]], {i, Length[seq] - 1}]
add[{1, 2, 3}, 1, 1, 1]


At first step, it inserts 3 but the next step it couldn't say vn=2

between {1,2} Insert 3 to {1,2,3} between {1,3} Insert vn to {1,3,2,3}

Strange! Replace "==" by "===" make it better but still error.

(ps. At first, "Switch" didn't work)

==== edit to be better but same error =====

Replace Goto&Label by Continue and sequential If by Switch.

add[seq_, n1_, n2_, n3_] :=
Do[
Block[{nn1, nn2, nn3, vn, vv = Sort[{seq[[i]], seq[[i + 1]]}]},
Print["Between ", vv];
Switch[vv,
{2, 3}, If[n1 >= 3, Continue[], nn1 = n1 + 1; vn = 1],
{1, 3}, If[n2 >= 3, Continue[], nn2 = n2 + 1; vn = 2],
{1, 2}, If[n3 >= 3, Continue[], nn3 = n3 + 1; vn = 3],
_, Print["error"]];
Print["insert ", vn, " to ", seq];
add[Insert[seq, vn, i + 1], nn1, nn2, nn3]]
, {i, Length[seq] - 1}]

add[{1, 2, 3}, 1, 1, 1]


I expect the following output.

Between {1,2}

insert 3 to {1,2,3}

Between {1,3}

insert 2 to {1,3,2,3}

-
example? If should behave the same way inside a Module or outside. If you find that If does not do so, this would qualify as a huge bug and should be submitted to supprt@wolfram.com for more investigation. But again, you should provide an example of what you mean as this could be a user error. – Nasser Mar 3 at 1:24
Please provide an example, as I really don't understand what you are asking. – rcollyer Mar 3 at 1:41
I could not follow your code. But you say  program to generate sequences of "1", "2" and "3" with no equal consecutive pairs. Is this sort of what you mean? lst = {1, 2, 3}; Permutations[#] & /@ Subsets[lst] This gives !Mathematica graphics if this is not what you want, then may be give small example of input/output needed. (ps. not good idea to use procedural coding in M, no goto, etc...) – Nasser Mar 3 at 5:00
f[n_] := RandomChoice[{1, 2, 3}, n] //. {a___, x_, x_, b___} -> {a, x, b} – belisarius Mar 3 at 7:12
This is not a Mathematica problem: it is a logic problem in your code. During your Switch you give at most one of nn1, nn2, or nn3 a value, but then you recursively call add using these undefined values, so your procedure breaks down. The first instance of this with your input is after you have inserted 3 to {1, 2, 3}: only nn3 is set at this point, and you have not handled the subsequent add[{1,3,2,3}, nn1, nn2, 2] correctly. Voting to close as Too Localized. – Oleksandr R. Mar 3 at 13:58

## closed as too localized by Yves Klett, Oleksandr R., m_goldberg, Daniel Lichtblau, Sjoerd C. de VriesMar 3 at 15:15

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, see the FAQ.

It's not the If that is causing your problems, but simply the errors in your program logic. In many passes of your loop nn1, nn2, nn3 and/or vn never receive a numeric value. You then call your function with variables that aren't always defined. The If statement then fails, for instance because you get a test like

{1,2}=={1,vn}


for which Mathematica can not determine the corresponding Boolean value. It returns unevaluated, causing your problems. Using === instead of == forces a definite return of the test (note that that may not be correct in your case). Anything that isn't explicitly True is determined as False.

The same problem occurs with the three n1 >= 3 tests.

By the way, may I congratulate you with the first occurrence of Goto and Label in Mathematica in my experience? Ever since Edsger Dijkstra's famous article Goto Considered Harmful the use of this construction is frowned upon in CS circles and it takes some courage (or perhaps ignorance) to use it.

-
 "... first occurrence of Goto and Label in Mathematica..." — hardly the first on this site! See here and here. There are several more examples, but I'll chalk those up to OP's inexperience and answerers not wishing to change OP's code too much. – rm -rf♦ Mar 3 at 16:15 @rm-rf Objection, your honor! Selective citation! The prosecuter spirits away the clause "in my experience". ;-) – Sjoerd C. de Vries Mar 3 at 17:39 :D $\phantom{}$ – rm -rf♦ Mar 3 at 17:49 Thanks every one again for answer and info. – user6167 Mar 4 at 0:35