4 ms·
> The approach of generating source code and exec()ing it, is a cool demonstration of Python's expressive power This sentence is very surprising to me. If the
by jorams 9y ago
> The approach of generating source code and exec()ing it, is a cool demonstration of Python's expressive power
This sentence is very surprising to me. If the best way to implement something is to literally build a string of source code and pass it to the interpreter, to me it means the user is unable to really express what they want in the language.
As a (terrible) example, imagine a language whose number addition operator only works on literals.
1 + 2
=> 3
a = 1
b = 2
a + b
=> ERROR!
It does, however, have a string concatenation operator that also works on variables and a way to read user-provided numbers into a variable, as well as some kind of eval function. What would you do to add two user-provided numbers? Something like the following:
foo = read number!
bar = read number!
baz = concatenate x, ' + ', y
quux = eval baz
The same thing could be stated about this language...
> The approach of generating source code and eval-ing it, is a cool demonstration of <this language>'s expressive power.
...but it clearly wouldn't make sense. Functions like exec and eval are an escape hatch for when there is no sensible way of expressing something in the language.
- rajathagasthya 9y agoNo one is claiming exec-ing generated source code is the best way to implement something (namedtuple in this case). The correct way is to use metaclass, but as I noted in another comment exec-ing source code provides a significant speed up to using metaclasses. I imagine that was the rationale behind this particular namedtuple implementation.
- comex 9y agoI’d say that the existence of an escape hatch for things that can’t be expressed natively is itself a form of expressitivity. It’s one that’s near ubiquitous among dynamically typed languages, so it doesn’t say much that Python has it, but it still provides a favorable comparison to some static languages. That said, this particular use case for eval is basically macros lite: the code being evaluated doesn’t generally depend on input to the resulting program, so it could have been expressed as a transformation to the module source code, i.e. a macro. And a true macro would be able to provide more natural syntax, whereas namedtuple requires stuffing the field names into a string (or using a wrapper based on some metaclass thing, but the syntax for that isn’t great either). Thus, languages that have macro support, both dynamically typed (Lisp) and statically (e.g. Rust), could be called more expressive in this respect.