2

Why are the following functions

a[x___] := If[ UnsameQ[x, Null],    1, 2, 3]
b[x___] := If[ Not[SameQ[x, Null]], 1, 2, 3]

different? For example

a[]
(*1*)
a[1]
(*1*)
b[]
(*2*)
b[1]
(*1*)

In particular, why does a[] gives 1 instead of 2?

I didn't expect that also because

UnsameQ[x, y] == Not[SameQ[x, y]]
UnsameQ[x, Null] == Not[SameQ[x, Null]]
(*True*)
(*True*)

Moreover, if I define

uns[a_, b_] := UnsameQ[a, b]
nts[a_, b_] := Not[SameQ[a, b]]

the functions

c[x___] := If[nts[x, Null], 1, 2, 3]
d[x___] := If[uns[x, Null], 1, 2, 3]

are different from the previous ones:

c[]
(*3*)
c[1]
(*1*)
d[]
(*3*)
d[1]
(*1*)

Why does it happens?

The same question holds for SameQ and Not[UnsameQ]

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
Giancarlo
  • 712
  • 4
  • 11
  • 1
    You're actually evaluating UnsameQ[Null] and SameQ[Null] both of which return True. The BlankNullSequence spits out something akin to Sequence[] if you have no match. – b3m2a1 May 31 '17 at 04:52
  • 4
    One is the negation of the other with two arguments only. They take any number of arguments. When used with fewer or more arguments, the identity does not hold. Another example would be SameQ[a, b, a] and UnsameQ[a, b, a], which are both false, as these expressions are neither all identical, nor all different. – Szabolcs May 31 '17 at 07:25
  • 1
    The behaviour of SameQ is weird if there is only one parameter. SameQ[x] == True. According to the documentation, "lhs===rhs yields True if the expression lhs is identical to rhs, and yields False otherwise. " If there is no rhs, SameQ should return False, however it doesn't. – webcpu May 31 '17 at 08:01
  • This is far from trivial. Voting "leave open". – LLlAMnYP Jun 02 '17 at 11:09
  • @UnchartedWorks from the docs, e1===e2===e3 gives True if all the ei are identical. (equivalent to SameQ[e1,e2,e3]. Of course in a set of just [e1] all of the ei are identical. No reason to return False. – LLlAMnYP Jun 02 '17 at 11:15
  • @LLlAMnYP How about UnsameQ[x]? It gives True. – webcpu Jun 02 '17 at 11:37
  • @UnchartedWorks similarly, there is not a single pair of arguments that match there :-) – LLlAMnYP Jun 02 '17 at 14:17
  • @LLlAMnYP UnsameQ yields True if the expression lhs is not identical to rhs, and yields False otherwise. Should UnsameQ give False? ;) – webcpu Jun 02 '17 at 14:20
  • @UnchartedWorks see Details section: UnsameQ[e1,e2,e3] is true if no two ei are identical. There are no two ei in UnsameQ[e1] so no two ei are identical. – LLlAMnYP Jun 02 '17 at 14:22
  • @ LLlAMnYP "the expression lhs is not identical to rhs" is not equivalent to "no two ei are identical". It's confusing. – webcpu Jun 02 '17 at 14:31

1 Answers1

3

You seem to assume that a[] and b[] are the same as a[Null] and b[Null], but they are not. If you were to run a Trace on a[] and b[], you would see

Trace[a[]]

{a[], If[UnsameQ[Null], 1, 2, 3], {UnsameQ[Null], True}, If[True, 1, 2, 3], 1}

Trace[b[]]

{b[], If[!SameQ[Null], 1, 2, 3], {{SameQ[Null], True}, !True, False}, If[False, 1, 2, 3], 2}

Both UnsameQ and SameQ are only seeing one argument, which is an edge case not discussed in the Mathematica documentation (), but the traces show how of these functions behave differently when given a single argument, explaining the differences you are seeing.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
  • An illustration: f[x___] := HoldComplete@x; f[] returns HoldComplete[]. – Alexey Popkov May 31 '17 at 05:16
  • That's is interesting: so let's say that if I have a function f[a_,b___] and I want that if I input only one argument I get f[a]=a but if I input 2 arguments I get f[a,b]=2a+b. How can I implement that? – Giancarlo May 31 '17 at 06:47
  • @Giancarlo. Please don't ask a new question in a comment. However, in the case you bring up in your comment, I would suggest f[x_] := x; f[x_, y_] := 2 x + y – m_goldberg May 31 '17 at 07:01
  • Thanks m_goldberg. Related to the original question, it's still not clear to me why a[] is different from d[], and, similarly, b[] is different from c[]. Do you have any idea why? – Giancarlo May 31 '17 at 08:58