Skip to main content
added 4 characters in body
Source Link
Lukas Lang
  • 34.4k
  • 1
  • 56
  • 99

The example at hand

One part of the confusion seems to arise from the fact that the patterns that are compared differ in two aspects: The additional ___ and the head (f vs _). LetsLet us first consider two separate examples, where the definitions only differ in one aspect.

Additional ___

We see the same behavior (i.e. patterns are incomparable) for the following simpler function definition (no upvalues and a fixed head):

Clear@f
f[___, 1, ___] := 1
f[1, ___] := 2
f[1]
(* 1 *)

Clear@f
f[1, ___] := 2
f[___, 1, ___] := 1
f[1]
(* 2 *)

This demonstrates (without having to rely on any undocumented function) that MMA deems the patterns incomparable. I have no idea why this particular example behaves the way it does, as it seems rather trivial to decide which one is more general…

Head f vs _

To show that the issue has nothing to do with f vs _, consider the following example:

Clear@h
h /: f[_h, ___] := 1
h /: _[_h, ___] := 2
f[h[1]]
(* 1 *)

Clear@h
h /: _[_h, ___] := 2
h /: f[_h, ___] := 1
f[h[1]]
(* 1 *)

As can be seen, the pattern with head f is correctly identified as more specific.

So the question "why a pattern with ff as the head is not more specific than a pattern with any head" is based on a false premise.

"The ordering of patterns" vs. "The standard evaluation procedure"

Second, I think you're confusing the ordering of definitions with the evaluation procedure: When you define a new rule for a function, the rule is inserted into the down/up-values of the associated symbol according to it's specificity. This is what the linked question is all about - i.e. how MMA decides where to insert a given rule. This has nothing to do with the second statement, "heads are evaluated first". This only affects how an expression is evaluated, given the rules that are already present at this point. Consider the following example:

h = Hold
h[Print@1]
(* Hold[Print[1]] *)

As you can see, the head of the expression, h is first evaluated to Hold, before the Print@1 expression is evaluated.

So, to summarize:

  • When a new rule for a symbol is defined, the left and right side of the assignment are first evaluated as appropriate (in most cases this means not at all). The rule is then inserted according to its specificity.
  • When an expression is evaluated, the head is evaluated first, before any of the arguments. For h[a][b], this means h, then a, then h[a], then b, then h[a][b].

The example at hand

One part of the confusion seems to arise from the fact that the patterns that are compared differ in two aspects: The additional ___ and the head (f vs _). Lets first consider two separate examples, where the definitions only differ in one aspect.

Additional ___

We see the same behavior (i.e. patterns are incomparable) for the following simpler function definition (no upvalues and a fixed head):

Clear@f
f[___, 1, ___] := 1
f[1, ___] := 2
f[1]
(* 1 *)

Clear@f
f[1, ___] := 2
f[___, 1, ___] := 1
f[1]
(* 2 *)

This demonstrates (without having to rely on any undocumented function) that MMA deems the patterns incomparable. I have no idea why this particular example behaves the way it does, as it seems rather trivial to decide which one is more general…

Head f vs _

To show that the issue has nothing to do with f vs _, consider the following example:

Clear@h
h /: f[_h, ___] := 1
h /: _[_h, ___] := 2
f[h[1]]
(* 1 *)

Clear@h
h /: _[_h, ___] := 2
h /: f[_h, ___] := 1
f[h[1]]
(* 1 *)

As can be seen, the pattern with head f is correctly identified as more specific.

So the question "why a pattern with f as the head is not more specific than a pattern with any head" is based on a false premise.

"The ordering of patterns" vs. "The standard evaluation procedure"

Second, I think you're confusing the ordering of definitions with the evaluation procedure: When you define a new rule for a function, the rule is inserted into the down/up-values of the associated symbol according to it's specificity. This is what the linked question is all about - i.e. how MMA decides where to insert a given rule. This has nothing to do with the second statement, "heads are evaluated first". This only affects how an expression is evaluated, given the rules that are already present at this point. Consider the following example:

h = Hold
h[Print@1]
(* Hold[Print[1]] *)

As you can see, the head of the expression, h is first evaluated to Hold, before the Print@1 expression is evaluated.

So, to summarize:

  • When a new rule for a symbol is defined, the left and right side of the assignment are first evaluated as appropriate (in most cases this means not at all). The rule is then inserted according to its specificity.
  • When an expression is evaluated, the head is evaluated first, before any of the arguments. For h[a][b], this means h, then a, then h[a], then b, then h[a][b].

The example at hand

One part of the confusion seems to arise from the fact that the patterns that are compared differ in two aspects: The additional ___ and the head (f vs _). Let us first consider two separate examples, where the definitions only differ in one aspect.

Additional ___

We see the same behavior (i.e. patterns are incomparable) for the following simpler function definition (no upvalues and a fixed head):

