Thread: [Pyobjc-dev] NGPython
Brought to you by:
ronaldoussoren
From: Helge H. <hel...@op...> - 2004-02-29 20:17:26
|
Hi, just tried out the 1.1b1 release, very nice :-) Actually I have written an Objective-C bridge for Python on GNUstep/libFoundation some five years ago, this was called NGPython. While it doesn't seem to compile anymore out of the box even on GNUstep, I thought someone might be interested in ripping of some code nevertheless. The most interesting part is probably the "pybridget2.py" tool contained in NGPython. This is actually a parser for headers and "jobs" files - similiar to those used for the NeXT Java bridge, and for generating class wrapping information. It was pretty flexible on mapping Python function names to selectors: ---snip--- class NSSet = FoundationCollections.NSSet constructor -initWithArray: constructor -initWithSet: @{ keyConstructors = { "array": "initWithArray", "set": "initWithSet" } lenConstructors = { 0: "init", 1: "initWithArray" } @} -allObjects ---snap--- For construction of Python objects you could then use code like this: ---snip--- set = NSSet(array=myarray) set = NSSet(set=otherSet) ---snap--- With the mapping mechanism taking keywords and positional parameters into account. I think that this was much more beautiful than the current automatic ":" => "_" scheme used in PyObjC ;-) So, if someone is interested, drop me a line and I send you the code ;-) Unfortunately I won't find the time to look at adding the mapping stuff to PyObjC, but maybe someone else has ... best regards, Helge -- http://docs.opengroupware.org/Members/helge OpenGroupware.org |
From: b.bum <bb...@ma...> - 2004-03-01 06:30:13
|
On Feb 29, 2004, at 12:13 PM, Helge Hess wrote: > With the mapping mechanism taking keywords and positional parameters > into account. > I think that this was much more beautiful than the current automatic > ":" => "_" scheme used in PyObjC ;-) It fails this simple test: can the mapping rule be expressed as a single rule. The ":" -> "_" mapping, though ugly (really -- none of us are attached to it), can: "Given an ObjC method name, replace all ":" with "_" to find the python name." A 'bridget' style mapping cannot. There will be special cases and the end result will be a new language that is effectively a hybrid between Python and Objective-C. Just like the Java<->Objective-C bridge, such an approach to "mapping" Objective-C methods into Python in a "Pythonic" fashion will yield something that requires the developer to learn a new language. To use the provided examples: > set = NSSet(array=myarray) > set = NSSet(set=otherSet) Neither of these are meaningful to either the Python or Objective-C developer. The current form is as follows: set = NSSet.setWithArray_(myarray) set = NSSet.setWithSet_(otherSet) While the trailing '_' are unpalatable to the traditional Python programmer, it is extremely clear exactly what the code is doing. If not, the developer only has to remember one rule to figure out what bit of Foundation documentation to read to figure it out. Relevant post here: http://www.pycs.net/bbum/2003/11/29.html Thread starts here: http://mail.python.org/pipermail/pythonmac-sig/2002-October/006458.html b.bum |
From: Helge H. <hel...@op...> - 2004-03-01 10:07:15
|
On 01.03.2004, at 07:26, b.bum wrote: >> I think that this was much more beautiful than the current automatic >> ":" => "_" scheme used in PyObjC ;-) > > It fails this simple test: can the mapping rule be expressed as a > single rule. > The ":" -> "_" mapping, though ugly (really -- none of us are attached > to it), can: > "Given an ObjC method name, replace all ":" with "_" to find the > python name." > A 'bridget' style mapping cannot. Could you elaborate? What do you mean by "can be expressed as a single rule"? Do you care about speed? Of course the mapping "can" be expressed as a single rule as long as it is unique. > There will be special cases and the end result will be a new language > that is effectively a hybrid between Python and Objective-C. Absolutely not, this is just regular Python - a function which does different things depending on the input parameters. Of course the developer need to know about the used libraries in any case. > Just like the Java<->Objective-C bridge, such an approach to "mapping" > Objective-C methods into Python in a "Pythonic" fashion will yield > something that requires the developer to learn a new language. I can't see why. Indeed he does need to know much less about Objective-C than before if he doesn't do exotic things. > To use the provided examples: >> set = NSSet(array=myarray) >> set = NSSet(set=otherSet) > > Neither of these are meaningful to either the Python or Objective-C > developer. Well, all Python developers I know can perfectly deal with that. Its just regular style, eg extensively used in Zope. > The current form is as follows: > > set = NSSet.setWithArray_(myarray) > set = NSSet.setWithSet_(otherSet) > > While the trailing '_' are unpalatable to the traditional Python > programmer, it is extremely clear exactly what the code is doing. If > not, the developer only has to remember one rule to figure out what > bit of Foundation documentation to read to figure it out. There are obviously situations where and explicit factory makes a lot more sense, yet, in the case of NSSet its awkward and unintuitive for Python developers (and even Objective-C developers will get into difficulties to know what syntax to use in what situation). > Relevant post here: > http://www.pycs.net/bbum/2003/11/29.html OK, your position understood ;-) We had none of your issues listed (neither speed nor maintenance) and used the stuff in real world applications for some two years or so. Writing .jobs files is a no-brainer and there is nothing which prevents you from falling back to "ugly" syntax in case there is no mapping. Anyway, we can let the thread stop here, my posting wasn't really meant to start a flamewar but to offer some code in case someone is interested ;-) BTW: your post fails to list the really interesting parts, like the required reverse mapping of selectors for subclassing Objective-C objects in Python. best regards, Helge -- http://docs.opengroupware.org/Members/helge OpenGroupware.org |
From: b.bum <bb...@ma...> - 2004-03-01 17:12:36
|
Please read the rather long thread on python-dev. All of the points you raise have been addressed in that thread. This is a subject that has come up every 18 months to two years for the history of the PyObjC project (since 1994/1995) and the change has not been made yet. None of us are attached to the '_' based notation, but it remains because it is brain-dead simple and has no exceptions beyond those necessary to support the idiosyncrasies of mapping C to Python. > Good points, yet the "usual" mapping rule is pretty easy to explain > and understand and just makes sense. Like if you have an Objective-C > method with "With", the "With" denotes keyword arguments > (initWithSet:, NSSet(set=)). > I don't think this is much more difficult for the regular developer to > remember. Except that there are exceptions.... and exceptions to the exceptions... End result developer has to remember: "This is the mapping, except this special case and that special case and this other special case and that inconsistency and, oh wait, this is a new framework, it hasn't been mapped yet and oops, Apple released a new version, those haven't been mapped yet but will be..." On Mar 1, 2004, at 2:02 AM, Helge Hess wrote: > On 01.03.2004, at 07:26, b.bum wrote: >>> I think that this was much more beautiful than the current automatic >>> ":" => "_" scheme used in PyObjC ;-) >> >> It fails this simple test: can the mapping rule be expressed as a >> single rule. >> The ":" -> "_" mapping, though ugly (really -- none of us are >> attached to it), can: >> "Given an ObjC method name, replace all ":" with "_" to find the >> python name." >> A 'bridget' style mapping cannot. > > Could you elaborate? What do you mean by "can be expressed as a single > rule"? Do you care about speed? > Of course the mapping "can" be expressed as a single rule as long as > it is unique. Speed is just a matter of caching and optimizations. The last sentence of your statement is exactly why mappings are a nightmare. There will always be special cases, including dealing with situations where the default "mapping" is not unique. >> There will be special cases and the end result will be a new language >> that is effectively a hybrid between Python and Objective-C. > > Absolutely not, this is just regular Python - a function which does > different things depending on the input parameters. Of course the > developer need to know about the used libraries in any case. A language is a combination of its syntax and the APIs of the base libraries. To effectively use Python, you need to know Python and you need to know some limited subset of the python library. The same is true of Cocoa or GNUStep based Objective-C. A mapping based solution attemps to "port" the Objective-C API into Python in a "Pythonic" fashion. The end result is an API that is neither Objective-C nor Python. It sort of looks like Python, but there will be all kinds of weird little special cases resulting from the underlying C nature of Objective-C. >> Just like the Java<->Objective-C bridge, such an approach to >> "mapping" Objective-C methods into Python in a "Pythonic" fashion >> will yield something that requires the developer to learn a new >> language. > > I can't see why. Indeed he does need to know much less about > Objective-C than before if he doesn't do exotic things. That is incorrect. The developer still has to know that there is API to be called and still has to find that API. As it stands, the developer can find the API by looking directly in the Python library or finding the API by looking directly in the Objective-C header files [API]. A mapped solution ensures that the developer cannot look in either of these places to find canonical information as to what they should implement. Furthermore, the Objective-C method names are meaningful. -setObject:forKey: says more than just "this is a method named 'setObject:forKey:', it also gives information about the arguments and their order (and, no, they are not named arguments). A mapping based solution loses all of that. This was one of the primary complaints about bridged Java (and WO 5.x). The Java APIs were a mutated Foundation. It was less approachable to new developers because the API was not as self-descriptive. >> The current form is as follows: >> >> set = NSSet.setWithArray_(myarray) >> set = NSSet.setWithSet_(otherSet) >> >> While the trailing '_' are unpalatable to the traditional Python >> programmer, it is extremely clear exactly what the code is doing. If >> not, the developer only has to remember one rule to figure out what >> bit of Foundation documentation to read to figure it out. > > There are obviously situations where and explicit factory makes a lot > more sense, yet, in the case of NSSet its awkward and unintuitive for > Python developers (and even Objective-C developers will get into > difficulties to know what syntax to use in what situation). If Objective-C developers have difficulty and that difficulty is still found in bridged Obj-C on the python side, why go through such pains to hide it? Again, unless the PyObjC project were to specifically document each and every mapping, there is nowhere that the developer could look up NSSet(array=myArray) to understand what is being invoked on the ObjC side. > Anyway, we can let the thread stop here, my posting wasn't really > meant to start a flamewar but to offer some code in case someone is > interested ;-) No flamewar -- I don't think you understand how much thought, effort, and engineering has gone into the current implementation, including a lot of thinking as to how to make a mapping based solution work. I think I can safely speak for the entire pyobjc-dev community in saying that we all think the '_' based notation isn't pretty. But the lack of 'pythonic syntax' is a disadvantage that pales in comparison to having a solution that "just works" across releases of the OS and with any Objective-C API available, including those that we have never "mapped". > BTW: your post fails to list the really interesting parts, like the > required reverse mapping of selectors for subclassing Objective-C > objects in Python. Subclassing works fine. Go read the python-dev thread, there is a lot more info there.... b.bum |
From: Helge H. <hel...@op...> - 2004-03-01 17:38:42
|
On 01.03.2004, at 18:08, b.bum wrote: > Please read the rather long thread on python-dev. All of the points > you raise have been addressed in that thread. Well, I think I have very well understood your point on that. The reason why I still like the approach is that we have the experience that it works just great in practice, has little to no maintenance issues and is much easier to understand for non-Objective-C people. So you may or may not follow on that, your decision ;-) Really no point in discussing that. > This is a subject that has come up every 18 months to two years for > the history of the PyObjC project (since 1994/1995) and the change has > not been made yet. Well, at least I can provide code for getting started, I guess that validates bringing up the topic yet another time ;-) > A mapping based solution attemps to "port" the Objective-C API into > Python in a "Pythonic" fashion. The end result is an API that is > neither Objective-C nor Python. It sort of looks like Python, but > there will be all kinds of weird little special cases resulting from > the underlying C nature of Objective-C. Actually this is less a problem with Python since you can override all the Pythonic stuff (for iterators, attributes access etc) and make Objective-C objects look like regular Python ones. > A mapped solution ensures that the developer cannot look in either of > these places to find canonical information as to what they should > implement. Only if the mapping is unnatural and difficult to understand. Which it isn't. Besides that its not a big deal at all to write a small Python script which generates new index files into Objective-C documentation which takes mappings into account. > Furthermore, the Objective-C method names are meaningful. > -setObject:forKey: says more than just "this is a method named > 'setObject:forKey:', it also gives information about the arguments and > their order (and, no, they are not named arguments). A mapping based > solution loses all of that. I don't see why. You can of course map the selector setObject:forKey: to a method named setObjectForKey in case you want to do that. After all thats the whole point - making better user-level method names which are natural in the host language. Note: the pybridget tool also supports matching based on positional parameters, not only on keywords. > This was one of the primary complaints about bridged Java (and WO > 5.x). The Java APIs were a mutated Foundation. It was less > approachable to new developers because the API was not as > self-descriptive. If you say so. I think its more a problem of having various different collection classes and few ways to mix their usage (say List vs NSArray vs Collection.Array vs JGL vs ...). But, no point (and interest ;-) in discussing that. This isn't so much a problem with Python where Foundation collections can act like regular Python collections. >> Anyway, we can let the thread stop here, my posting wasn't really >> meant to start a flamewar but to offer some code in case someone is >> interested ;-) > > No flamewar -- I don't think you understand how much thought, effort, > and engineering has gone into the current implementation, including a > lot of thinking as to how to make a mapping based solution work. OK. I can ackknowledge that, in case you also understand how much thought, effort, and engineering were done in the NGPython implementation, including a lot of thinking as to how to make a mapping based solution work ;-) I did not want to start a discussion, if PyObjC people have decided not to do any mapping, its their choice, no discussion about that. I *only* offered some code which could help getting started with that and mentioned, that the approach worked just fine for us. >> BTW: your post fails to list the really interesting parts, like the >> required reverse mapping of selectors for subclassing Objective-C >> objects in Python. > Subclassing works fine. Yes, of course, but its more interesting (difficult) with a mapping framework in place ;-) > Go read the python-dev thread, there is a lot more info there.... Sorry, not enough sparetime. best regards, Helge -- http://docs.opengroupware.org/Members/helge OpenGroupware.org |
From: Dinu G. <gh...@da...> - 2004-03-01 08:13:50
|
Helge Hess: > Actually I have written an Objective-C bridge for Python on > GNUstep/libFoundation some five years ago, this was called NGPython. > While it doesn't seem to compile anymore out of the box even on > GNUstep, I thought someone might be interested in ripping of some code > nevertheless. [...] > > So, if someone is interested, drop me a line and I send you the code > ;-) Unfortunately I won't find the time to look at adding the mapping > stuff to PyObjC, but maybe someone else has ... Hi Helge, I think, we've talked to each other some two years ago on the Wocoa People meeting in Berlin, and I tried to pull something out of you at that time, but in vain... Apart from that, it's obviously too late to change the mapping rules without having some *real* advantage... ;-) Regards, Dinu -- Dinu C. Gherman - http://python.net/~gherman ...................................................................... "The best way to predict the future is to invent it." (Alan Kay) |
From: Ronald O. <ous...@ci...> - 2004-03-01 09:23:42
|
On 1-mrt-04, at 9:14, Dinu Gherman wrote: > Helge Hess: > >> Actually I have written an Objective-C bridge for Python on >> GNUstep/libFoundation some five years ago, this was called NGPython. >> While it doesn't seem to compile anymore out of the box even on >> GNUstep, I thought someone might be interested in ripping of some >> code nevertheless. [...] >> >> So, if someone is interested, drop me a line and I send you the code >> ;-) Unfortunately I won't find the time to look at adding the mapping >> stuff to PyObjC, but maybe someone else has ... > > Hi Helge, > > I think, we've talked to each other some two years ago on the > Wocoa People meeting in Berlin, and I tried to pull something > out of you at that time, but in vain... > > Apart from that, it's obviously too late to change the mapping > rules without having some *real* advantage... ;-) Like Bill pointed out the mapping stuff has some real disadvantages, even though they would allow for a nicer API (e.g. without those irritating underscores). IMHO the major problems are documentation and effort. If we would rename methods we would basically render most existing Cocoa documentation useless for Python users, using the current scheme it is easy to use the existing documentation and translate Objective-C code snippets into Python. Maintaining a seperate set of documentation for PyObjC would be a lot of work. Maintaining the mapping would also be a lot of work (and the development would be even more work). PyObjC development is done by a very small group in their spare time, there just isn't enough room to do the additional work that would be required for maintaining the mapping. If someone does have a lot of time to spend on improving the Cocoa <-> Python mapping I'd spend it on trying to find a way to add (an emultation of) segmented method names to Python. Ronald -- X|support bv http://www.xsupport.nl/ T: +31 610271479 F: +31 204416173 |
From: Helge H. <hel...@op...> - 2004-03-01 10:19:44
|
On 01.03.2004, at 10:19, Ronald Oussoren wrote: > IMHO the major problems are documentation and effort. If we would > rename methods we would basically render most existing Cocoa > documentation useless for Python users, using the current scheme it is > easy to use the existing documentation and translate Objective-C code > snippets into Python. Maintaining a seperate set of documentation for > PyObjC would be a lot of work. Good points, yet the "usual" mapping rule is pretty easy to explain and understand and just makes sense. Like if you have an Objective-C method with "With", the "With" denotes keyword arguments (initWithSet:, NSSet(set=)). I don't think this is much more difficult for the regular developer to remember. > Maintaining the mapping would also be a lot of work (and the > development would be even more work). No, not at all. Told from experience ;-) > PyObjC development is done by a very small group in their spare time, > there just isn't enough room to do the additional work that would be > required for maintaining the mapping. Well, I would volunteer to do that. Should be some 2h per MacOSX release (= per year) ;-) Don't forget that you do *not* need to map every single selector from every single class. You only need to map additional selectors and even with those, there can be default mappings. regards, Helge -- http://docs.opengroupware.org/Members/helge OpenGroupware.org |
From: Helge H. <hel...@op...> - 2004-03-01 10:11:56
|
On 01.03.2004, at 09:14, Dinu Gherman wrote: > I think, we've talked to each other some two years ago on the > Wocoa People meeting in Berlin, and I tried to pull something > out of you at that time, but in vain... Hu? I'm pretty sure I sent you the stuff after the Wocoa! (though I never got any feedback, maybe it really went to /dev/null ;-) Its just that this was only for the GNU runtime which probably was uninteresting for you. > Apart from that, it's obviously too late to change the mapping > rules without having some *real* advantage... ;-) Well, I consider that a real advantage for Python focused developers which do not care about Objective-C but only for AppKit. Maybe it even could be an option (beautifulMappingsOn=YES ;-). Anyway, I don't complain. Personally I would love to see the pybridget syntax, but unless someone else with sparetime does as well, we won't see that anyway ;-) best regards, Helge -- http://docs.opengroupware.org/Members/helge OpenGroupware.org |