It also has a great toolset for making interactive plots. Assuming you understand the following jargon, it uses the functional reactive paradigm.
All possible variable names in Mathematica are pre-declared, unlike in general-purpose programming languages.* For instance, the variable "x" is predeclared, and when its value is printed out, it prints out "x". Sympy and Sage absolutely use the wrong approach here. You can work around the problem in Sympy using
from sympy.abc import *
but this is honestly rather shit.The editor is nice, in that it suggests documentation, and offers to auto-complete your code. It's similar to an IDE in that respect. This compares favourably against Maxima, where some people suggest to use it via Emacs, and then you don't get access to auto-completion or context-relevant documentation.
You can also copy-paste any object in the notebook. I don't know if this is directly useful, but the copy-paste includes any plot, image, formula, output, etc. The experience is similar to MS Office, where you can similarly copy-paste any image, table, text, or combination of these. With something like Sympy, you would need to use some function to serialise an object (like a formula) to code.
Finally, comparison to Sagemath: Everything in Sagemath seems half done. It ticks a lot of feature boxes, but the features seem incompletely implemented, even when compared to Sympy. By contrast, when Mathematica does something, it seems to be done in a more complete and usable way. The whole system seems consistent, somehow.
* - This is one of the ways that a CAS should not behave like a general-purpose language.
- If you do matrix algebra in it, it rigidly insists on knowing which ring your matrix-elements belong to. If you have a symbolic variable, then you need to indicate this as part of the ring. Some functionality is not available for certain rings, which sometimes feels overly pedantic; surely a best-case effort could somehow be made? I haven't tried this for a while, but I remember this was an obstacle that I hadn't encountered in Mathematica (or Sympy), which seemed to just do the right thing. Note that normally when working with real- and complex-algebras, I usually resort to various matrix representations.
- The pretty-printer wasn't good. Maybe my mistake was insisting it print to Unicode, but it failed to pretty-print the elements of a matrix. It defaulted to printing out Python code within a matrix. Maybe this is a bug? Maybe I should've just outputted to Latex?
- The variables weren't pre-declared, so I kept having to write out `var("x")`, etc. This is not ergonomic for a CAS. Sagemath doesn't even ship with a hack like `from sympy.abc import *`.