Orderless pattern matching

16

6

The MMA docs state that "In matching patterns with Orderless functions, all possible orders of arguments are tried".

Why then does the following not work?

plus[x__Integer, y__Real] := x+y
Attributes[plus] = {Orderless}
plus[2.5, 3]

Got:

plus[2.5, 3]

Expected:

5.5

Note that the expression does match the pattern.

MatchQ[plus[2.5, 3], plus[x__Integer, y__Real]]

returns True if and only if plus has the Orderless Attribute.

sn6uv

Posted 2015-01-10T15:27:49.430

Reputation: 545

Related: (304), (5067), (18060)

– Mr.Wizard – 2015-01-10T15:53:25.533

Answers

21

I think the documentation needs to be more clear on this; the order of definitions is important:

Remove[plus]

Attributes[plus] = {Orderless};
plus[x__Integer, y__Real] := x + y

plus[2.5, 3]
5.5

So the Orderless attribute must be active at the time the definition is created.

Noteworthy is that definitions made before setting the attribute can cohabit with those made after setting it in a very useful way. For years I didn't know this until Simon Woods made me aware of it with this answer:

Here is my own application of that behavior:


OrderlessPatternSequence

Version 10.1 introduces OrderlessPatternSequence which allows orderless behavior to be applied one definition (or even pattern) at a time.

Remove[plus]

plus[OrderlessPatternSequence[x__Integer, y__Real]] := x + y

plus[a_, b_] /; a < b := {a, b}

The first definition works in orderless fashion:

plus[2.5, 3, 1.8]
7.3

The second definition retains normal behavior:

plus[3, 1]
plus[3, 1]

Mr.Wizard

Posted 2015-01-10T15:27:49.430

Reputation: 259 163