Forward-References & Out-of-order declaration

While reading material for implementing some kind of import hooks and so forth for the xfork package, I came across this one: http://stackoverflow.com/questions/16907186/python-model-inheritance-and-ord... Reactivated in my mind, after reading Prof. Humbert's request of adding a "more forwarded" referencing of classes, I just wanted to ask: 1) What is the general opinion regarding having a more declarative style when writing modules? 2) That given, what is the general opinion about introducing the out-of-order declaration asked for in the StackOverflow posts? Best, Sven

On Tue, Aug 25, 2015 at 11:03 AM, Sven R. Kunze <srkunze@mail.de> wrote:
It would be a nice idea for a different language. Python's execution model would have to be changed dramatically in order to support this (outside the very narrow case of annotations or the cases where it already works). This just isn't going to happen -- too much code relies on the existing execution model.
2) That given, what is the general opinion about introducing the out-of-order declaration asked for in the StackOverflow posts?
I couldn't extract an actual proposal from the stackoverflow link you gave. -- --Guido van Rossum (python.org/~guido)

On 25.08.2015 22:48, Guido van Rossum wrote:
I can totally understand that and I am not a friend of hard cut/dramatic changes and so forth myself. It's just that I was pondering multiple times over this and I am usual sort of: "there must be a way and it must work smoothly". What I asked about is basically a reduction of functionality. Thus, the result of that reduction is a subset of Python and so still valid Python. So, I can think of two ways in order to test it out: - another keyword instead of 'import' (e.g. 'use') that does not actually execute the module but construct its dict from its AST or - mark the modules alike the pyxl magic encoding you referred to lately and thus enforce this sort of declaration model Don't get me wrong. Most of the time, I love Python's spontaneous nature of getting things done on the module level; and I never want that to go away. However, once your code base matures, you need to shape your code the right way and massage it in some separate packages and modules. Most of these libs are just of a declarative style (e.g. 5 classes and 3 functions, period); nothing more is necessary here. Also the issue of failing cyclic imports can be solved by some sort of "restricted/declarative importing". Not a huge issue by itself and most of the time, one can fix it by scratching one's head enough; it's time-consuming nevertheless.
Not sure if that makes sense anymore, but I think it's worth at least to get the idea across: The issue (not a huge problem again but annoying from time to time) is that the order of declaration in a module actually matters. IIRC other modern languages like C# don't require you do actually care about this anymore. Possible example (for whatever reason an author wants to do that -- also cf. stackoverflow): class UseThis(Base): pass class UseThat(Base): pass class Base: pass In that regard, Python feels a bit rusty. Best, Sven

On Wed, Aug 26, 2015 at 8:11 AM, Sven R. Kunze <srkunze@mail.de> wrote:
Frankly, I don't have a problem with this. You get a mandate that requires you to do what's good practice anyway: lay things out in a logical order. In the same way that Python's use of indentation for block structure is generally just enforcing what you'd have done regardless of language, this requires that you sort things in dependency order. That tends to mean that the first use of any name in a module is its definition/source. Want to know what 'frobnosticate' means? Go to the top of the file, search for it. Having that enforced by the language is a restriction, but how often does good code have to be seriously warped to fit into that model? Not often, in my experience. ChrisA

On Aug 25, 2015, at 11:03, Sven R. Kunze <srkunze@mail.de> wrote:
The fact that the global namespace is imperative rather than declarative means that you can use functions and classes in defining later functions, classes, and constants. This is essential for features like decorators, metaclasses, dynamically-generated types liked namedtuples, etc. Sure, you could probably come up with ways to replace all of those features with similar features that didn't require the existing implementation (make everything lazy, use a two-level store, or just come up with special-purpose workarounds for each feature), or require users to do things differently (e.g., you can only use decorators imported from a separate scope), but that would be a pretty different language.

On Tue, Aug 25, 2015 at 11:03 AM, Sven R. Kunze <srkunze@mail.de> wrote:
It would be a nice idea for a different language. Python's execution model would have to be changed dramatically in order to support this (outside the very narrow case of annotations or the cases where it already works). This just isn't going to happen -- too much code relies on the existing execution model.
2) That given, what is the general opinion about introducing the out-of-order declaration asked for in the StackOverflow posts?
I couldn't extract an actual proposal from the stackoverflow link you gave. -- --Guido van Rossum (python.org/~guido)

On 25.08.2015 22:48, Guido van Rossum wrote:
I can totally understand that and I am not a friend of hard cut/dramatic changes and so forth myself. It's just that I was pondering multiple times over this and I am usual sort of: "there must be a way and it must work smoothly". What I asked about is basically a reduction of functionality. Thus, the result of that reduction is a subset of Python and so still valid Python. So, I can think of two ways in order to test it out: - another keyword instead of 'import' (e.g. 'use') that does not actually execute the module but construct its dict from its AST or - mark the modules alike the pyxl magic encoding you referred to lately and thus enforce this sort of declaration model Don't get me wrong. Most of the time, I love Python's spontaneous nature of getting things done on the module level; and I never want that to go away. However, once your code base matures, you need to shape your code the right way and massage it in some separate packages and modules. Most of these libs are just of a declarative style (e.g. 5 classes and 3 functions, period); nothing more is necessary here. Also the issue of failing cyclic imports can be solved by some sort of "restricted/declarative importing". Not a huge issue by itself and most of the time, one can fix it by scratching one's head enough; it's time-consuming nevertheless.
Not sure if that makes sense anymore, but I think it's worth at least to get the idea across: The issue (not a huge problem again but annoying from time to time) is that the order of declaration in a module actually matters. IIRC other modern languages like C# don't require you do actually care about this anymore. Possible example (for whatever reason an author wants to do that -- also cf. stackoverflow): class UseThis(Base): pass class UseThat(Base): pass class Base: pass In that regard, Python feels a bit rusty. Best, Sven

On Wed, Aug 26, 2015 at 8:11 AM, Sven R. Kunze <srkunze@mail.de> wrote:
Frankly, I don't have a problem with this. You get a mandate that requires you to do what's good practice anyway: lay things out in a logical order. In the same way that Python's use of indentation for block structure is generally just enforcing what you'd have done regardless of language, this requires that you sort things in dependency order. That tends to mean that the first use of any name in a module is its definition/source. Want to know what 'frobnosticate' means? Go to the top of the file, search for it. Having that enforced by the language is a restriction, but how often does good code have to be seriously warped to fit into that model? Not often, in my experience. ChrisA

On Aug 25, 2015, at 11:03, Sven R. Kunze <srkunze@mail.de> wrote:
The fact that the global namespace is imperative rather than declarative means that you can use functions and classes in defining later functions, classes, and constants. This is essential for features like decorators, metaclasses, dynamically-generated types liked namedtuples, etc. Sure, you could probably come up with ways to replace all of those features with similar features that didn't require the existing implementation (make everything lazy, use a two-level store, or just come up with special-purpose workarounds for each feature), or require users to do things differently (e.g., you can only use decorators imported from a separate scope), but that would be a pretty different language.
participants (4)
-
Andrew Barnert
-
Chris Angelico
-
Guido van Rossum
-
Sven R. Kunze