cdp49@cam.ac.uk writes:
I think that's exactly the problem with a lack of Python macros. The full quote, of course, goes: "There should be one-- and preferably only one --*obvious* way to do it."
You understand that the Zen is humorous? Most of the Zen, if taken universally and seriously, advocates the impossible. And as a whole, it's definitely impossible even in the limited scope it's intended to apply to -- it's internally inconsistent.
Often, there's a mathematical notation for something, and *this* is the only obvious way to write anything out.
But that's not the way Python looks at it, you see. First, "a" mathematical notation doesn't exclude multiple notations, and for most mathematical concepts there are indeed multiple common notations (eg, for multiplication, juxtaposition of the factors, *, ・, and × are all in common use depending on the kind of multiplication). I'm pretty sure Tim Peters was well aware of such. Frequently the most commonly used expressions are really ugly (at least in my experience in mathematical applications to game theory ;-). Now, you can recover your position from that issue by appealing to other more or less Zen desiderata (readability counts, for example), but they're not quite as strong arguments here. The second objection is more serious: the Zen is intended to be restricted to Python. "There should be one-- and preferably only one --obvious way to do it [*in Python*]." Guido (and the other OG core devs) wanted consistent and obvious ways to do it *in Python*. The consistent and obvious way to write "X ~ N(0,1)" (oops, not so obvious after all!) in Python is "X = Normal(0,1)", where presumably the Normal class provides facilities such as CDF and PDF as well as the PRNG of random.normalvariate.
Not to mention, DSLs are forced to adopt all kinds of weird syntax
This is more or less intentional, though, as is the restriction to a predefined set of operator symbols (you can't define ・ as an operator symbol when you need two kinds of multiplication for example). Python has consistently refused to be turned into a platform for DSLs for almost 3 decades. Ruby and Lisps are better for that. You don't have to like that (quite a few people don't, of course that's why MacroPy was written), but it's really not un-Pythonic. There is method to this madness: Python aims for readability and flexibility for the community of Python programmers who might encounter the code, rather than catering to authors and their domain specialist community. The fact that Python adoption is still growing should tell you something about the preferences and needs of the general Python community.
I don't want to be forced to learn lots of weird little functions like `np.matmul(x1, x2)` when there's already one obvious syntax I'm very familiar with: `x1 * x2`.
I don't recall ever writing matrix multiplication that way in mathematics though. That's universally written as juxtaposition in my experience. And the obvious way to write it in Python (and np) has been "x1 @ x2" for some years now. In np, "*" means element-wise multiplication, I believe. Perhaps some BDFL will arise to merge the benefits of Python with those of Julia, but for the near term we're all going to have to choose one or the other. Steve