On Jul 26, 2019, at 05:25, Ricky Teachey <ricky@teachey.org> wrote:
This is a neat idea and I have wanted something similar myself in situations I do not want to instantiate class object or break code out to another module.
Controversial opinion: it may even justify a keyword. But it wouldn't have to be a new one, def could work just fine:
def ns: a = 3
It’s not clear to me whether people want a module-like, class-like, or function-like namespace here, but I do think it’s probably exactly one of those three. And it’ll be a lot easier to define and implement—and for everyone to understand future Python code—if it is. I don’t think anyone cares about fast locals here, and I hope nobody cares about things like super magic. But the differences in how variables in the namespace interact with functions and classes (and new-kind-of-namespace-things) defined within the namespace do probably matter. And you’d probably want to know what to expect from eval/exec, locals/globals/vars, etc., because someone is going to do that and you want it to be obvious what it means, rather than having to dig through the spec or trial-and-error at the interactive prompt to figure it out. And people probably occasionally want to know how to do the same thing programmatically (just like people occasionally want to know how to call a metaclass explicitly). But the nesting is the key question. Meanwhile, do we even need to name the namespace? While it does allow the JS-style trick you gave for defining a “prototype” object without a class, do we actually want that in Python? And are there any other practical uses for names here? If not, there’s a really easy design and implementation, something like one of the following: A bare “def:” statement defines a function, doesn’t bind it to anything, calls it with no args, and discards both the function and the result. So locals, nonlocal, eval, etc. work exactly the same way as in any other def body. A bare “class:” statement defines a class namespace, doesn’t call the metaclass, and doesn’t bind anything to anything. Again, everything works exactly the same way as in any other class body. A bare “import:” statement defines a module namespace, doesn’t construct a module out of it, and doesn’t bind anything to anything.
Final observation: I think one shortfall in python is that it nudges the user to use OOP a little bit too forcefully
I think it’s a strength of Python that it uses OOP under the hood for all kinds of stuff, but usually doesn’t make you think in OOP terms while writing and reading the code. And I think your version of the proposal takes it farther in that direction, which is good. For example, nobody thinks of def as being syntactic sugar for constructing an object of type function that has a descriptor that returns an object of type method, and then binding it to a name. It just defines a method on a class, and it works. But, because that’s what it does under the covers, on the rare occasions where you need to go under the covers, you use the same OO style as with everything else. Compare that to the way reflection on methods works in, say, ObjC, where you end up calling a bunch of C functions, and passing them not actual classes and methods but pointers to opaque Class and Selector objects, and it feels more like you’re writing an ObjC interpreter than writing ObjC code.