10

I am studying Mathematica myself and doing some exercises for improvement.

Question: Try to guess the internal forms of b/c and c/b. Verify your answer using FullForm.

Here is what I got by using FullForm:

FullForm[b/c] 
Times[b,Power[c,-1]] 
FullForm[c/b] 
Times[Power[b,-1],c]

As you can see from the full form of b/c and c/b, the order of two terms in function Times is different. I am wondering why does this happen? What is the purpose of this? For the full form of c/b, why not Times[c,Power[b,-1]]? Just curious, however this doesn't seem to be important.

emnha
  • 2,101
  • 13
  • 26

1 Answers1

9

Times has the Attribute Orderless:

Attributes[Times]
{Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected}

As the documentation states:

Orderless is an attribute that can be assigned to a symbol f to indicate that the elements ei in expressions of the form f[e1, e2, ...] should automatically be sorted into canonical order. This property is accounted for in pattern matching.

Observe it acting on an arbitrary user head:

Attributes[head] = {Orderless};
head[b, c]
head[c, b]
head[b, c]

head[b, c]

Among other things this helps to put expressions into a canonical form, allowing e.g. head[b, c] == head[c, b] to return True, as it should be for a commutative operator.

Recommended reading:

May also be of interest:

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Thanks. I still wonder why the form of b/c is sorted (canonical order) but c/b is not? – emnha Sep 29 '17 at 08:01
  • 1
    @anhnha It is sorted according to the canonical ordering function of Mathematica, e.g. Sort[{Power[b, -1], a, c}] outputs {a, 1/b, c}. Sadly that ordering remains poorly documented. – Mr.Wizard Sep 29 '17 at 08:07
  • 1
    Well, in this case, it's simple: What comes first in the alphabet? – halirutan Sep 29 '17 at 08:08
  • @halirutan Well I think a natural parallel would be Sort[{foo[b, -1], a, c}] which returns {a, c, foo[b, -1]} -- do you not think it at least plausible for that to cause confusion? – Mr.Wizard Sep 29 '17 at 08:10
  • Yes, and my comment was more to state the obvious. It's clear that we need some order in a term-rewriting system like Mathematica to reach a normal form and make things work. Unfortunately, while in languages like C, you learn the core principals first, in Mathematica you can happily work for years without ever knowing about normal forms, ordering, reduction and term-rewriting in general, although it is the very core principle of Mathematica. And as you pointed out, even when you want to know more, the core principles are often poorly documented. To this day (and to my knowledge), ... – halirutan Sep 29 '17 at 08:17
  • Well, does canonical order mean alphabet order? – emnha Sep 29 '17 at 08:18
  • there is no clear documentation about all details of the evaluation loop, no documentation, how patterns are sorted (and this is crucial in Mathematica) and no docs about why we need separate rule lists forDownValues, UpValues, OwnValues and how everything relates to Attributes etc. – halirutan Sep 29 '17 at 08:20
  • @halirutan Well comment that ought to to put off anyone on the fence about Mathematica. :-/ – Mr.Wizard Sep 29 '17 at 08:25
  • 3
    @anhnha Only for simple symbols. You can look up the documentation of sort and find in the details section: "Sort orders symbols by their names, and in the event of a tie, by their contexts." and "Sort usually orders expressions by putting shorter ones first, and then comparing parts in a depth-first manner. " and "Sort treats powers and products specially, ordering them to correspond to terms in a polynomial." As pointed out by Mr.Wizard, things get more involved as soon as you have complex expressions. – halirutan Sep 29 '17 at 08:28
  • @halirutan and already we reach a(n apparent) contradiction, as one would think c is shorter than Power[b, -1] – LLlAMnYP Sep 29 '17 at 09:02
  • @LLlAMnYP As stated, "powers take a special role". In this case, it means that the length of the expression is not taking into account. Things are sorted by alphabet and in case of a tie by the exponent. Otherwise, the sorting for this Sort[{Power[b, -1], Power[b, 1]}] would be reversed, as the -1 is longer. Unfortunately, even this isn't true as you can see in Sort[{power[b, -1], power[b, 1]}] :) Appending another parameter to the first power however does push it to the end. – halirutan Sep 29 '17 at 09:14
  • @halirutan in this case they're of equal length since -1 and 1 are both integer literals, but ofc -1 comes before 1 – LLlAMnYP Sep 29 '17 at 09:16
  • @LLlAMnYP Yes, you are correct. – halirutan Sep 29 '17 at 09:17
  • @LLlAMnYP Actually Power[b, 1] directly simplifies to b but even with Sort[Hold[Power[b, 1], Power[b, -1]]] one sees that the sorting is respected. – Mr.Wizard Sep 29 '17 at 09:17
  • I guess this would be an extremely nice assignment for a class: Implement sorting for expressions to get the same results as Mathematica does. – halirutan Sep 29 '17 at 09:19
  • 1
    @halirutan You and I have different definitions for nice. ;-p – Mr.Wizard Sep 29 '17 at 09:22