5 ms·
Why would you add macros to the most succinct widely used programming language that is loved for its readability? Macros are generally useful because they A) m
by WoodenChair 6y ago
Why would you add macros to the most succinct widely used programming language that is loved for its readability?
Macros are generally useful because they A) make something more succinct, B) improve performance by doing something at compile time instead of runtime, or C) enable metaprogramming. The downside is that they risk the creation of unreadable or overly magic code.
Python already is succinct and already has metaprogramming (although not to the extent of Lisp, as pointed out by the rationale). And we all know Python is slow, but the downsides of making it less readable through macros outweigh the upsides IMHO. Python is loved for being readable. Instead let's improve on its general performance.
- hanselot 6y agoI completely agree here. Besides, why waste precious resources that could be devoted to the language police and enforcing sweeping changes to random words only programmers will ever read? Didn't you take the CoC?
- peterkelly 6y agoIf macros are used responsibly, they can make a program more readable. I have to write lots of boilerplate code for certain things that in other languages would be much simpler; for example when I'm doing pattern matching in Python I have to use a sequence of if statements and complex expressions. I'd love a pattern matching macro because that would let me express my logic in a manner which more closely matches the semantics. Macros can be abused just like decorators, classes, or functions to make complex code that's difficult to understand or modify. While macros give you a bit more rope, used properly they can be very handy.
- throw_m239339 6y ago> If macros are used responsibly, they can make a program more readable. (AST based) Macros can really be an asset in a statically typed language (like Rust or Crystal), they are crap in C since it's text substitution [1], but an interpreted language that already has a lot of meta programming capabilities doesn't really need macros. Python has problems, but you don't fix those with Macros on top of them. They will never be used responsibly. 1: With a better macro system C could have been a much better and secure language IMHO.
- rbanffy 6y agoMetaprogramming has a runtime cost that macros (even crappy C-like ones) don't. In the case of an interpreted language, this is an important feature. Having said that, I haven't seen metaprogramming being overused or abused much in Python.
- 10000truths 6y agoYou shouldn't be using Python in the first place if you're worried about the runtime cost of metaprogramming.
- rbanffy 6y agoIf macros offer the same benefit at no additional cost, why not?
- formerly_proven 6y agoMacros have decidedly nonzero cost. Look at the discussion from the core devs surrounding this; just the implementation is a major change for the parsing and AST modules with unclear performance implications. Introducing this much complexity to the language is far from "no cost" as well. I predict that if this PEP goes through, it will be a watershed moment for Python and the language will become an unrecognizable mess (more so than already) within a few years. If GvR was still in charge, I would be sure that this would be dismissed. Now, I am not so sure, and that troubles me.
- rst 6y agoA nicer and more complete syntax for anonymous functions, or some reasonable equivalent (like JS arrow defns, or Ruby code blocks) might serve most of the same needs as a full-blown macro facility, without some of the complications. It's pretty common in Ruby for libraries to define DSLs with syntax similar to what macros were used for in, say, '80s LISP code. (The nearest current Python equivalent is lambdas, but there are very awkward limits on the varieties of control structure they can contain.)
- sevensor 6y agoAgreed. I've been studying Racket lately. Historically I've mainly worked in C and Python, although I've scratched the surface with lisps before. One of the things that strikes me about Racket is that every new special form I learn has its own evaluation rules. They may be very similar, they may follow certain patterns, but they don't attain total consistency. (Especially confusing to me has been the existence of expressions with arity other than one, which are OK in some forms but not in others.) Most of the special forms are macros underneath; you can go and read them, although they're still parenthesis soup to me at the moment. Still, there's a path through the fog -- you know that underneath it all, there is a small number of primitive forms, and all this syntactic abstraction is ultimately built on top of them. Contrast this with Python. Python has a lot of syntax. You can't reason your way through Python by reference to a small number of primitive forms. Instead, just about every expression evaluates to an object, and if you know what kind of object it produces, you can go look up what that object does. What I really enjoy about learning Racket is seeing how syntactic abstraction lets the language get away with not creating new data structures when it doesn't have to. However, a marriage of the two approaches seems like too much. To understand what a macro does, now you're going to have to map the macro's special syntax back to Python's ordinary syntax, and then you're going to have to figure out how to use whatever kind of objects that syntax produces. This imposes a whole new layer of reasoning on the reader. I'm not a fan of this PEP and I'd avoid using it in my code if it were adopted. I already have enough trouble explaining generator comprehensions to my colleagues; a half dozen new quasi-Python languages that compose with each other in surprising ways would be more than enough to make them retreat back to C#.