Clear@f
f[___, 1, ___] := 1
f[1, ___] := 2
f[1]
(* 1 *)

Clear@f
f[1, ___] := 2
f[___, 1, ___] := 1
f[1]
(* 2 *)

This demonstrates (without having to rely on any undocumented function) that MMA deems the patterns incomparable. I have no idea why this particular example behaves the way it does, as it seems rather trivial to decide which one is more general…

Head f vs _

To show that the issue has nothing to do with f vs _, consider the following example:

Clear@h
h /: f[_h, ___] := 1
h /: _[_h, ___] := 2
f[h[1]]
(* 1 *)

Clear@h
h /: _[_h, ___] := 2
h /: f[_h, ___] := 1
f[h[1]]
(* 1 *)

As can be seen, the pattern with head f is correctly identified as more specific.

So the question "why a pattern with f as the head is not more specific than a pattern with any head" is based on a false premise.

"The ordering of patterns" vs. "The standard evaluation procedure"

Second, I think you're confusing the ordering of definitions with the evaluation procedure: When you define a new rule for a function, the rule is inserted into the down/up-values of the associated symbol according to it's specificity. This is what the linked question is all about - i.e. how MMA decides where to insert a given rule. This has nothing to do with the second statement, "heads are evaluated first". This only affects how an expression is evaluated, given the rules that are already present at this point. Consider the following example:

h = Hold
h[Print@1]
(* Hold[Print[1]] *)

As you can see, the head of the expression, h is first evaluated to Hold, before the Print@1 expression is evaluated.

So, to summarize:

  • When a new rule for a symbol is defined, the left and right side of the assignment are first evaluated as appropriate (in most cases this means not at all). The rule is then inserted according to its specificity.
  • When an expression is evaluated, the head is evaluated first, before any of the arguments. For h[a][b], this means h, then a, then h[a], then b, then h[a][b].
added 716 characters in body
Source Link
Lukas Lang
  • 34.4k
  • 1
  • 56
  • 99

The example at hand

First, regarding your exampleOne part of the confusion seems to arise from the fact that the patterns that are compared differ in two aspects: The additional ___ and the head (f vs _). Lets first consider two separate examples, where the definitions only differ in one aspect.

Additional ___

We see the same behavior (i.e. patterns are incomparable) for the following simpler function definition (no upvalues and a fixed head):

Clear@f
f[___, 1, ___] := 1
f[1, ___] := 2
f[1]
(* 1 *)

Clear@f
f[1, ___] := 2
f[___, 1, ___] := 1
f[1]
(* 2 *)

This clearly demonstrates (without having to rely on any undocumented function) that MMA deems the patterns incomparable. It also shows that the specificity of the head has nothing to do with the issue. I have no idea why this particular example behaves the way it does, as it seems rather trivial to decide which one is more general…

Head f vs _

To show that the issue has nothing to do with f vs _, consider the following example:

Clear@h
h /: f[_h, ___] := 1
h /: _[_h, ___] := 2
f[h[1]]
(* 1 *)

Clear@h
h /: _[_h, ___] := 2
h /: f[_h, ___] := 1
f[h[1]]
(* 1 *)

As can be seen, the pattern with head f is correctly identified as more specific.

So the question "why a pattern with f as the head is not more specific than a pattern with any head" is based on a false premise.

"The ordering of patterns" vs. "The standard evaluation procedure"

Second, I think you're confusing the ordering of definitions with the evaluation procedure: When you define a new rule for a function, the rule is inserted into the down/up-values of the associated symbol according to it's specificity. This is what the linked question is all about - i.e. how MMA decides where to insert a given rule. This has nothing to do with the second statement, "heads are evaluated first". This only affects how an expression is evaluated, given the rules that are already present at this point. Consider the following example:

h = Hold
h[Print@1]
(* Hold[Print[1]] *)

As you can see, the head of the expression, h is first evaluated to Hold, before the Print@1 expression is evaluated.

So, to summarize:

  • When a new rule for a symbol is defined, the left and right side of the assignment are first evaluated as appropriate (in most cases this means not at all). The rule is then inserted according to its specificity.
  • When an expression is evaluated, the head is evaluated first, before any of the arguments. For h[a][b], this means h, then a, then h[a], then b, then h[a][b].

The example at hand

First, regarding your example: We see the same behavior for the following simpler function definition (no upvalues and a fixed head):

Clear@f
f[___, 1, ___] := 1
f[1, ___] := 2
f[1]
(* 1 *)

Clear@f
f[1, ___] := 2
f[___, 1, ___] := 1
f[1]
(* 2 *)

This clearly demonstrates (without having to rely on any undocumented function) that MMA deems the patterns incomparable. It also shows that the specificity of the head has nothing to do with the issue. I have no idea why this particular example behaves the way it does, as it seems rather trivial to decide which one is more general…

