Wrappers and keywords
(You'll excuse me I hope if this is deemed inappropriate. I'm posting this here rather than in the general list since it's about the language and not it's application.) I am curious to know why the, what seems to me kludgy, "def x(): pass x = (static|class)method(x)" syntax was chosen over a simple "staticdef x ():..." or "classdef x ():..." def specialization syntax? Either method adds keywords to the language, but a direct declaration seems clearer and less error prone to me compared to the "call->assignment magically makes a wrapper" method. Is it hard to do the needed special wrapping directly? Regards, David LeBlanc Seattle, WA USA
David> I am curious to know why the, what seems to me kludgy, "..." David> syntax was chosen over a simple "staticdef" or "classdef" def David> specialization syntax? It was felt that it was more important in the short term to explore/add the functionality and settle details of syntax later. Skip
David LeBlanc wrote:
I am curious to know why the, what seems to me kludgy, "def x(): pass x = (static|class)method(x)" syntax was chosen over a simple "staticdef x ():..." or "classdef x ():..." def specialization syntax?
That syntax hasn't been chosen yet; syntactic sugar for static and class methods, properties, slots, and other object types is still an area of ongoing research. The current implementation was created since it did not need an extension to the syntax: x=staticmethod(x) was syntactically correct even in Python 1.2 (which is the oldest Python version I remember). There have been numerous proposals on what the syntactic sugar should look like, which is one reason why no specific solution has been implemented yet. Proposals get usually discredit if they require introduction of new keywords, like "staticdef". The current favorite proposals is to write def x() [static]: pass or perhaps def x() [staticmethod]: pass In that proposal, static(method) would *not* be a keyword, but would be an identifier (denoting the same thing that staticmethod currently denotes). This syntax nicely extends to def x() [threading.synchronized, xmlrpclib.webmethod]: pass The syntax has the disadvantage of not applying nicely to slots. Regards, Martin
<snip>
There have been numerous proposals on what the syntactic sugar should look like, which is one reason why no specific solution has been implemented yet. Proposals get usually discredit if they require introduction of new keywords, like "staticdef". The current favorite proposals is to write
def x() [static]: pass
or perhaps
def x() [staticmethod]: pass
In that proposal, static(method) would *not* be a keyword, but would be an identifier (denoting the same thing that staticmethod currently denotes). This syntax nicely extends to
def x() [threading.synchronized, xmlrpclib.webmethod]: pass
I'm not sure what you're suggesting here semantically...?
The syntax has the disadvantage of not applying nicely to slots.
Regards, Martin
It also has the disadvantage of adding a new syntactical construct to the language does it not (which seems like more pain than a couple of keywords)? I don't recall any other place in the language that uses [] as a way to specify a variable (oops, excepting list comprehensions sort of, and that's not quite the same thing IMO), especially in that position in a statement? It seems like it would open the door to uses (abuses?) like: class foo [abstract]: pass (although, this particular one might satisfy the group that wants interfaces in python) Is there any real difference between what amounts to a reserved constant identifier (with semantic meaning rather than value) compared to a keyword statement sentinal? Are there any other language-level uses like that (reserved constant identifier), or does this introduce something new as well? Speaking of slots, is their primary purpose to have classes whose instances are not morphable? If so, one might default to all classes being non-morphable by default and having something like: class foo [morphable]: pass as identifying those which are (an obviously python-3000 feature if implemented thusly). Regards, Dave LeBlanc Seattle, WA USA
David> It also has the disadvantage of adding a new syntactical David> construct to the language does it not (which seems like more pain David> than a couple of keywords)? I don't recall any other place in David> the language that uses [] as a way to specify a variable (oops, David> excepting list comprehensions sort of, and that's not quite the David> same thing IMO), especially in that position in a statement? Adding new syntactic sugar is less problem than adding keywords for two reasons: * old code may have used the new keyword as a variable (because it wasn't a keyword) * old code won't have used the new syntactic sugar (because it wasn't proper syntax) Combined, it means there is a higher probability that old code will continue to run with a new bit of syntax than with a new keyword. You can think of [mod1, mod2, ...] as precisely a list of modifiers to normal functions, so it is very much like existing list construction syntax in that regard. Also "[...]" often means "optional" in may grammar specifications or documentation, so there's an added hint as to the meaning. Skip
On Thu, 17 Apr 2003, Skip Montanaro wrote:
Adding new syntactic sugar is less problem than adding keywords for two reasons:
* old code may have used the new keyword as a variable (because it wasn't a keyword)
* old code won't have used the new syntactic sugar (because it wasn't proper syntax)
(If i recall correctly, minting new keywords is particularly onerous in python because of its simple parser. Specifically, you can't use keywords for variable names anywhere, even outside the syntactic construct which involves the keyword. Hence the need to use 'klass' instead of 'class' for parameter names, no variables named 'from', etc. 'import's recent aliasing refinement - import x as y was implemented without making "as" a keyword specifically to avoid this drawback. "as" gets its role there purely by virtue of the import syntax, not as a new keyword - and so you can use "as" as a variable name, etc. The scheme for qualifying function definitions with [...] would have the same virtue - not requiring the qualifiers to be new keywords...) -- Ken klm@zope.com
David LeBlanc wrote:
In that proposal, static(method) would *not* be a keyword, but would be an identifier (denoting the same thing that staticmethod currently denotes). This syntax nicely extends to
def x() [threading.synchronized, xmlrpclib.webmethod]: pass
I'm not sure what you're suggesting here semantically...?
That is part of the point: You could add arbitrary annotations to function definitions, to indicate that they are static methods, to indicate that multiple calls to them should be synchronized, or to indicate that the method should be available via SOAP (the simple object access protocol). The language would not associate any inherent semantics. Instead, the identifiers in the square brackets would be callable (or have some other interface) that modifies the function-under-construction, to integrate additional aspects.
It also has the disadvantage of adding a new syntactical construct to the language does it not (which seems like more pain than a couple of keywords)?
No. The disadvantage of adding keywords is that it breaks backwards compatibility: Somebody might be using that identifier already. When it becomes a keyword, existing code that works now would stop working. With the extension of sqare brackets after the parameter list, nothing breaks, as you can't currently put brackets in that place.
I don't recall any other place in the language that uses [] as a way to specify a variable (oops, excepting list comprehensions sort of, and that's not quite the same thing IMO), especially in that position in a statement? It seems like it would open the door to uses (abuses?) like: class foo [abstract]: pass
The syntax is inspired by DCOM IDL, and by C#, both allowing to annotate declarations with square brackets.
Is there any real difference between what amounts to a reserved constant identifier (with semantic meaning rather than value) compared to a keyword statement sentinal?
What is a keyword statement sentinal, and what alternatives are you comparing here?
Are there any other language-level uses like that (reserved constant identifier), or does this introduce something new as well?
If you are referring the the def foo()[static] proposal: "static" would not be reserved nor constant. Instead, writing def foo()[bar1, bar2]: body would be a short-hand for writing def foo(): body foo = bar1(foo) foo = bar2(foo) bar1 and bar2 could be arbitrary expressions - nothing reserved at all.
Speaking of slots, is their primary purpose to have classes whose instances are not morphable?
No. Regards, Martin
participants (4)
-
"Martin v. Löwis"
-
David LeBlanc
-
Ken Manheimer
-
Skip Montanaro