3
$\begingroup$

Consider the following code:

list={1,2}
MemberQ[list, x_ /; (x == #)] & /@ list

This gives {True,True}

MemberQ[list,form] means that an element of List matches form,

But how does mathematica know what to put for the pattern x_?

Asked differently, I view the above MemberQ as doing the following:

  • MemberQ is a pure function as input above
  • Map (/@) applies list to the MemberQ (pure) function
    • This means that Map evaluates MemberQ with each element of list in place of #
  • What part of the code tells mathematica what to use for the named pattern x_??. (in other words, how does mathematica know what $x$ is when checking x==# is true or not)

I thought maybe Map was applying the list elements to both # and x_, but

f[x_, #] & /@ {5}

gives {f[x_,5]}


Edit: An example of where this construct is potentially relevant: This answer


Edit 2: I think maybe this is what is happen:

First let us look at MemberQ[list,x_]. This will give True For (almost?) list. What is this doing? This is saying does list match the form of Pattern[x,Blank[]]. Well, Pattern[x,Blank[]], is just any expression, so yes list matches.

Now let us consider MemberQ[list,x_/;(x==#)]. This is asking whether list matches patterns that are an expression AND have (x==#). Well, if # is an expression, it will match (the condition will be satisfied), and since we are doing /@list, we are asking if expressions of the form in list match elements in list, which is true.

$\endgroup$
1
  • 2
    $\begingroup$ Wrapping Trace around the computation might give some information about the binding. $\endgroup$ Commented Jan 30, 2020 at 0:18

2 Answers 2

1
$\begingroup$

I think perhaps you are seeking or misunderstanding the function of /; which is shorthand for Condition. You write: "how does mathematica know what x is when checking x==# is true or not." The value bound to the pattern x_ is substituted into the right hand side of /; where x appears, in the manner of rules or function definitions.

Compare:

f[x_] := Print[something[x]]

f /@ {1, 2, 3}

MemberQ[{1, 2, 3}, x_ /; Print[something[x]]]

Cases[{1, 2, 3}, x_ :> Print[something[x]]]

These all print:

something1

something[2]

something[3]


Preserved for reference, you wrote:

I will try rephrasing: what is "the value bound to the pattern" in the 3rd and 4th lines of your code? I look at the second line and I see map that says "hey, apply {1,2,3} to f. But in lines 3 and 4 I don't see what part of the commands binds a value to x (I understand that the value bound to x is substituted in the right hand side, but I don't understand why (in your lines 3 and 4) 1,2, and 3 are being bound to x)

Both MemberQ and Cases have an implicit levelspec(1) of {1}, as does Map. Writing these out in explicit form:

MemberQ[{1, 2, 3}, x_ /; Print[x], {1}];
Cases[{1, 2, 3}, x_ :> Print[x], {1}];
Map[Print, {1, 2, 3}, {1}];

A different levelspec can be used for each, e.g. {0, 1} to include the complete expression:

MemberQ[{1, 2, 3}, x_ /; Print[x], {0, 1}];
Cases[{1, 2, 3}, x_ :> Print[x], {0, 1}];
Map[Print, {1, 2, 3}, {0, 1}];

Each function also supports the Heads option.

Observe that List in List[1, 2, 3] is itself a level one component:

MemberQ[{1, 2, 3}, x_ /; Print[x], {1}, Heads -> True];
Cases[{1, 2, 3}, x_ :> Print[x], {1}, Heads -> True];
Map[Print, {1, 2, 3}, {1}, Heads -> True];

(Printing omitted throughout to avoid cluttering this post.)

$\endgroup$
2
  • $\begingroup$ I will try rephrasing: what is "the value bound to the pattern" in the 3rd and 4th lines of your code? I look at the second line and I see map that says "hey, apply {1,2,3} to f. But in lines 3 and 4 I don't see what part of the commands binds a value to x (I understand that the value bound to x is substituted in the right hand side, but I don't understand why (in your lines 3 and 4) 1,2, and 3 are being bound to x) $\endgroup$
    – majmun
    Commented Jan 31, 2020 at 7:49
  • $\begingroup$ @majmun Got it! :-) $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2020 at 14:57
1
$\begingroup$

It is applying the test to each element of the list. Consider this:

list = {1, 2}
MemberQ[list, x_ /; (x + # == 4)] & /@ list

{False, True}

When x and # are both 2 the x_ pattern as 2 is tested in MemberQ. Otherwise the x_ pattern is False. I.e. MemberQ[list, False] which in turn yields False.

In the case of your code

MemberQ[list, x_ /; (x == #)] & /@ list

it seems unlikely the test would ever yield False, but then again strange cases can be produced:

list = {a = 1, Unevaluated[1 + a]};
MemberQ[list, x_ /; (x == #)] & /@ list

{True, False}

I.e. The x pattern remains unevaluated while # evaluates in the map, so

Unevaluated[1 + a] == 2 tests False and then MemberQ does too.

Finally,

The constructions in the "potentially relevant" answer you mention are these:

MemberQ[{1, 2, 3}, _?(# == 2 &)]

and

MemberQ[{1, 2, 3}, x_ /; x == 2]

both of which are equivalent, and evaluate to True. Your actual case is like the latter, with a pure function # added for the map.

MemberQ[{1, 2, 3}, x_ /; x == #] & /@ {2, 4}

{True, False}

$\endgroup$
2
  • $\begingroup$ But why are x and # being taken to be the same? I realize that x_ stands for any expression, and we call it x, but when I look at the code It looks to me like it needs to be told two things: what is the expression x_, and what is #. Obviously this is not the case $\endgroup$
    – majmun
    Commented Jan 29, 2020 at 22:58
  • 1
    $\begingroup$ Using the x_ pattern just facilitates a test on #, so it is testing itself. And its value is each item in list, taken in turn. $\endgroup$ Commented Jan 29, 2020 at 23:02

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.