"The ordering of patterns" vs. "The standard evaluation procedure"

Second, I think you're confusing the ordering of definitions with the evaluation procedure: When you define a new rule for a function, the rule is inserted into the down/up-values of the associated symbol according to it's specificity. This is what the linked question is all about - i.e. how MMA decides where to insert a given rule. This has nothing to do with the second statement, "heads are evaluated first". This only affects how an expression is evaluated, given the rules that are already present at this point. Consider the following example:

h = Hold
h[Print@1]
(* Hold[Print[1]] *)

As you can see, the head of the expression, h is first evaluated to Hold, before the Print@1 expression is evaluated.

So, to summarize:

  • When a new rule for a symbol is defined, the left and right side of the assignment are first evaluated as appropriate (in most cases this means not at all). The rule is then inserted according to its specificity.
  • When an expression is evaluated, the head is evaluated first, before any of the arguments. For h[a][b], this means h, then a, then h[a], then b, then h[a][b].

The example at hand

One part of the confusion seems to arise from the fact that the patterns that are compared differ in two aspects: The additional ___ and the head (f vs _). Lets first consider two separate examples, where the definitions only differ in one aspect.

Additional ___

We see the same behavior (i.e. patterns are incomparable) for the following simpler function definition (no upvalues and a fixed head):

Clear@f
f[___, 1, ___] := 1
f[1, ___] := 2
f[1]
(* 1 *)

Clear@f
f[1, ___] := 2
f[___, 1, ___] := 1
f[1]
(* 2 *)

This demonstrates (without having to rely on any undocumented function) that MMA deems the patterns incomparable. I have no idea why this particular example behaves the way it does, as it seems rather trivial to decide which one is more general…

Head f vs _

To show that the issue has nothing to do with f vs _, consider the following example:

Clear@h
h /: f[_h, ___] := 1
h /: _[_h, ___] := 2
f[h[1]]
(* 1 *)

Clear@h
h /: _[_h, ___] := 2
h /: f[_h, ___] := 1
f[h[1]]
(* 1 *)

As can be seen, the pattern with head f is correctly identified as more specific.

So the question "why a pattern with f as the head is not more specific than a pattern with any head" is based on a false premise.

"The ordering of patterns" vs. "The standard evaluation procedure"

Second, I think you're confusing the ordering of definitions with the evaluation procedure: When you define a new rule for a function, the rule is inserted into the down/up-values of the associated symbol according to it's specificity. This is what the linked question is all about - i.e. how MMA decides where to insert a given rule. This has nothing to do with the second statement, "heads are evaluated first". This only affects how an expression is evaluated, given the rules that are already present at this point. Consider the following example:

h = Hold
h[Print@1]
(* Hold[Print[1]] *)

As you can see, the head of the expression, h is first evaluated to Hold, before the Print@1 expression is evaluated.

So, to summarize:

  • When a new rule for a symbol is defined, the left and right side of the assignment are first evaluated as appropriate (in most cases this means not at all). The rule is then inserted according to its specificity.
  • When an expression is evaluated, the head is evaluated first, before any of the arguments. For h[a][b], this means h, then a, then h[a], then b, then h[a][b].
Source Link
Lukas Lang
  • 34.4k
  • 1
  • 56
  • 99

The example at hand

First, regarding your example: We see the same behavior for the following simpler function definition (no upvalues and a fixed head):

Clear@f
f[___, 1, ___] := 1
f[1, ___] := 2
f[1]
(* 1 *)

Clear@f
f[1, ___] := 2
f[___, 1, ___] := 1
f[1]
(* 2 *)

This clearly demonstrates (without having to rely on any undocumented function) that MMA deems the patterns incomparable. It also shows that the specificity of the head has nothing to do with the issue. I have no idea why this particular example behaves the way it does, as it seems rather trivial to decide which one is more general…

"The ordering of patterns" vs. "The standard evaluation procedure"

Second, I think you're confusing the ordering of definitions with the evaluation procedure: When you define a new rule for a function, the rule is inserted into the down/up-values of the associated symbol according to it's specificity. This is what the linked question is all about - i.e. how MMA decides where to insert a given rule. This has nothing to do with the second statement, "heads are evaluated first". This only affects how an expression is evaluated, given the rules that are already present at this point. Consider the following example:

h = Hold
h[Print@1]
(* Hold[Print[1]] *)

As you can see, the head of the expression, h is first evaluated to Hold, before the Print@1 expression is evaluated.

So, to summarize:

  • When a new rule for a symbol is defined, the left and right side of the assignment are first evaluated as appropriate (in most cases this means not at all). The rule is then inserted according to its specificity.
  • When an expression is evaluated, the head is evaluated first, before any of the arguments. For h[a][b], this means h, then a, then h[a], then b, then h[a][b].