From birchb at tpg.com.au Mon May 1 12:36:10 2006 From: birchb at tpg.com.au (Bill Birch) Date: Mon, 1 May 2006 20:36:10 +1000 Subject: [melbourne-pug] Help wanted for Python 3000 PEP Message-ID: <200605012036.10902.birchb@tpg.com.au> Hi, Would you be interested in reviewing/contributing to a Python Enhancement Proposal for Python-3000? I am half-way through writing this PEP on Type Expressions. There has been significant chat on the py3k mailing list (http://mail.python.org/pipermail/python-3000/) about optional static type checking so a type system is needed to support this. Any takers? I'll buy the coffees! Bill -- http://billbirch.wordpress.com/ From jimmy.briggs at gmail.com Mon May 1 12:57:14 2006 From: jimmy.briggs at gmail.com (James Briggs) Date: Mon, 1 May 2006 20:57:14 +1000 Subject: [melbourne-pug] Help wanted for Python 3000 PEP In-Reply-To: <200605012036.10902.birchb@tpg.com.au> References: <200605012036.10902.birchb@tpg.com.au> Message-ID: <23b1b67f0605010357o2de4f584w570d8718ac0fb2e@mail.gmail.com> My work commitments are falling away, which may well free up some time. Not sure how much info-sci theory on type stuff remains but I am willing to help. James On 5/1/06, Bill Birch wrote: > > Hi, > > Would you be interested in reviewing/contributing to a Python Enhancement > Proposal for Python-3000? I am half-way through writing this PEP on Type > Expressions. There has been significant chat on the py3k mailing list > (http://mail.python.org/pipermail/python-3000/) about optional static type > checking so a type system is needed to support this. > > Any takers? > > I'll buy the coffees! > > Bill > -- > http://billbirch.wordpress.com/ > _______________________________________________ > melbourne-pug mailing list > melbourne-pug at python.org > http://mail.python.org/mailman/listinfo/melbourne-pug > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/melbourne-pug/attachments/20060501/95236db7/attachment.html From mauriceling at acm.org Mon May 1 21:46:09 2006 From: mauriceling at acm.org (Maurice Ling) Date: Tue, 02 May 2006 03:46:09 +0800 Subject: [melbourne-pug] Help wanted for Python 3000 PEP In-Reply-To: <200605012036.10902.birchb@tpg.com.au> References: <200605012036.10902.birchb@tpg.com.au> Message-ID: <44566581.1010209@acm.org> Hi, I'll be pleased to comment. Incidentially I will arrive back Melbourne later. Please send me what you have so far. Thanks Maurice Bill Birch wrote: >Hi, > >Would you be interested in reviewing/contributing to a Python Enhancement >Proposal for Python-3000? I am half-way through writing this PEP on Type >Expressions. There has been significant chat on the py3k mailing list >(http://mail.python.org/pipermail/python-3000/) about optional static type >checking so a type system is needed to support this. > >Any takers? > >I'll buy the coffees! > >Bill > > From tennessee at tennessee.id.au Tue May 2 02:12:31 2006 From: tennessee at tennessee.id.au (Tennessee Leeuwenburg) Date: Tue, 02 May 2006 10:12:31 +1000 Subject: [melbourne-pug] Help wanted for Python 3000 PEP In-Reply-To: <200605012036.10902.birchb@tpg.com.au> References: <200605012036.10902.birchb@tpg.com.au> Message-ID: <4456A3EF.3050808@tennessee.id.au> Bill Birch wrote: > Hi, > > Would you be interested in reviewing/contributing to a Python Enhancement > Proposal for Python-3000? I am half-way through writing this PEP on Type > Expressions. There has been significant chat on the py3k mailing list > (http://mail.python.org/pipermail/python-3000/) about optional static type > checking so a type system is needed to support this. > > Any takers? > > I'll buy the coffees! > > Bill > Sure, count me in for a discussion session or review or whatever would be helpful. It's not my central area, but I'm happy to provide what help I can. Let's see what you're talking about, and I'll let you know if there's anything useful I can do. Cheers, -T From tennessee at tennessee.id.au Fri May 5 01:49:19 2006 From: tennessee at tennessee.id.au (Tennessee Leeuwenburg) Date: Fri, 05 May 2006 09:49:19 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <4456A3EF.3050808@tennessee.id.au> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> Message-ID: <445A92FF.8090803@tennessee.id.au> Hi all, I've been starting to adopt a new coding idiom, and I thought I'd ask for comments. I've been extending some code, which has involved overriding many __doFoo() methods and accessing __myVariable variables. As I understand it, this is stylistically bad, and __XXX is a way of flagging that the thing is private-only. Keep Out Unless Absolutely Necessary. I can see a middle ground between the public interface and very private methods. Such a thing might be an element of processing which is typically called privately, but wouldn't be unsafe to call or override in appropriate circumstances. For this reason I've been using .XXX for the public interface, ._doFoo() for internal methods which are relatively safe, and .__doFoo() for things intended to be very private. Cheers, -T From mauriceling at acm.org Fri May 5 02:31:17 2006 From: mauriceling at acm.org (Maurice Ling) Date: Fri, 05 May 2006 10:31:17 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <445A92FF.8090803@tennessee.id.au> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> <445A92FF.8090803@tennessee.id.au> Message-ID: <445A9CD5.7040004@acm.org> Hi, Programmatically, Python does not have any means to "hide" methods, all methods are public (in java's terms). There may be some good reasons for doing so, at least it simplifies things. However, in a large module (especially modules that we did not write ourselves), changing a method can be scary because it may break other parts. Personally, I think that using .XXX for public, ._XXX for internal and .__XXX for private methods is more of a code documentation thing, which is probably good if followed religiously. At least it does put up a danger flag for yourself in future and prevent shooting yourself in the foot. I am just wondering how can this is better tied in with Bill Birch's type proposal...... maurice Tennessee Leeuwenburg wrote: >Hi all, > >I've been starting to adopt a new coding idiom, and I thought I'd ask >for comments. > >I've been extending some code, which has involved overriding many >__doFoo() methods and accessing __myVariable variables. As I understand >it, this is stylistically bad, and __XXX is a way of flagging that the >thing is private-only. Keep Out Unless Absolutely Necessary. > >I can see a middle ground between the public interface and very private >methods. Such a thing might be an element of processing which is >typically called privately, but wouldn't be unsafe to call or override >in appropriate circumstances. > >For this reason I've been using .XXX for the public interface, ._doFoo() >for internal methods which are relatively safe, and .__doFoo() for >things intended to be very private. > >Cheers, >-T >_______________________________________________ >melbourne-pug mailing list >melbourne-pug at python.org >http://mail.python.org/mailman/listinfo/melbourne-pug > > > From daedalus at eigenmagic.com Fri May 5 02:24:47 2006 From: daedalus at eigenmagic.com (Justin Warren) Date: Fri, 05 May 2006 10:24:47 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <445A92FF.8090803@tennessee.id.au> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> <445A92FF.8090803@tennessee.id.au> Message-ID: <1146788687.7067.6.camel@localhost.localdomain> On Fri, 2006-05-05 at 09:49 +1000, Tennessee Leeuwenburg wrote: > Hi all, > > I've been starting to adopt a new coding idiom, and I thought I'd ask > for comments. > > I've been extending some code, which has involved overriding many > __doFoo() methods and accessing __myVariable variables. As I understand > it, this is stylistically bad, and __XXX is a way of flagging that the > thing is private-only. Keep Out Unless Absolutely Necessary. > > I can see a middle ground between the public interface and very private > methods. Such a thing might be an element of processing which is > typically called privately, but wouldn't be unsafe to call or override > in appropriate circumstances. > > For this reason I've been using .XXX for the public interface, ._doFoo() > for internal methods which are relatively safe, and .__doFoo() for > things intended to be very private. I concur. That's pretty much what I use as well. I also tend to use ._XXX() for things that I'm deprecating but don't want to nuke the code from the file just yet. This is mostly because I'm slack with my test code (ie: I don't have any) so I'm not sure what else might be using the method and may need to reinstate it. :) -- Justin Warren From daedalus at eigenmagic.com Fri May 5 02:42:28 2006 From: daedalus at eigenmagic.com (Justin Warren) Date: Fri, 05 May 2006 10:42:28 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <445A9CD5.7040004@acm.org> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> <445A92FF.8090803@tennessee.id.au> <445A9CD5.7040004@acm.org> Message-ID: <1146789748.7067.11.camel@localhost.localdomain> On Fri, 2006-05-05 at 10:31 +1000, Maurice Ling wrote: > Hi, > > Programmatically, Python does not have any means to "hide" methods, all > methods are public (in java's terms). There may be some good reasons for > doing so, at least it simplifies things. However, in a large module > (especially modules that we did not write ourselves), changing a method > can be scary because it may break other parts. > > Personally, I think that using .XXX for public, ._XXX for internal and > .__XXX for private methods is more of a code documentation thing, which > is probably good if followed religiously. At least it does put up a > danger flag for yourself in future and prevent shooting yourself in the > foot. > > I am just wondering how can this is better tied in with Bill Birch's > type proposal...... I like that Python doesn't prevent you from using any method. This means that if I have a good reason for using a ._xx() or .__xx() method, I can use it without having to change the module to make the method public or shared (or whatever the C++ idiom is). I've had to use an 'internal' method from a third party module a couple of times because the module in question didn't have the interface or functionality I needed and I didn't want to write a wrapper module or modify the library code. It encourages me to contact the module developer to request a feature enhancement.. or to submit a patch. -- Justin Warren From mauriceling at acm.org Fri May 5 02:57:39 2006 From: mauriceling at acm.org (Maurice Ling) Date: Fri, 05 May 2006 10:57:39 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <1146789748.7067.11.camel@localhost.localdomain> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> <445A92FF.8090803@tennessee.id.au> <445A9CD5.7040004@acm.org> <1146789748.7067.11.camel@localhost.localdomain> Message-ID: <445AA303.8080903@acm.org> Justin Warren wrote: >On Fri, 2006-05-05 at 10:31 +1000, Maurice Ling wrote: > > >>Hi, >> >>Programmatically, Python does not have any means to "hide" methods, all >>methods are public (in java's terms). There may be some good reasons for >>doing so, at least it simplifies things. However, in a large module >>(especially modules that we did not write ourselves), changing a method >>can be scary because it may break other parts. >> >>Personally, I think that using .XXX for public, ._XXX for internal and >>.__XXX for private methods is more of a code documentation thing, which >>is probably good if followed religiously. At least it does put up a >>danger flag for yourself in future and prevent shooting yourself in the >>foot. >> >>I am just wondering how can this is better tied in with Bill Birch's >>type proposal...... >> >> > >I like that Python doesn't prevent you from using any method. This means >that if I have a good reason for using a ._xx() or .__xx() method, I can >use it without having to change the module to make the method public or >shared (or whatever the C++ idiom is). > > I understand your point on this. It does remove the constant need to decide the "view" of a method as I code in Python. My real concern with such idioms is this, it varies with developers. For example, you (Justin) may use ._XX for depreciation of codes, Tennessee uses ._XX for internal methods, we can appreciate the confusion of the 3rd person using both of your codes (or even more) together. So to an extend, when I look at unknown codes, .XX means safe and any number of underscore prefixes to XX (ie, ._XX or .__XX) means unquantified danger. I am hoping that Bill's type system is able to strike a middle ground on this, allowing developers to define their own coding conventions which is mappable to a standard type system as metaknowledge, or something like that. maurice >I've had to use an 'internal' method from a third party module a couple >of times because the module in question didn't have the interface or >functionality I needed and I didn't want to write a wrapper module or >modify the library code. It encourages me to contact the module >developer to request a feature enhancement.. or to submit a patch. > > > From darius at obsidian.com.au Fri May 5 02:52:40 2006 From: darius at obsidian.com.au (KevinL) Date: Fri, 05 May 2006 10:52:40 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <445A9CD5.7040004@acm.org> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> <445A92FF.8090803@tennessee.id.au> <445A9CD5.7040004@acm.org> Message-ID: <445AA1D8.4050804@obsidian.com.au> I thought I remembered something special about double-underscore attributes - http://www.thescripts.com/forum/thread41364.html has more detail. Basically, their name gets mangled to avoid namespace collisions. The upshot of this is, the classes you're working with may not behave as you expect if you inherit from it for another class (I'd guess that the potential for unexpected behaviour is low, but it's there). I, unlike you, don't see a middle ground between public and private - either the variable is part of the documented API and safe to use, or it's not. So .XXX and ._XXX are sufficient in my mind, and the only place I use double-underscores is for the standard __doc__, __init__, etc. methods. KevinL Maurice Ling wrote: > Hi, > > Programmatically, Python does not have any means to "hide" methods, all > methods are public (in java's terms). There may be some good reasons for > doing so, at least it simplifies things. However, in a large module > (especially modules that we did not write ourselves), changing a method > can be scary because it may break other parts. > > Personally, I think that using .XXX for public, ._XXX for internal and > .__XXX for private methods is more of a code documentation thing, which > is probably good if followed religiously. At least it does put up a > danger flag for yourself in future and prevent shooting yourself in the > foot. > > I am just wondering how can this is better tied in with Bill Birch's > type proposal...... > > maurice > > Tennessee Leeuwenburg wrote: > > >> Hi all, >> >> I've been starting to adopt a new coding idiom, and I thought I'd ask >> for comments. >> >> I've been extending some code, which has involved overriding many >> __doFoo() methods and accessing __myVariable variables. As I understand >> it, this is stylistically bad, and __XXX is a way of flagging that the >> thing is private-only. Keep Out Unless Absolutely Necessary. >> >> I can see a middle ground between the public interface and very private >> methods. Such a thing might be an element of processing which is >> typically called privately, but wouldn't be unsafe to call or override >> in appropriate circumstances. >> >> For this reason I've been using .XXX for the public interface, ._doFoo() >> for internal methods which are relatively safe, and .__doFoo() for >> things intended to be very private. >> >> Cheers, >> -T >> _______________________________________________ >> melbourne-pug mailing list >> melbourne-pug at python.org >> http://mail.python.org/mailman/listinfo/melbourne-pug >> >> >> >> > > _______________________________________________ > melbourne-pug mailing list > melbourne-pug at python.org > http://mail.python.org/mailman/listinfo/melbourne-pug > From miked at dewhirst.com.au Fri May 5 06:12:22 2006 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Fri, 05 May 2006 14:12:22 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <445A92FF.8090803@tennessee.id.au> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> <445A92FF.8090803@tennessee.id.au> Message-ID: <445AD0A6.4080906@dewhirst.com.au> Tennessee Leeuwenburg wrote: > Hi all, > > I've been starting to adopt a new coding idiom, and I thought I'd ask > for comments. > > I've been extending some code, which has involved overriding many > __doFoo() methods and accessing __myVariable variables. As I understand > it, this is stylistically bad, and __XXX is a way of flagging that the > thing is private-only. Keep Out Unless Absolutely Necessary. Here is what PEP 8 has to say ... ( http://www.python.org/dev/peps/pep-0008/ ) ... In addition, the following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention): - _single_leading_underscore: weak "internal use" indicator. E.g. "from M import *" does not import objects whose name starts with an underscore. - single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g. Tkinter.Toplevel(master, class_='ClassName') - __double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below). - __double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented. Regards Mike > > I can see a middle ground between the public interface and very private > methods. Such a thing might be an element of processing which is > typically called privately, but wouldn't be unsafe to call or override > in appropriate circumstances. > > For this reason I've been using .XXX for the public interface, ._doFoo() > for internal methods which are relatively safe, and .__doFoo() for > things intended to be very private. > > Cheers, > -T > _______________________________________________ > melbourne-pug mailing list > melbourne-pug at python.org > http://mail.python.org/mailman/listinfo/melbourne-pug > > From daedalus at eigenmagic.com Fri May 5 06:27:24 2006 From: daedalus at eigenmagic.com (Justin Warren) Date: Fri, 05 May 2006 14:27:24 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <445AD0A6.4080906@dewhirst.com.au> References: <200605012036.10902.birchb@tpg.com.au> <4456A3EF.3050808@tennessee.id.au> <445A92FF.8090803@tennessee.id.au> <445AD0A6.4080906@dewhirst.com.au> Message-ID: <1146803244.7067.28.camel@localhost.localdomain> On Fri, 2006-05-05 at 14:12 +1000, Mike Dewhirst wrote: > Tennessee Leeuwenburg wrote: > > Hi all, > > > > I've been starting to adopt a new coding idiom, and I thought I'd ask > > for comments. > > > > I've been extending some code, which has involved overriding many > > __doFoo() methods and accessing __myVariable variables. As I understand > > it, this is stylistically bad, and __XXX is a way of flagging that the > > thing is private-only. Keep Out Unless Absolutely Necessary. > > Here is what PEP 8 has to say ... I knew there was a good reason I used ._xx() that way. :) Note that when I say "code that is temporarily deprecated", by renaming the method I have explicitly changed the API from containing the method as a public method to one that is indicated as for internal use. Such use will be accompanied by comments, and since ._xx() won't get inherited by import *, you won't know about it unless you go looking for it, and notice the comments. 99% of the time such code doesn't make it out of testing and won't be checked into the code repository. Truly deprecated code raises a *mumble*Deprecated warning. -- Justin Warren From birchb at tpg.com.au Mon May 8 15:23:17 2006 From: birchb at tpg.com.au (Bill Birch) Date: Mon, 8 May 2006 23:23:17 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <445AA303.8080903@acm.org> References: <200605012036.10902.birchb@tpg.com.au> <1146789748.7067.11.camel@localhost.localdomain> <445AA303.8080903@acm.org> Message-ID: <200605082323.17780.birchb@tpg.com.au> On Fri, 5 May 2006 10:57 am, Maurice Ling wrote: > > I am hoping that Bill's type system is able to strike a middle ground on > this, allowing developers to define their own coding conventions which > is mappable to a standard type system as metaknowledge, or something > like that. > Hi, A type system would help reason about the code. There's been various proposals to add "interfaces" a la Java to Python. These have merit to solve this issue. The technique is to first define an interface or interfaces, then the implementation class methods or attributes that are not in in the interfaces are effectively private. By declaring interfaces you are publically committing to honour some methods, but caveat user on the others. Because the interface is separated you don't have the issues with underscores in names. The type system just allows you to capture the method signatures and have code to introspect them at runtime. Zope has an interface package which you can use right now. I have not used it (yet). Has anyone? It looks clunky. http://svn.zope.org/Zope3/trunk/src/zope/interface/README.txt?view=markup You -could- use a decorator to scare people away: def private(x) : return x def protected(x) : return x def public(x) : return x class Ubeaut(object): @private def hairyDetailedFunctionNoOneShouldUse(self): pass @public def goForIt(self): pass Not very original. But is blindingly obvious what you mean. If you stick with this system one day you could code up something more snazzy than the identity function. Personally I am against using underscores to give subtle meanings, and I am glad we have decorators. Perhaps one day the magic underscore behaviour of import will be replaced with a decorator. -- http://billbirch.wordpress.com/ From birchb at tpg.com.au Mon May 8 15:40:57 2006 From: birchb at tpg.com.au (Bill Birch) Date: Mon, 8 May 2006 23:40:57 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <1146803244.7067.28.camel@localhost.localdomain> References: <200605012036.10902.birchb@tpg.com.au> <445AD0A6.4080906@dewhirst.com.au> <1146803244.7067.28.camel@localhost.localdomain> Message-ID: <200605082340.57581.birchb@tpg.com.au> On Fri, 5 May 2006 02:27 pm, Justin Warren wrote: > Note that when I say "code that is temporarily deprecated", by renaming > the method I have explicitly changed the API from containing the method > as a public method to one that is indicated as for internal use. Such > use will be accompanied by comments, and since ._xx() won't get > inherited by import *, you won't know about it unless you go looking for > it, and notice the comments. 99% of the time such code doesn't make it > out of testing and won't be checked into the code repository. > > Truly deprecated code raises a *mumble*Deprecated warning. How about yet another decorator? def deprecated(f): def new_f(*args, **kwds): print "warning: deprecated function", f.func_name return f(*args, **kwds) new_f.func_name = f.func_name return new_f @deprecated def lepard(a, *args, **kwargs): print a, args, kwargs >>> lepard(1,2,3, four=4) warning: deprecated function lepard 1 (2, 3) {'four': 4} -- http://billbirch.wordpress.com/ From daedalus at eigenmagic.com Tue May 9 01:30:14 2006 From: daedalus at eigenmagic.com (Justin Warren) Date: Tue, 09 May 2006 09:30:14 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <200605082323.17780.birchb@tpg.com.au> References: <200605012036.10902.birchb@tpg.com.au> <1146789748.7067.11.camel@localhost.localdomain> <445AA303.8080903@acm.org> <200605082323.17780.birchb@tpg.com.au> Message-ID: <1147131014.5073.13.camel@localhost.localdomain> On Mon, 2006-05-08 at 23:23 +1000, Bill Birch wrote: > On Fri, 5 May 2006 10:57 am, Maurice Ling wrote: > > > > > I am hoping that Bill's type system is able to strike a middle ground on > > this, allowing developers to define their own coding conventions which > > is mappable to a standard type system as metaknowledge, or something > > like that. > > > Hi, > > A type system would help reason about the code. There's been various proposals > to add "interfaces" a la Java to Python. These have merit to solve this > issue. The technique is to first define an interface or interfaces, then the > implementation class methods or attributes that are not in in the interfaces > are effectively private. By declaring interfaces you are publically > committing to honour some methods, but caveat user on the others. Because > the interface is separated you don't have the issues with underscores in > names. The type system just allows you to capture the method signatures and > have code to introspect them at runtime. This is something I don't really understand as I don't have the background; I chose engineering. :) Could you possibly explain it? There may be others on the list who are interested in some CS fundamentals, too. Not understanding it well enough is a large contributor to my apprehension. > Zope has an interface package which you can use right now. I have not used it > (yet). Has anyone? It looks clunky. > http://svn.zope.org/Zope3/trunk/src/zope/interface/README.txt?view=markup I've used bits of it with my dealings with Zope and Twisted. It's not integrated into the python internals, but it seems to work quite well. > You -could- use a decorator to scare people away: > > def private(x) : return x > def protected(x) : return x > def public(x) : return x Why do people want to turn Python into C++ or Java? Why are you trying to scare away people who want to use your code? > class Ubeaut(object): > > @private > def hairyDetailedFunctionNoOneShouldUse(self): pass def ButWhatIfINeedToBecauseYouDidntImplementThePublicFunctionINeed(eh) > @public > def goForIt(self): pass > > Not very original. But is blindingly obvious what you mean. If you stick with > this system one day you could code up something more snazzy than the identity > function. > > Personally I am against using underscores to give subtle meanings, and I am > glad we have decorators. Perhaps one day the magic underscore behaviour of > import will be replaced with a decorator. Perhaps I don't see underscores as being so subtle. I'm all for an explicit mechanism of telling someone that certain portions of the API are stable and will be honoured, while other parts are volatile or not for public consumption. I'm not a big fan of someone preventing me from getting something done because they've prematurely optimised their API, leaving out something I believe should be there, and then preventing me from doing it myself because they've locked down the private functions. If public/private/whatever is simply a sign placed near the function warning me that I'm doing something dangerous, then fine. I might have a very good reason for doing it, and be confident in my ability to do so. I don't want the software making it arbitrarily difficult for me to get something done. That's one of the reasons I love Python so much. It doesn't get in my way as much as C++ or Java or Eiffel. -- Justin Warren From daedalus at eigenmagic.com Tue May 9 01:37:36 2006 From: daedalus at eigenmagic.com (Justin Warren) Date: Tue, 09 May 2006 09:37:36 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <200605082340.57581.birchb@tpg.com.au> References: <200605012036.10902.birchb@tpg.com.au> <445AD0A6.4080906@dewhirst.com.au> <1146803244.7067.28.camel@localhost.localdomain> <200605082340.57581.birchb@tpg.com.au> Message-ID: <1147131456.5073.19.camel@localhost.localdomain> On Mon, 2006-05-08 at 23:40 +1000, Bill Birch wrote: > On Fri, 5 May 2006 02:27 pm, Justin Warren wrote: > > > > Truly deprecated code raises a *mumble*Deprecated warning. > How about yet another decorator? > > def deprecated(f): > def new_f(*args, **kwds): > print "warning: deprecated function", f.func_name > return f(*args, **kwds) > new_f.func_name = f.func_name > return new_f > > @deprecated > def lepard(a, *args, **kwargs): > print a, args, kwargs > > >>> lepard(1,2,3, four=4) > warning: deprecated function lepard > 1 (2, 3) {'four': 4} Ah, no. I meant PEP 230, I believe, and the DeprecationWarning category. You could build a decorator to spit one out, I guess. -- Justin Warren From tennessee at tennessee.id.au Tue May 9 02:04:10 2006 From: tennessee at tennessee.id.au (Tennessee Leeuwenburg) Date: Tue, 09 May 2006 10:04:10 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <1147131014.5073.13.camel@localhost.localdomain> References: <200605012036.10902.birchb@tpg.com.au> <1146789748.7067.11.camel@localhost.localdomain> <445AA303.8080903@acm.org> <200605082323.17780.birchb@tpg.com.au> <1147131014.5073.13.camel@localhost.localdomain> Message-ID: <445FDC7A.30906@tennessee.id.au> > >> @public >> def goForIt(self): pass >> >> Not very original. But is blindingly obvious what you mean. If you stick with >> this system one day you could code up something more snazzy than the identity >> function. >> >> Personally I am against using underscores to give subtle meanings, and I am >> glad we have decorators. Perhaps one day the magic underscore behaviour of >> import will be replaced with a decorator. >> > > Perhaps I don't see underscores as being so subtle. I'm all for an > explicit mechanism of telling someone that certain portions of the API > are stable and will be honoured, while other parts are volatile or not > for public consumption. I'm not a big fan of someone preventing me from > getting something done because they've prematurely optimised their API, > leaving out something I believe should be there, and then preventing me > from doing it myself because they've locked down the private functions. > > If public/private/whatever is simply a sign placed near the function > warning me that I'm doing something dangerous, then fine. I might have a > very good reason for doing it, and be confident in my ability to do so. > I don't want the software making it arbitrarily difficult for me to get > something done. > > That's one of the reasons I love Python so much. It doesn't get in my > way as much as C++ or Java or Eiffel. > > I strongly agree. I don't think using doXX(), _doXX(), and __doXX() are only subtly different. I think it's quite clear. It's nice and brief, a quick hint as to the intended use of the function. I don't want to be prevented from doing things, nor do I want to have to catch interface violations at runtime "just in case" someone has used an interface. If I liked a language that strict, I'd use Java, because it's also powerful and supports all that junk/jazz. Strong interfaces could kill python for hackers. Decorators are not in themselves bad. I find them confusing and unnatural, but maybe that's just because I'm not used to them. However, using them for evil is evil -- and I think that it's evil to allow programmers to write uncallable methods. Cheers -T From tennessee at tennessee.id.au Tue May 9 02:08:44 2006 From: tennessee at tennessee.id.au (Tennessee Leeuwenburg) Date: Tue, 09 May 2006 10:08:44 +1000 Subject: [melbourne-pug] Decorators In-Reply-To: <1147131014.5073.13.camel@localhost.localdomain> References: <200605012036.10902.birchb@tpg.com.au> <1146789748.7067.11.camel@localhost.localdomain> <445AA303.8080903@acm.org> <200605082323.17780.birchb@tpg.com.au> <1147131014.5073.13.camel@localhost.localdomain> Message-ID: <445FDD8C.9080700@tennessee.id.au> Does anyone have any functional code which demonstrates the use of decorators? I don't mean just @staticmethod def foo(): print "bar" but rather something that demonstrates where and why one would make use of a decorator? Cheers, -T From gcross at fastmail.fm Tue May 9 02:47:51 2006 From: gcross at fastmail.fm (Graeme Cross) Date: Tue, 09 May 2006 10:47:51 +1000 Subject: [melbourne-pug] Decorators In-Reply-To: <445FDD8C.9080700@tennessee.id.au> References: <200605012036.10902.birchb@tpg.com.au> <1146789748.7067.11.camel@localhost.localdomain> <445AA303.8080903@acm.org> <200605082323.17780.birchb@tpg.com.au> <1147131014.5073.13.camel@localhost.localdomain> <445FDD8C.9080700@tennessee.id.au> Message-ID: <1147135671.26335.260940459@webmail.messagingengine.com> On Tue, 09 May 2006 10:08:44 +1000, "Tennessee Leeuwenburg" said: > Does anyone have any functional code which demonstrates the use of > decorators? I don't mean just > > @staticmethod > def foo(): > print "bar" > > but rather something that demonstrates where and why one would make use > of a decorator? > http://wiki.python.org/moin/PythonDecoratorLibrary is a good resource. To quote the page: "This page is meant to be a central repository of decorator code pieces, whether useful or not ." - Graeme -- Graeme Cross E-mail: gcross at fastmail.net From gcross at fastmail.fm Tue May 9 02:50:42 2006 From: gcross at fastmail.fm (Graeme Cross) Date: Tue, 09 May 2006 10:50:42 +1000 Subject: [melbourne-pug] Decorators In-Reply-To: <1147135671.26335.260940459@webmail.messagingengine.com> References: <200605012036.10902.birchb@tpg.com.au> <1146789748.7067.11.camel@localhost.localdomain> <445AA303.8080903@acm.org> <200605082323.17780.birchb@tpg.com.au> <1147131014.5073.13.camel@localhost.localdomain> <445FDD8C.9080700@tennessee.id.au> <1147135671.26335.260940459@webmail.messagingengine.com> Message-ID: <1147135842.27175.260940636@webmail.messagingengine.com> On Tue, 09 May 2006 10:47:51 +1000, "Graeme Cross" said: > On Tue, 09 May 2006 10:08:44 +1000, "Tennessee Leeuwenburg" > said: > > Does anyone have any functional code which demonstrates the use of > > decorators? I don't mean just > > > > @staticmethod > > def foo(): > > print "bar" > > > > but rather something that demonstrates where and why one would make use > > of a decorator? > > > > http://wiki.python.org/moin/PythonDecoratorLibrary is a good resource. And a quick search in the Python cookbook reveals 53 recipes that mention decorators, and some of those recipes are both educational and useful. http://aspn.activestate.com/ASPN/search?query=decorator&x=0&y=0§ion=PYTHONCKBK&type=Subsection Regards, Graeme -- Graeme Cross E-mail: gcross at fastmail.net From birchb at tpg.com.au Tue May 9 17:16:56 2006 From: birchb at tpg.com.au (Bill Birch) Date: Wed, 10 May 2006 01:16:56 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <1147131014.5073.13.camel@localhost.localdomain> References: <200605012036.10902.birchb@tpg.com.au> <200605082323.17780.birchb@tpg.com.au> <1147131014.5073.13.camel@localhost.localdomain> Message-ID: <200605100116.57066.birchb@tpg.com.au> On Tue, 9 May 2006 09:30 am, Justin Warren wrote: > Today 09:30:14 am > > On Mon, 2006-05-08 at 23:23 +1000, Bill Birch wrote: > > On Fri, 5 May 2006 10:57 am, Maurice Ling wrote: > > > I am hoping that Bill's type system is able to strike a middle ground > > > on this, allowing developers to define their own coding conventions > > > which is mappable to a standard type system as metaknowledge, or > > > something like that. > > > > Hi, > > > > A type system would help reason about the code. There's been various > > proposals to add "interfaces" a la Java to Python. These have merit to > > solve this issue. The technique is to first define an interface or > > interfaces, then the implementation class methods or attributes that are > > not in in the interfaces are effectively private. By declaring interfaces > > you are publically committing to honour some methods, but caveat user on > > the others. ?Because the interface is separated you don't have the issues > > with underscores in names. The type system just allows you to capture the > > method signatures and have code to introspect them at runtime. > > This is something I don't really understand as I don't have the > background; I chose engineering. :) Could you possibly explain it? There > may be others on the list who are interested in some CS fundamentals, > too. Not understanding it well enough is a large contributor to my > apprehension. Me too, I chose engineering. I just read a lot ;-) OK - Here's an explanation: Type systems are just meta-data, that is data about data. The int object in Python is just an object like any other, except it captures the thought "all objects which are integers". Type theory is based on set theory. So maths people say that a type is just a set. So int is the set of all objects which are integers. And yes it could be infinite. So when I said that a type system helps you reason about code, I mean that when you layer types onto each other they begin to look like declarative rules. And when you add code which can use the type objects it can make deductions about the programs. This is how type inferencing works. The languages have rich internal type systems which the compilers use to do fancy deductions about types. Interfaces were created as a way of describing classes without showing how they were implemented. C++ has abstract classes and multiple inheritance. Java has interfaces as a way of allowing objects to have a kind of multiple inheritance. There are also hundreds of "Interface Definition Languages" (IDLs) for defining distributed procedure calling. DCE, CORBA, SOAP all have them. All of them provide just the class definition without any procedural code: interface Shape: def draw(x: int, y: int) def moveTo(x, int, y: int) def area() -> float An interface just describes the outside surface of the object. There are no innards. So if you can declare that you are abiding by that interface: class Square( implements(Shape) ): def __init__(self, ...): ... def draw(x: int, y: int): ... And an IDE or type checker can make sure you -do- implement all the required methods. Likewise, if someone is writing generic code they can limit the number of possibilities by constraining input arguments to only allow objects which conform to an interface: def drawAlotOfShapes(collection: list[Shape]): for s in collection: s.draw() Interfaces allow you to say "I look like a Shape" , whereas class inheritance says " I am constructed from a Shape". People using Python don't need interfaces to be able to call methods, but in large bodies of code (like Zope) it helps humans to understand how to maintain the code if there is a description of the significant methods required to plug one class into another. This is why Zope added their own interfaces. Interfaces are a way of saying to the user of your code which bits they need to care about. So what I meant was that if you are using interfaces to document your classes, then there is less need to adopt concepts like 'private'. If all you know about is the interface, you don't see the guts. Python is at a cross-roads in its development, because in Python-3000 it's likely that there will be a way to annotate functions with types, and hence there will be some easier way to implement interfaces. However the Python community needs to decide if they are going to have a type system that works with duck typing like Haskell, or one that is like C++/Java. The two camps are "structural subtyping" and "nominative subtyping". nominative subtyping works off labels attached to the objects. If you are nominative you simply look at the label on an object to find out what it is. So if there is a thing with a label stuck to it saying "I am a duck." you just assume it is one. If you are structural you actually perform a deep analysis of the object and deduce its type based on what you find and prior declarations. So if you see that something has feathers, wings, a bill and makes a quacking sound you assume it is a duck. Even if it has a note stuck to it saying "I am a banana.". Python currently uses duck typing (aka no typing), it's like LISP in that way. Call a function, see what it does. So IMHO if Python is to be expanded to have Interfaces and more complex types, then it needs to support structural subtyping -and- nominative typing. Although Python does have nominative labels, __class__, __bases__, they don't prevent classes with different names working in the same role. e.g. class A(object): def callMe(self): print 'callMe' class B(object): def callMe(self): print 'callMe' def useIt(x): x.callMe() useIt(A()) # no error useIt(B()) # no error Although class A and B have no relationship to each other they are 'plug-compatible'. They are structural equivalents and hence useIt() can call either. This would fail in C++ or Java since A and B would have to inherit from an interface of base class. The goal is to codify the structural interface in an obvious way: interface IcanBeCalled: def callMe() -- http://billbirch.wordpress.com/ From mauriceling at acm.org Wed May 10 01:28:14 2006 From: mauriceling at acm.org (Maurice Ling) Date: Wed, 10 May 2006 09:28:14 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <200605100116.57066.birchb@tpg.com.au> References: <200605012036.10902.birchb@tpg.com.au> <200605082323.17780.birchb@tpg.com.au> <1147131014.5073.13.camel@localhost.localdomain> <200605100116.57066.birchb@tpg.com.au> Message-ID: <4461258E.8070303@acm.org> Bill Birch wrote: >On Tue, 9 May 2006 09:30 am, Justin Warren wrote: > > >>Today 09:30:14 am >> >>On Mon, 2006-05-08 at 23:23 +1000, Bill Birch wrote: >> >> >>>On Fri, 5 May 2006 10:57 am, Maurice Ling wrote: >>> >>> >>>>I am hoping that Bill's type system is able to strike a middle ground >>>>on this, allowing developers to define their own coding conventions >>>>which is mappable to a standard type system as metaknowledge, or >>>>something like that. >>>> >>>> >>>Hi, >>> >>>A type system would help reason about the code. There's been various >>>proposals to add "interfaces" a la Java to Python. These have merit to >>>solve this issue. The technique is to first define an interface or >>>interfaces, then the implementation class methods or attributes that are >>>not in in the interfaces are effectively private. By declaring interfaces >>>you are publically committing to honour some methods, but caveat user on >>>the others. Because the interface is separated you don't have the issues >>>with underscores in names. The type system just allows you to capture the >>>method signatures and have code to introspect them at runtime. >>> >>> >>This is something I don't really understand as I don't have the >>background; I chose engineering. :) Could you possibly explain it? There >>may be others on the list who are interested in some CS fundamentals, >>too. Not understanding it well enough is a large contributor to my >>apprehension. >> >> >Me too, I chose engineering. I just read a lot ;-) > >OK - Here's an explanation: > >Type systems are just meta-data, that is data about data. The int object in >Python is just an object like any other, except it captures the thought "all >objects which are integers". Type theory is based on set theory. So maths >people say that a type is just a set. So int is the set of all objects which >are integers. And yes it could be infinite. So when I said that a type >system helps you reason about code, I mean that when you layer types onto >each other they begin to look like declarative rules. And when you add code >which can use the type objects it can make deductions about the programs. >This is how type inferencing works. The languages have rich internal type >systems which the compilers use to do fancy deductions about types. > >Interfaces were created as a way of describing classes without showing how >they were implemented. C++ has abstract classes and multiple inheritance. >Java has interfaces as a way of allowing objects to have a kind of multiple >inheritance. There are also hundreds of "Interface Definition >Languages" (IDLs) for defining distributed procedure calling. DCE, CORBA, >SOAP all have them. All of them provide just the class definition without any >procedural code: > >interface Shape: > def draw(x: int, y: int) > def moveTo(x, int, y: int) > def area() -> float > >An interface just describes the outside surface of the object. There are no >innards. > >So if you can declare that you are abiding by that interface: > >class Square( implements(Shape) ): > def __init__(self, ...): > ... > def draw(x: int, y: int): > ... >And an IDE or type checker can make sure you -do- implement all the required >methods. Likewise, if someone is writing generic code they can limit the >number of possibilities by constraining input arguments to only allow objects >which conform to an interface: > >def drawAlotOfShapes(collection: list[Shape]): > for s in collection: > s.draw() > >Interfaces allow you to say "I look like a Shape" , whereas class inheritance >says " I am constructed from a Shape". > >People using Python don't need interfaces to be able to call methods, but in >large bodies of code (like Zope) it helps humans to understand how to >maintain the code if there is a description of the significant methods >required to plug one class into another. This is why Zope added their own >interfaces. > >Interfaces are a way of saying to the user of your code which bits they need >to care about. So what I meant was that if you are using interfaces to >document your classes, then there is less need to adopt concepts like >'private'. If all you know about is the interface, you don't see the guts. > >Python is at a cross-roads in its development, because in Python-3000 it's >likely that there will be a way to annotate functions with types, and hence >there will be some easier way to implement interfaces. However the Python >community needs to decide if they are going to have a type system that works >with duck typing like Haskell, or one that is like C++/Java. > >The two camps are "structural subtyping" and "nominative subtyping". >nominative subtyping works off labels attached to the objects. If you are >nominative you simply look at the label on an object to find out what it is. >So if there is a thing with a label stuck to it saying "I am a duck." you >just assume it is one. If you are structural you actually perform a deep >analysis of the object and deduce its type based on what you find and prior >declarations. So if you see that something has feathers, wings, a bill and >makes a quacking sound you assume it is a duck. Even if it has a note stuck >to it saying "I am a banana.". > >Python currently uses duck typing (aka no typing), it's like LISP in that >way. Call a function, see what it does. So IMHO if Python is to be expanded >to have Interfaces and more complex types, then it needs to support >structural subtyping -and- nominative typing. > >Although Python does have nominative labels, __class__, __bases__, they don't >prevent classes with different names working in the same role. e.g. > >class A(object): > def callMe(self): > print 'callMe' > >class B(object): > def callMe(self): > print 'callMe' > >def useIt(x): > x.callMe() > >useIt(A()) # no error >useIt(B()) # no error > >Although class A and B have no relationship to each other they are >'plug-compatible'. They are structural equivalents and hence useIt() can call >either. This would fail in C++ or Java since A and B would have to inherit >from an interface of base class. > >The goal is to codify the structural interface in an obvious way: > >interface IcanBeCalled: > def callMe() > > > The explanation that Java developers gave for having interface is that Java only accepts single inheritance, which can be a problem. For example, Java threads typically inherits from Thread class, which contains the methods for multithreading. However, this means that your class (ie, circles) cannot be derived from another suitable parent class (ie, shapes). So, an interface "Runnable" is used. In fact, Thread class implements Runnable to mark it as multithreadable. Now, my Circles class can be derived from Shapes class and implements Runnable for multithreading. Python does not have this issue. Nevertheless, I concur with Bill about interfaces (ie, class declarations without innards). Sometimes in my work, I use "abstract" classes to mark out crucial interfaces (ie, an engine class should have the following methods implemented) so that module switching (in the case of plug ins) can happen at runtime. May not have any real protection or safeguard value but it sure has documentation value. For example, the interface class describes what the methods should do (the requirements), and the implementation class (implementing the interface) describes how the methods are implemented in accordance to the requirement. maurice From daedalus at eigenmagic.com Wed May 10 02:00:43 2006 From: daedalus at eigenmagic.com (Justin Warren) Date: Wed, 10 May 2006 10:00:43 +1000 Subject: [melbourne-pug] Coding idiom In-Reply-To: <200605100116.57066.birchb@tpg.com.au> References: <200605012036.10902.birchb@tpg.com.au> <200605082323.17780.birchb@tpg.com.au> <1147131014.5073.13.camel@localhost.localdomain> <200605100116.57066.birchb@tpg.com.au> Message-ID: <1147219243.5827.14.camel@localhost.localdomain> On Wed, 2006-05-10 at 01:16 +1000, Bill Birch wrote: [snip] Great explanation. Thanks. Now I know what duck typing is! > Although class A and B have no relationship to each other they are > 'plug-compatible'. They are structural equivalents and hence useIt() can call > either. This would fail in C++ or Java since A and B would have to inherit > from an interface of base class. > > The goal is to codify the structural interface in an obvious way: > > interface IcanBeCalled: > def callMe() This is a noble and useful goal, and I appreciate the benefits of a well defined interface between modules. I also like not having to have classes inherit from a common base class in order to implement some functionality defined in an interface somewhere. It's much more practical and I believe is a better reflection of real life than the idealised CS model of OO. So, this type system.. it will support the ability to define an input type that adheres to a given interface, a la your Shape example? How does it differ from zope.interface? What advantages will it provide? What are its downsides? As an aside, I'm enjoying learning about this stuff. :) -- Justin Warren From birchb at tpg.com.au Tue May 16 13:45:01 2006 From: birchb at tpg.com.au (Bill Birch) Date: Tue, 16 May 2006 21:45:01 +1000 Subject: [melbourne-pug] Enhancement - Argument Decorators? Message-ID: <200605162145.01783.birchb@tpg.com.au> Today I posted this to c.l.p. Any feedback gratefully received etc ---------- Guido has proposed a syntax for type annotations in Python-3000. Example: def foo(x: t1, y: t2) -> t3: ...body... http://www.artima.com/weblogs/viewpost.jsp?thread=87182 The types are dynamic and there is significant execution of code prior to the function body being called. Which tends to make the above closer to a decorator than a static type declaration. That being so, it occurred to me that perhaps an argument decorator would be more general and perhaps less restrictive. The example using decorators: def foo(@T1 x, @t2 y) @ t3: ...body... The compiler would do something like this: def foo__(x, y): # original function ...body... def foo(x, y): # wrapper function x = T1.__decarg__(foo_, x) y = t2.__decarg__(foo_, y) r = foo__(x, y) return t3.__decreturn___(foo__, r) More examples: def func(@between(1,400) x) @bool : # between checks input range def func(@NotNone x): # x must be a real object def func(@long x) @coerce(float): # coerce forces type conversion def func(@sequence s, @function fn) @sequence: # more abstract types To someone used to reading decorators, the @ character is a flag that some kind of dynamic magic is being run. So IMHO using @ here too is consistent with its existing usage. Argument decorators would be an object (not a function) with methods corresponding to their usage: class T1(object): def __decarg__(self, function, arg): # returns arg def __decreturn__(self, function, arg): # returns arg This will allow existing types to be used if they implement these methods: def bar(@int x, @float y) @float : ...body... Because this syntax is just a decorator, you could use or abuse it as you wished. So you could define and use your own type-checking classes and semantics: def bar(@StrictlyInt x, @DuckCompatibleSequence seq) : ...body... Since the decorator is an *object*, not a function, we could add other methods for use by IDEs for intellisense etc. Any views on this? Something to put forward to the python-3000 list maybe? -- http://billbirch.wordpress.com/ From richardjones at optushome.com.au Wed May 31 01:00:11 2006 From: richardjones at optushome.com.au (Richard Jones) Date: Wed, 31 May 2006 09:00:11 +1000 Subject: [melbourne-pug] Open Source Developers' Conference 2006 - Call for papers Message-ID: <200605310900.11627.richardjones@optushome.com.au> http://www.osdc.com.au/papers/cfp06.html The Open Source Developers' Conference is an Australian conference designed for developers, by developers. It covers numerous programming languages across a range of operating systems. We're seeking papers on Open Source languages, technologies, projects and tools as well as topics of interest to Open Source developers. The conference will be held in Melbourne, Victoria (Monash University's Caulfield Campus) from the 6th to the 8th of December, 2006. Last year's conference had about 160 people and around 60 presentations on a range of topics - see http://osdc2005.cgpublisher.com/proposals/ for a list. This list might also be useful if you're looking for ideas on what sort of thing would be appropriate. If you have any questions, or have never submitted a paper proposal before, please read our FAQ page at http://www.osdc.com.au/faq/index.html If you don't find an answer there, please contact richard at osdc.com.au To submit a proposal, follow the instructions at http://www.osdc.com.au/papers/cfp06.html This year we're also going to run a day of tutorials. See the CFP for more information. The deadline for proposals is 12th July 2006. Hope to see you there! The OSDC 2006 committee.