"Ruminating" is the best word I can think of here - I've been slowly digesting the ideas and discussions over the last couple months. Part of the reason why all this is relevant to me is that I'm working on a couple of side projects, some of which involve "mini-languages" that have similar issues to what has been discussed on the list.
Bear in mind that none of what I say here is a recommendation of where Python *should* go - rather, it's a description of where I have *already* gone in some of the work that I am doing. It is merely one possible answer out of many to the suggestions that have been put forward in this forum. (And if this is merely a rehash of something that was discussed long ago, I apologize.) I'll start with the 'switch' discussion (you'll note that the ideas here cut across a bunch of different threads.) The controversy, for which there seemed to be no final resolution, had to do with when the case values should be evaluated (I won't repeat the descriptions of the various schools - look in the PEP.) As some people pointed out, the truly fundamental issue has to do with the nature of constants in Python, which is to say that currently, there are none - other than literals. What would be entailed in adding a const type? Without fundamentally changing the language, the best you can do is early binding, in other words the const value isn't known at compilation time, but is a variable that is frozen at some point - perhaps at module load time. Adding a true const - that is, a variable whose value is known to the compiler, and can be optimized as such - is somewhat more involved. For one thing, the compiler knows nothing about external modules, or anything outside the current compilation unit. Without the ability to import external definitions, a compile-time 'const' is quite useless. One way around this (which is a little kludgey) would be to add a second type of 'import' - a compile-time import, which could be called something like 'include' or 'using'. An import of this type would act as if it had been textually included in the current source file. It would become part of the current compilation unit, and it would have the same restrictions - such as the inability to access variables imported via 'import' at compile time. Include files can of course include other files - but they can also 'import' as well. The effect of the importing from an include is the same as importing from the primary source file (because of the rule which states that 'include' is equivalent to textual inclusion.) Conversely, imported files can include - however the effect of the inclusion is limited to the imported file only, and does not affect the primary source file (because it's a different compilation unit.) This implies that you can't access constants that are within an imported module (because the constant definitions exist only within the compiler - they are transformed into literals before code generation occurs.) If a source file and an included module need to share constant values, they must each include the definitions of those constants. This can lead to problems if the include files are changing - one file might be compiled with a different version of the include file than another. OTOH, many potential uses for constants would be for things like operating system error codes and flags, which are fairly stable and unchanging -- so even a restricted use of the facility (i.e. don't use it for values which are in flux) might be worth while. Another possibility is to embed include checksums or other version info within the compiled file. So far, it seems like a lot of added complexity for fairly little benefit. However, where it gets interesting is when you realize that once you've given the compiler knowledge of the world outside a single compilation unit, a number of interesting possibilities arise. The one I've been experimenting with in my mini-language is macros. Not macros in the C sense, but in the lisp sense - a function which takes unevaluated arguments. Actually, they more closely resemble Dylan macros, in that they add production rules to the parser. Internally a macro is a small snippet of an AST, which gets spliced into the AST of the calling function at compile time. Macro arguments can be identifiers, expressions, and statements, all of which get substituted into the appropriate point in the AST. This is of course going way past Guido's "Programmable Syntax" prohibition. Good thing I am only talking hypothetically! It seems to me, however, (getting back to 'switch') that supporting a proper 'switch' statement has to address these issues in *some* fashion - the issue of constants isn't going to go away completely under any of the proposed approaches. In fact, I'm actually leaning towards the position of *not* adding a switch statement to Python, simply because I'm not sure that Python *should* deal with all of these issues. It seems to me that adding 'const' to the language opens up a Pandora's box, containing both chaos and hope - and I think that for some language X, it may be a good idea to open that box, but I don't know if X includes Python. -- Talin _______________________________________________ Python-3000 mailing list [email protected] http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com
