[Python-Dev] Extended Function syntax (original) (raw)

Gerald S. Williams gsw@agere.com
Wed, 29 Jan 2003 15:10:51 -0500


Guido van Rossum wrote:

The problem is that this is a very radical change to the grammar, and I'm not sure I can rigorously define how the switch from "expression parsing mode" to "block parsing mode" should work.

I've started to compose this e-mail three times, and I keep running into counter-examples. I'll try to keep this consistent...

I can see your point. What happens as soon as you try to do something like this?

class Foo(object): myprop1, myprop2 = property: ... , property: ...

Although at least in this case, the following trick could suffice:

class Foo(object): myprop1, myprop2 = ( property: ... ), # block end: indent == property: line property: ... # block end: indent < property: line myprop3 = property: ... # block end: indent == property: line ...

That example may be contrived (and it's solved anyway), but perhaps it demonstrates one of the dimensions in which this impacts the grammar. There must be similar situations to consider.

And once you open the door for code blocks of this type, I think improving on lambda is a natural next step (or perhaps the first step :-) ). The solution reached here is likely to have further-reaching consequences.

So perhaps I should drag out an implementation that uses a lambda replacement:

class Parrot(object): count = property(*mu(""": "Treat mostly-parrots as full parrots." def Get(self): return self._count def Set(self,count): self._count = int(round(count)) def Del(self): self._count = 0 return Get,Set,Del,"Current parrot count" """)())

def mu(*code): """For when lambda doesn't hack it""" splitcode = "".join(map(str,code)).split(":") args = splitcode[0] code = ":".join(splitcode[1:]) return mucode(args,code)

def mucode(args, code): exec "def mucode(" + args + "):" + code + "\n" return mucode

That could be easily morphed into something like this (under the hood, propertymethods() could have it's way with class or perform whatever other evil incarnations are needed):

class Parrot(object): count = propertymethods(""" "Current parrot count" def get(self): return self._count def set(self,count): self._count = int(round(count)) def del(self): self._count = 0""")

But you still have the issue of marking where the block ends and of allowing other things to follow it on the same "line". Is the parentheses trick I initially showed sufficient in all cases?

If it is, one solution that wouldn't be too far removed from the current version is to add a standard construct that encapsulates a block of code (if need be, it could return it as text). Then property() could do something special if it saw such a block:

class Parrot(object): count = property(codeblock: "Current parrot count" def get(self): return self._count def set(self,count): self._count = int(round(count)) def del(self): self._count = 0 )

Of course, if you make property a keyword, you could go a step further:

class Parrot(object): count = property codeblock: "Current parrot count" def get(self): return self._count def set(self,count): self._count = int(round(count)) def del(self): self._count = 0

In the end, this doesn't look that different, does it? But I think separating the notion of "codeblock" from the notion of "property" is a good idea regardless.

-Jerry