Thread: [Pyobjc-dev] Re: [Pythonmac-SIG] pyobjc / cocoa
Brought to you by:
ronaldoussoren
From: Jack J. <Jac...@cw...> - 2002-10-16 13:17:28
|
[I've added pyobjc-dev to the distribution] On Wednesday, October 16, 2002, at 02:28 , Ronald Oussoren wrote: >> Something that is open to discussion, I think, is how to map ObjC >> names to Python names. The current PyObjC code supports two >> compile-time options, object.message_withFoo_(arg1, arg2) and another >> that I forget with even more underscores in there (this mapping is >> ambiguous: it maps to both [object message: withFoo:] and to [object >> message_withFoo:]). The Java-ObjC brigde has simply defined sensible >> static mappings for all names used in Cocoa, and the above would >> probably become something like object.messagewithFoo() or >> object.messageWithFoo(). Python's current method is more flexible, but >> boy does it lead to ugly method names in your code... > > Changing the mapping from Objective-C names to/from Python names is > definitely open for discusion. > > BTW. The current PyObjC no longer supports object.message__withFoo__. I think that what I would like is one static scheme that is the same (or almost the same) as the Java/ObjC naming scheme, plus a fallback scheme (which could be the current message_withFoo_ scheme). There may be a problem here with overloading, though: if I look at AppKitJava there's often multiple ObjC selectors that map to one Java method name, I'm not sure how they handle this, especially in the face of overriding ObjC methods from Java. The static scheme could simply be a Python dictionary (or an NSDictionary, but a Python dictionary is easier to initialize, I guess) that we initialize with Python code, where the Python code is generated by running /Developer/Java/Jobs/*.jobs through a script. Fastest is probably to create both Python->ObjC and ObjC->Python dictionaries. Is it still possible to have two name mapping schemes, where first one is tried and then the other? Or would this wreak havoc now that we have two-way inheritance and such? Hmm, even if that isn't possible we could cop out: if the method name translation routine finds that a certain name isn't in the dictionaries it would simply add it. Or (more cumbersome, but safer) there could be a (Python) API MapObjCSelector('message:withFoo', 'messageWithFoo') which could then also check that this mapping doesn't conflict with another one. With such a scheme the Python programmer would have to declare any new ObjC messages it uses, but the question is how often this will happen. -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: tmk <li...@ne...> - 2002-10-16 21:38:09
|
Yo, FWIW, after reading all the proposals re: the method syntax. and writing some (a little) Python Cocoa code, I'm getting the strong feeling that I'd definitely go for bbum's suggestion to stay with the current "_" based naming convention. > object.message_withFoo_(arg1, arg2) It may not be the prettiest but after some testing, this syntax proved to be the easiest-to-understand and to map CORRECTLY with its ObjC counterparts (e.g. when I read.messageWithFoo(arg1, arg2) I found that I tend to expect only one argument (withFoo) while the underscore make it clear there are two of them and in what order). Besides I remember how the ObjC syntax eventually made sense to me. It was after I read the following recipe: "there are as many parameters to a message as they are colons in its name". My litmus test for the syntax choice: "explain the mapping mechanism unambiguously in one sentence". "replace the underscores in the python method name by colons and you'll get the name of the original ObjC method" (Btw, is this the reason why there's hardly any doc with the PyObjC 0.7.0 package ;-) Wow. And again so many thanks and kudos to Ronald, Bill et al for this incredible tool. Today I wrote my first real Cocoa app (other than those in the tutorials I've read) in python in a couple of hours. This is all IMHO and just my .02 euros. = tmk = On Wednesday, Oct 16, 2002, at 10:54 Europe/Brussels, Jack Jansen wrote: > > On Wednesday, October 16, 2002, at 09:45 , Just van Rossum wrote: > >> Seth Delackner wrote: >> >>> To expand on my previous comment in a different direction, why not: >>> >>> rt = pyobjc.runtime >>> >>> rt.call(obj, "message", "arg1name", arg1value, "arg2name", >>> arg2value); >>> Which would directly map to: >>> [obj message arg1name:arg1value arg2name:arg2value]; >>> although I'll be the first to admit I have no idea how to actually >>> affect that transform. >> >> I still know very little about ObjC, let alone pyobjc, but in my >> ideal would be >> something like: >> >> obj.message(arg1name=arg1value, arg2name=arg2value) > > There's a fundamental problem with this: the "argnames" are really > part of the Objective C method name. I.e. if you see a call [object > message: arg1 withFoo: arg2] you should think of "message:withFoo:" as > the method name, *not* of "message:" as the message name and > "withFoo:" as the name of an optional argument. > > Within the ObjC environment the three methods [object message], > [object message: arg1] and [object message: arg1 withFoo: arg2] have > absolutely no relationship to each other. Trying to unify these is > going to lead to some very ugly code at some point. For instance, how > would you override "message:withFoo:" in a Python object subclassed > from an ObjC object without overriding "message:"? > > ObjC picked the "interspersed method names" (there's probably an > official term for this) up from Smalltalk. And, incidentally, ABC, > Python's predecessor, had this same syntax but it's one of the many > things from ABC that Guido dropped for Python. > > Something that is open to discussion, I think, is how to map ObjC > names to Python names. The current PyObjC code supports two > compile-time options, object.message_withFoo_(arg1, arg2) and another > that I forget with even more underscores in there (this mapping is > ambiguous: it maps to both [object message: withFoo:] and to [object > message_withFoo:]). The Java-ObjC brigde has simply defined sensible > static mappings for all names used in Cocoa, and the above would > probably become something like object.messagewithFoo() or > object.messageWithFoo(). Python's current method is more flexible, but > boy does it lead to ugly method names in your code... > -- > - Jack Jansen <Jac...@or...> > http://www.cwi.nl/~jack - > - If I can't dance I don't want to be part of your revolution -- Emma > Goldman - > > > _______________________________________________ > Pythonmac-SIG maillist - Pyt...@py... > http://mail.python.org/mailman/listinfo/pythonmac-sig > |
From: Ronald O. <ous...@ci...> - 2002-10-16 14:42:10
|
On Wednesday, Oct 16, 2002, at 15:17 Europe/Amsterdam, Jack Jansen wrote: > > I think that what I would like is one static scheme that is the same > (or almost the same) as the Java/ObjC naming scheme, plus a fallback > scheme (which could be the current message_withFoo_ scheme). There may > be a problem here with overloading, though: if I look at AppKitJava > there's often multiple ObjC selectors that map to one Java method > name, I'm not sure how they handle this, especially in the face of > overriding ObjC methods from Java. I agree that using the naming scheme as from the Java-Cocoa bridge would be usefull. Making up yet another naming scheme would be IMHO be unwise, if only because this would make it very hard to find documentation. W.R.T. mapping multiple selectors onto the same java method in the Java bridge: I suppose these are selectors that are logically 1 method with a number of default arguments, and the ones with less arguments probably call the ones with more arguments: [object foo] -> [object fooWithArg:nil andNum:nil] [object fooWithArg:arg] -> [object fooWithArg:arg andNum:nil] [object fooWithArg:arg andNum:arg2] > > The static scheme could simply be a Python dictionary (or an > NSDictionary, but a Python dictionary is easier to initialize, I > guess) that we initialize with Python code, where the Python code is > generated by running /Developer/Java/Jobs/*.jobs through a script. > Fastest is probably to create both Python->ObjC and ObjC->Python > dictionaries. I was thinking along the same lines. The actual datastructure should be hidden, you'd just call a global function in the objc module to map an Objective-C selector on a Python method name. > > Is it still possible to have two name mapping schemes, where first one > is tried and then the other? Or would this wreak havoc now that we > have two-way inheritance and such? Having two mapping scheme's is not really a problem. That is, unless you want to be able to access a method using both mapping schemes at the same time. The current code does something like the code below while creating a proxy class for and objective-C class: def map_selector(sel): return sel.replace(':', '_') def make_methods(ocClass, clsDict): for meth in ocClass.methods(): clsDict[map_selector(meth.selector)] = wrapMethod(meth) The proxy class is created once including all methods. There is some additional code that recalculates the class dict whenever the method list of the Objective-C class changes. This may happen when loading a bundle that defines additional categories for existing classes. It would be fairly easy to replace the 'map_selector' function by a function that first does a lookup in a translation table. IMHO it is highly unlikely that users define completely new selectors in Python, other than new actions for use in Interface Builder, and I already have written a module that reads the classes.nib from a .NIB 'file' and creates a python module containing the corresponding python classes. Using names without underscores for IBActions is therefore very easy. Ronald |
From: Ronald O. <ous...@ci...> - 2002-10-16 14:49:22
|
To reply to myself... Another mapping scheme would be to just drop the colons and translate the character just beyond colons to uppercase. This would make the python methodnames more pleasant, although still long and 'foreign looking': [obj setObject:value forKey:key] -> obj.setObjectForKey(value, key) Ronald |
From: Jack J. <Jac...@cw...> - 2002-10-16 15:25:04
|
On Wednesday, October 16, 2002, at 04:49 , Ronald Oussoren wrote: > To reply to myself... > > Another mapping scheme would be to just drop the colons and translate > the character just beyond colons to uppercase. This would make the > python methodnames more pleasant, although still long and 'foreign > looking': > > [obj setObject:value forKey:key] -> obj.setObjectForKey(value, key) I think the bottom line is: which method makes it easiest to write Python code given Apple's documentation? I must say I haven't looked at the Java Cocoa documentation (actually, I tend to read the ObjC header files mostly) but if that is good then I think we should stick with the Java names. If it isn't good (or nonexistent:-) then an algorithmic name translation scheme is probably best. Something else that might be worthwhile is a helper command that translates ObjC calls to Python. You would then copy [obj setObject: value forKey: key], paste it in your Python script (where it will stay selected) and select the "ObjC methodcall to Python" command to turn it into obj.setObjectForKey(value, key). The only question is how we could get this into Project Builder (into the Python IDE would be easy). -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: <bb...@ma...> - 2002-10-16 15:43:55
|
A brief followup to my previous email: Doing such a mapping is ultimately a Very Bad Idea. While it makes reading PyObjC code easier from the perspective of a Python programmer, it seriously hampers the efforts of a programmer coming to the environment from an ObjC background. Making messaging across the bridge transparent is paramount. Making it syntactically transparent will cause problems both in maintenance and in coding efficiency. The Java bridge should not be used as a model of "how to do things right". It is a painful, painful thing to use. As well, the pure Java version of Foundation, EO, and WebObjects provide a great deal of evidence that trying to map the Objective-C syntax into a Java or Python-like (because, in reality, Java's and Python's method invocation syntax is fairly identical) leads to a lot of confusion. Even to this day, developers that have spent years working against the pure Java version of Foundation hesitate for a second when dealing with methods like setObjectForKey() -- some of the longer methods are even worse. As ugly as it is, there is a hell of a lot of value in preserving the ObjC method naming semantics on the Python side of the bridge. We have been down this path before -- in the ObjC [WebScript and its "new style" syntax] realm, in the Java realm with the bridge and pure Java implementations of Foundation, etc., and in the Python realm (this discussion has come up in the context of PyObjC on a regular basis since the project's inception so many years ago. b.bum On Wednesday, October 16, 2002, at 11:25 AM, Jack Jansen wrote: > On Wednesday, October 16, 2002, at 04:49 , Ronald Oussoren wrote: >> To reply to myself... >> >> Another mapping scheme would be to just drop the colons and translate >> the character just beyond colons to uppercase. This would make the >> python methodnames more pleasant, although still long and 'foreign >> looking': >> >> [obj setObject:value forKey:key] -> obj.setObjectForKey(value, key) > > I think the bottom line is: which method makes it easiest to write > Python code given Apple's documentation? I must say I haven't looked > at the Java Cocoa documentation (actually, I tend to read the ObjC > header files mostly) but if that is good then I think we should stick > with the Java names. If it isn't good (or nonexistent:-) then an > algorithmic name translation scheme is probably best. > > Something else that might be worthwhile is a helper command that > translates ObjC calls to Python. You would then copy [obj setObject: > value forKey: key], paste it in your Python script (where it will stay > selected) and select the "ObjC methodcall to Python" command to turn > it into obj.setObjectForKey(value, key). The only question is how we > could get this into Project Builder (into the Python IDE would be > easy). > -- > - Jack Jansen <Jac...@or...> > http://www.cwi.nl/~jack - > - If I can't dance I don't want to be part of your revolution -- Emma > Goldman - > > > > ------------------------------------------------------- > This sf.net email is sponsored by: viaVerio will pay you up to > $1,000 for every account that you consolidate with us. > http://ad.doubleclick.net/clk;4749864;7604308;v? > http://www.viaverio.com/consolidator/osdn.cfm > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev > b.bum Are you laughing? ... they are. |
From: Michael J. B. <mj...@um...> - 2002-10-18 15:16:00
|
On Wednesday, October 16, 2002, at 04:25 PM, Jack Jansen wrote: > Something else that might be worthwhile is a helper command that > translates ObjC calls to Python. You would then copy [obj setObject: > value forKey: key], paste it in your Python script (where it will stay > selected) and select the "ObjC methodcall to Python" command to turn it > into obj.setObjectForKey(value, key). The only question is how we could > get this into Project Builder (into the Python IDE would be easy). Sounds like a nice thing to do as a service or as a script. Getting it into Project Builder is then automatic. Since I don't know how to write a service, I wrote a basic AppleScript for that. And I do mean basic: testing was minimal, nested method calls aren't handled correctly, and string arguments containing ":" will cause big problems. But, it's a starting point which someone might find useful, and doing it correctly would basically require a mini-parser for Objective-C, which there's no way I'm going to write in AppleScript! ;) Might be quite nice done in Python using Plex, though. If anyone is interested in using it, copy the Objective C method call you want to convert, then run this script. The text will be converted to a Pythonic method call on the clipboard, which you can paste as usual. Be careful of spurious line breaks in the script when you first save it. Here it is: on run -- get an Objective C message from the clipboard set objcText to the clipboard if objcText starts with "[" and objcText ends with "]" then set objcText to items 2 through -2 of objcText as string end if set the tokens to split of the objcText at ":" set objectName to the first word of the first item of the tokens set methodName to {second word of the first item of the tokens} set methodArgs to {} repeat with tok in items 2 through -2 of tokens set namePiece to the last word of the tok copy namePiece to the end of the methodName copy (items 1 through -(1 + (length of namePiece)) of tok as string) to the end of methodArgs end repeat copy last item of tokens to the end of methodArgs --return {tokens, objectName, methodName, methodArgs} set the clipboard to objectName & "." & (join of methodName by "_") & "(" & (join of methodArgs by ",") & ")" end run on split of str at delim set oldTIDs to the text item delimiters of AppleScript set the text item delimiters of AppleScript to delim set tokens to the text items of the str set the text item delimiters of AppleScript to oldTIDs return the tokens end split on join of tokens by delim set oldTIDs to the text item delimiters of AppleScript set the text item delimiters of AppleScript to delim set str to the tokens as string set the text item delimiters of AppleScript to oldTIDs return the str end join |
From: <bb...@ma...> - 2002-10-16 15:54:06
|
This has not been my experience. In using the bridge, I define completely new selectors on the python side all the time as I refractor and generalize my code. As well, I'm defining new selectors as targets of Timers, Notifications, and certain kinds of delegation (sheet call back methods, as an example). These all have relatively predictable signatures, but the selector names tend to be unique inventions of my projects. In other words, I'm doing with the PyObjC bridge the exact same kind of development that I-- and the rest of the ObjC development community-- have done with ObjC for the last decade. b.bum On Wednesday, October 16, 2002, at 10:39 AM, Ronald Oussoren wrote: > IMHO it is highly unlikely that users define completely new selectors > in Python, other than new actions for use in Interface Builder, and I > already have written a module that reads the classes.nib from a .NIB > 'file' and creates a python module containing the corresponding python > classes. Using names without underscores for IBActions is therefore > very easy. |
From: <bb...@ma...> - 2002-10-16 15:35:01
|
(Jack; thanks for the CC to pyobjc. I have now subscribed to pythonmac and will try to keep up with things in this SIG.) First, a brief update on the progress made on the PyObjC project. The module itself is now compatible with the Apple supplied build of Python 2.2. At this point, the developer can create a new project in Project Builder, select "Cocoa-Python Application" (a custom template included with PyObjC), and Project Builder will create a new Cocoa application project that is implemented entirely in Python. The project template includes an implementation for a basic application delegate (NSObject subclass) that includes target/actions, outlets, and notification handling. When the 'install' target is used, the resulting application runs completely standalone on any OS X 10.2 machine without requiring that the user has preinstalled PyObjC or a custom build of Python. In comparison to Cocoa-Java, the PyObjC bridge is significantly less intrusive. More on this below. In comparison to Cocoa-AppleScript (AppleScript Studio), the PyObjC bridge presents a development experience that is much closer to pure Cocoa. AppleScript Studio is really a mix of Cocoa widgets into AppleScript style event handling-- the end result is very powerful, but it isn't Cooca programming. At this point, the PyObjC bridge is being used in several production quality projects/products. I.e. it is working now and working extremely well!! (And, again, a huge note of thanks to Ronald -- his work on the subclassing and method dispatch mechanisms made it all possible.) More information interspersed with Jack's and Ronald's text below. On Wednesday, October 16, 2002, at 09:17 AM, Jack Jansen wrote: > [I've added pyobjc-dev to the distribution] > On Wednesday, October 16, 2002, at 02:28 , Ronald Oussoren wrote: >>> Something that is open to discussion, I think, is how to map ObjC >>> names to Python names. The current PyObjC code supports two >>> compile-time options, object.message_withFoo_(arg1, arg2) and >>> another that I forget with even more underscores in there (this >>> mapping is ambiguous: it maps to both [object message: withFoo:] and >>> to [object message_withFoo:]). The Java-ObjC brigde has simply >>> defined sensible static mappings for all names used in Cocoa, and >>> the above would probably become something like >>> object.messagewithFoo() or object.messageWithFoo(). Python's current >>> method is more flexible, but boy does it lead to ugly method names >>> in your code... >> >> Changing the mapping from Objective-C names to/from Python names is >> definitely open for discusion. >> >> BTW. The current PyObjC no longer supports object.message__withFoo__. We have been down this path a number of times over the six year history of the PyObjC module. In all cases, we have ended up back with the naming conventions that we have now for a number of reasons. Moving from double underbar to single underbar was definitely a win -- made the code easier to read and write. > I think that what I would like is one static scheme that is the same > (or almost the same) as the Java/ObjC naming scheme, plus a fallback > scheme (which could be the current message_withFoo_ scheme). There may > be a problem here with overloading, though: if I look at AppKitJava > there's often multiple ObjC selectors that map to one Java method > name, I'm not sure how they handle this, especially in the face of > overriding ObjC methods from Java. The key value in the PyObjC module is that it provides an ObjC development experience that is about as close to transparent as can be achieved when mapping from one language to another. One of the most frustrating aspects of doing ObjC/Java (the bridge existed back to WebObjects 3.0 in 1997) was because of the mapping of method names. Specifically, the developer effectively had to learn three APIs deeply to be effective -- the ObjC API, the Java SDK APIs, and this weird permutation of the ObjC APIs as presented in Java. End result; the developer is constantly frustrated by constantly having to do the mapping in their heads. Worse, the mapped representation -- the conversion from, say, setObject:forKey: to setObjectForKey() -- loses the emphasis on the number and order of parameters that is emphasized by ObjC's method naming scheme. From personal experience-- both as a developer and a WebObjects training instructor-- I can confidently say that all of the effort that was put into presenting the ObjC API in Java such that it appeared to be a Java API caused a hell of a lot more confusion than it ever perpetuated clarity! Even if it slightly less Python-Pretty, this... mutableDictionary.setObject_forKey_ ( "foo", "bar" ) ... is ultimately easier to read and maintain than this... mutableDictionary.setObjectForKey( "foo", "bar" ) ... for a number of reasons: - the first is immediately recognizable as an ObjC method call. Regardless of how transparent the bridge is, the bridge is there and it does affect behavior. Trying to hide it makes maintenance significantly more expensive and the introduction of new developers into a project harder. (I helped maintain a mixed ObjC<->Java codebase with 500,000+ lines of code for over 3 years. The bridge was the single largest cause of problems in the project -- that it tried to hide the "crossing of the bridge" just confused things.) - the first form preserves the argumentation information as provided by the traditional ObjC method name (setObject:forKey:)-- the developer can easily map between that syntax and the original ObjC method. The second loses that information and the developer can easily assume that the key should be first. This is a huge problem among my development team with WebObjects 5.x -- all of us make this kind of mistake on a regular basis. - the first has the distinct advantage of allowing the developer to *always* be able to deduce the original ObjC method name by simply looking at the code. The developer doesn't have to go follow some random mapping to try and figure out what the ObjC method's name originally was. > Hmm, even if that isn't possible we could cop out: if the method name > translation routine finds that a certain name isn't in the > dictionaries it would simply add it. Or (more cumbersome, but safer) > there could be a (Python) API MapObjCSelector('message:withFoo', > 'messageWithFoo') which could then also check that this mapping > doesn't conflict with another one. With such a scheme the Python > programmer would have to declare any new ObjC messages it uses, but > the question is how often this will happen. Anything that adds more steps to the bridging process is bad. One of the most powerful and valuable aspects of the PyObjC bridge is that it so totally transparent; much more so than CamlBones (doesn't do subclassing), Java<->ObJC (changes the API) and AppleScript<->ObjC (not intended to be transparent at all). The developer is going to be defining new ObjC methods quite often. The current PyObjC module can complete replace ObjC within a Cocoa project. That is, Python is used to create all of the custom classes that one would normally find in a Cocoa project. As such, the developer is writing lots of custom methods that implement the functionality specific to their application. Certainly, there are many cases where the developer is simply overriding existing Cocoa providing functionality. As it is, many of those methods have to be declared such that the bridge can figure out how to do the dispatch. Very unfortunate, in and of itself, but livable. It would be even more unfortunate if every single action method and other custom methods had to be declared, as well! b.bum |
From: Ted H. <Ted...@ub...> - 2002-10-16 19:24:58
|
I apologize for low content ratio of this post, but as a once and (hopefully) future heavy user of the pyobjc bridge, I just wanted to whole-heartedly agree with everything that Bill says in this post. Explicit and straightforward are the way to go. Now that I've delurked temporarily, I also want to take this opportunity to extend a huge thanks to Ronald and Bill for their work on this project. I am really looking forward to getting back to this kind of environment. On Wed, 16 Oct 2002, bb...@ma... wrote: > (Jack; thanks for the CC to pyobjc. I have now subscribed to > pythonmac and will try to keep up with things in this SIG.) > > First, a brief update on the progress made on the PyObjC project. > > The module itself is now compatible with the Apple supplied build of > Python 2.2. > > At this point, the developer can create a new project in Project > Builder, select "Cocoa-Python Application" (a custom template included > with PyObjC), and Project Builder will create a new Cocoa application > project that is implemented entirely in Python. The project template > includes an implementation for a basic application delegate (NSObject > subclass) that includes target/actions, outlets, and notification > handling. > > When the 'install' target is used, the resulting application runs > completely standalone on any OS X 10.2 machine without requiring that > the user has preinstalled PyObjC or a custom build of Python. > > In comparison to Cocoa-Java, the PyObjC bridge is significantly less > intrusive. More on this below. > > In comparison to Cocoa-AppleScript (AppleScript Studio), the PyObjC > bridge presents a development experience that is much closer to pure > Cocoa. AppleScript Studio is really a mix of Cocoa widgets into > AppleScript style event handling-- the end result is very powerful, but > it isn't Cooca programming. > > At this point, the PyObjC bridge is being used in several production > quality projects/products. I.e. it is working now and working > extremely well!! > > (And, again, a huge note of thanks to Ronald -- his work on the > subclassing and method dispatch mechanisms made it all possible.) > > More information interspersed with Jack's and Ronald's text below. > > On Wednesday, October 16, 2002, at 09:17 AM, Jack Jansen wrote: > > [I've added pyobjc-dev to the distribution] > > On Wednesday, October 16, 2002, at 02:28 , Ronald Oussoren wrote: > >>> Something that is open to discussion, I think, is how to map ObjC > >>> names to Python names. The current PyObjC code supports two > >>> compile-time options, object.message_withFoo_(arg1, arg2) and > >>> another that I forget with even more underscores in there (this > >>> mapping is ambiguous: it maps to both [object message: withFoo:] and > >>> to [object message_withFoo:]). The Java-ObjC brigde has simply > >>> defined sensible static mappings for all names used in Cocoa, and > >>> the above would probably become something like > >>> object.messagewithFoo() or object.messageWithFoo(). Python's current > >>> method is more flexible, but boy does it lead to ugly method names > >>> in your code... > >> > >> Changing the mapping from Objective-C names to/from Python names is > >> definitely open for discusion. > >> > >> BTW. The current PyObjC no longer supports object.message__withFoo__. > > We have been down this path a number of times over the six year history > of the PyObjC module. In all cases, we have ended up back with the > naming conventions that we have now for a number of reasons. Moving > from double underbar to single underbar was definitely a win -- made > the code easier to read and write. > > > I think that what I would like is one static scheme that is the same > > (or almost the same) as the Java/ObjC naming scheme, plus a fallback > > scheme (which could be the current message_withFoo_ scheme). There may > > be a problem here with overloading, though: if I look at AppKitJava > > there's often multiple ObjC selectors that map to one Java method > > name, I'm not sure how they handle this, especially in the face of > > overriding ObjC methods from Java. > > The key value in the PyObjC module is that it provides an ObjC > development experience that is about as close to transparent as can be > achieved when mapping from one language to another. One of the most > frustrating aspects of doing ObjC/Java (the bridge existed back to > WebObjects 3.0 in 1997) was because of the mapping of method names. > Specifically, the developer effectively had to learn three APIs deeply > to be effective -- the ObjC API, the Java SDK APIs, and this weird > permutation of the ObjC APIs as presented in Java. > > End result; the developer is constantly frustrated by constantly > having to do the mapping in their heads. Worse, the mapped > representation -- the conversion from, say, setObject:forKey: to > setObjectForKey() -- loses the emphasis on the number and order of > parameters that is emphasized by ObjC's method naming scheme. > > From personal experience-- both as a developer and a WebObjects > training instructor-- I can confidently say that all of the effort that > was put into presenting the ObjC API in Java such that it appeared to > be a Java API caused a hell of a lot more confusion than it ever > perpetuated clarity! > > Even if it slightly less Python-Pretty, this... > > mutableDictionary.setObject_forKey_ ( "foo", "bar" ) > > ... is ultimately easier to read and maintain than this... > > mutableDictionary.setObjectForKey( "foo", "bar" ) > > ... for a number of reasons: > > - the first is immediately recognizable as an ObjC method call. > Regardless of how transparent the bridge is, the bridge is there and it > does affect behavior. Trying to hide it makes maintenance > significantly more expensive and the introduction of new developers > into a project harder. (I helped maintain a mixed ObjC<->Java codebase > with 500,000+ lines of code for over 3 years. The bridge was the > single largest cause of problems in the project -- that it tried to > hide the "crossing of the bridge" just confused things.) > > - the first form preserves the argumentation information as > provided by the traditional ObjC method name (setObject:forKey:)-- the > developer can easily map between that syntax and the original ObjC > method. The second loses that information and the developer can easily > assume that the key should be first. This is a huge problem among my > development team with WebObjects 5.x -- all of us make this kind of > mistake on a regular basis. > > - the first has the distinct advantage of allowing the developer to > *always* be able to deduce the original ObjC method name by simply > looking at the code. The developer doesn't have to go follow some > random mapping to try and figure out what the ObjC method's name > originally was. > > > Hmm, even if that isn't possible we could cop out: if the method name > > translation routine finds that a certain name isn't in the > > dictionaries it would simply add it. Or (more cumbersome, but safer) > > there could be a (Python) API MapObjCSelector('message:withFoo', > > 'messageWithFoo') which could then also check that this mapping > > doesn't conflict with another one. With such a scheme the Python > > programmer would have to declare any new ObjC messages it uses, but > > the question is how often this will happen. > > Anything that adds more steps to the bridging process is bad. One of > the most powerful and valuable aspects of the PyObjC bridge is that it > so totally transparent; much more so than CamlBones (doesn't do > subclassing), Java<->ObJC (changes the API) and AppleScript<->ObjC (not > intended to be transparent at all). > > The developer is going to be defining new ObjC methods quite often. > The current PyObjC module can complete replace ObjC within a Cocoa > project. That is, Python is used to create all of the custom classes > that one would normally find in a Cocoa project. As such, the > developer is writing lots of custom methods that implement the > functionality specific to their application. Certainly, there are > many cases where the developer is simply overriding existing Cocoa > providing functionality. > > As it is, many of those methods have to be declared such that the > bridge can figure out how to do the dispatch. Very unfortunate, in > and of itself, but livable. It would be even more unfortunate if > every single action method and other custom methods had to be declared, > as well! > > b.bum > Visit our website at http://www.ubswarburg.com This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of e-mail transmission. If verification is required please request a hard-copy version. This message is provided for informational purposes and should not be construed as a solicitation or offer to buy or sell any securities or related financial instruments. |
From: Jack J. <Jac...@or...> - 2002-10-16 22:33:01
|
On woensdag, oktober 16, 2002, at 05:34 , bb...@ma... wrote: > We have been down this path a number of times over the six year > history of the PyObjC module. In all cases, we have ended up > back with the naming conventions that we have now for a number > of reasons. Moving from double underbar to single underbar > was definitely a win -- made the code easier to read and write. I'm not convinced yet, but you're getting there:-) You're getting there because you have by far the most experience with this beast, so if you say the _ convention is A Good Thing and everything else leads to madness: okay, proof by authority:-) Also, the point of ObjC-Cocoa programmers moving to Python is a valid one. I'm not convinced yet, though, because I think it depends on the target audience. My first impression when I saw PyObjC code (about 18 months ago) was "UGLY!! UGLY!! UGLY!!", and I immediately stayed away from it for a year. And I've heard of more people with this reaction. So, if we care about winning existing Python programmers over to Cocoa (which I think we should: even though Carbon is going to be around for a long time it'll only be interesting to existing Mac programmers, and Cocoa has the potential to win over unix and windows Python people) we should make sure it looks appealing. Let's try for a political solution. The official mapping is the _ mapping. However, for convenience there are some method names that have an alias. This alias is translated early on (when looking up the method name from Python, or when creating the Python subclass of an ObjC class), and the official name is used from then on. Would this be workable? -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: <bb...@ma...> - 2002-10-16 22:48:31
|
On Wednesday, October 16, 2002, at 06:32 PM, Jack Jansen wrote: > On woensdag, oktober 16, 2002, at 05:34 , bb...@ma... wrote: >> We have been down this path a number of times over the six year >> history of the PyObjC module. In all cases, we have ended up back >> with the naming conventions that we have now for a number of reasons. >> Moving from double underbar to single underbar was definitely a win >> -- made the code easier to read and write. > > I'm not convinced yet, but you're getting there:-) > > You're getting there because you have by far the most experience with > this beast, so if you say the _ convention is A Good Thing and > everything else leads to madness: okay, proof by authority:-) Also, > the point of ObjC-Cocoa programmers moving to Python is a valid one. Let me clarify: I don't necessarily think it is A Good Thing. I'm just convinced that it is better than solutions that involve presenting a significantly mangled API on the other side of the bridge. The current _ based mapping system falls clearly under the KISS principal -- it is simple, slightly ugly, and just works. > > I'm not convinced yet, though, because I think it depends on the > target audience. My first impression when I saw PyObjC code (about 18 > months ago) was "UGLY!! UGLY!! UGLY!!", and I immediately stayed away > from it for a year. And I've heard of more people with this reaction. > So, if we care about winning existing Python programmers over to Cocoa > (which I think we should: even though Carbon is going to be around for > a long time it'll only be interesting to existing Mac programmers, and > Cocoa has the potential to win over unix and windows Python people) we > should make sure it looks appealing. I completely agree (including the UGLY!! part). A part of making it appealing is making it easier to work with or more powerful than working with the existing compiled ObjC based tools. The current model-- though ugly from a traditional python viewpoint-- is easy to work with in that it is very easy to map between Python<->ObjC and it is extremely powerful-- more powerful than straight ObjC-- in terms of both rapid turnaround time and ability to leverage the vast wealth of Python tools/frameworks/libraries that are available. > Let's try for a political solution. The official mapping is the _ > mapping. However, for convenience there are some method names that > have an alias. This alias is translated early on (when looking up the > method name from Python, or when creating the Python subclass of an > ObjC class), and the official name is used from then on. Would this be > workable? (I would also like to see effort invested in making the ObjC classes behave like proper Python classes where possible and vice-versa. For example, would it be possible to pass things of type PyDict across the bridge from Python->ObjC such that they behave like a subclass of NSMutableDictionary? I think so, but am not sure.) As much as I have been extremely vocal in my opinions on this subject, I'm also a very reasonable solution. As long as the underlying system remains as transparent and workable-- though UGLY!!-- as it currently is, I'm all for changes that will attract a larger audience. At the same time, I don't want to see the [somewhat limited] developer resources devoted to fixing problems that don't exist or to providing solutions that, in the end, no one will use. The Java bridge almost falls into the latter category -- almost in that there are a handful of developers that have either stuck with it or need to use it to access Java only functionality. If you look at the cocoa-dev mailing list archive, there is a boatload of posts from people that started with the Java/Cocoa APIs, worked with it for a while, and either gave up or picked up ObjC. Of those that picked up ObjC, they have become some of the most vocal proponents of the language! There are really two problems here: One of marketing, one of a technical nature. On the marketing side, if providing a layer on top of the existing PyObjC system will make it more palatable to a larger degree of Python programmers, there is certainly value within doing so! I do feel strongly that most programmers that come through this route will eventually find themselves using the '_' notation more and more often for three key reason; it immediately indicates where the bridge is crossed (which, regardless of the transparency of the bridge, that the bridge has been crossed is important), reduces maintenance costs over time, and provides the maximum interoperability between Python and ObjC with the least amount of effort. On the technical side... well, you know my feelings on the technical side -- that has been what the thread has focused on! b.bum |
From: tmk <li...@ne...> - 2002-10-17 00:35:26
|
On Thursday, Oct 17, 2002, at 00:32 Europe/Brussels, Jack Jansen wrote: > > On woensdag, oktober 16, 2002, at 05:34 , bb...@ma... wrote: >> We have been down this path a number of times over the six year >> history of the PyObjC module. In all cases, we have ended up back >> with the naming conventions that we have now for a number of reasons. >> Moving from double underbar to single underbar was definitely a win >> -- made the code easier to read and write. > > I'm not convinced yet, but you're getting there:-) > > You're getting there because you have by far the most experience with > this beast, so if you say the _ convention is A Good Thing and > everything else leads to madness: okay, proof by authority:-) Also, > the point of ObjC-Cocoa programmers moving to Python is a valid one. Yes on both counts. That's exactly what encouraged to actually try and write some code using the alternative syntax. And indeed, soon enough it so happens that the "_" notation just "grew" on me and became quite natural. I think it's because it "reads" effortlessly, whereas I needed to pause and decipher the innercased notation. > I'm not convinced yet, though, because I think it depends on the > target audience. My first impression when I saw PyObjC code (about 18 > months ago) was "UGLY!! UGLY!! UGLY!!", and I immediately stayed away > from it for a year. And Funny. Same here. But that was the notation with the double underscore (if memory serves I even de-lurked at that time just to say that I felt the syntax looked really UGLY ;-). But with one underscore, as said previously, it makes a lot of sense to me (much more than the alternatives anyway). One other thing, A paradox, I tend to dislike using underscores when I write "regular" python code. I prefer using InnerCased (?) style. Funny brain. > I've heard of more people with this reaction. So, if we care about > winning existing Python programmers over to Cocoa (which I think we > should: even though Carbon is going to be around for a long time it'll > only be interesting to existing Mac programmers, and Cocoa has the > potential to win over unix and windows Python people) we should make > sure it looks appealing. > Let's try for a political solution. The official mapping is the _ > mapping. However, for convenience there are some method names that > have an alias. This alias is translated early on (when looking up the > method name from Python, or when creating the Python subclass of an > ObjC class), and the official name is used from then on. Would this be > workable? Looks like a reasonable compromise. But I suspect (based on my humble experience) that most people will eventually use the "_" naturally (same as C programmers who first don't want to learn ObjC and then fall in love with it ;-) = tmk = > -- > - Jack Jansen <Jac...@or...> > http://www.cwi.nl/~jack - > - If I can't dance I don't want to be part of your revolution -- Emma > Goldman - > > > > ------------------------------------------------------- > This sf.net email is sponsored by: viaVerio will pay you up to > $1,000 for every account that you consolidate with us. > http://ad.doubleclick.net/clk;4749864;7604308;v? > http://www.viaverio.com/consolidator/osdn.cfm > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev > |
From: tmk <tm...@ma...> - 2002-10-17 00:28:43
|
On Thursday, Oct 17, 2002, at 00:32 Europe/Brussels, Jack Jansen wrote: > > On woensdag, oktober 16, 2002, at 05:34 , bb...@ma... wrote: >> We have been down this path a number of times over the six year >> history of the PyObjC module. In all cases, we have ended up back >> with the naming conventions that we have now for a number of reasons. >> Moving from double underbar to single underbar was definitely a win >> -- made the code easier to read and write. > > I'm not convinced yet, but you're getting there:-) > > You're getting there because you have by far the most experience with > this beast, so if you say the _ convention is A Good Thing and > everything else leads to madness: okay, proof by authority:-) Also, > the point of ObjC-Cocoa programmers moving to Python is a valid one. Yes on both counts. That's exactly what encouraged to actually try and write some code using the alternative syntax. And indeed, soon enough it so happens that the "_" notation just "grew" on me and became quite natural. I think it's because it "reads" effortlessly, whereas I needed to pause and decipher the innercased notation. > I'm not convinced yet, though, because I think it depends on the > target audience. My first impression when I saw PyObjC code (about 18 > months ago) was "UGLY!! UGLY!! UGLY!!", and I immediately stayed away > from it for a year. And Funny. Same here. But that was the notation with the double underscore (if memory serves I even de-lurked at that time just to say that I felt the syntax looked really UGLY ;-). But with one underscore, as said previously, it makes a lot of sense to me (much more than the alternatives anyway). One other thing, A paradox, I tend to dislike using underscores when I write "regular" python code. I prefer using InnerCased (?) style. Funny brain. > I've heard of more people with this reaction. So, if we care about > winning existing Python programmers over to Cocoa (which I think we > should: even though Carbon is going to be around for a long time it'll > only be interesting to existing Mac programmers, and Cocoa has the > potential to win over unix and windows Python people) we should make > sure it looks appealing. > Let's try for a political solution. The official mapping is the _ > mapping. However, for convenience there are some method names that > have an alias. This alias is translated early on (when looking up the > method name from Python, or when creating the Python subclass of an > ObjC class), and the official name is used from then on. Would this be > workable? Looks like a reasonable compromise. But I suspect (based on my humble experience) that most people will eventually use the "_" naturally (same as C programmers who first don't want to learn ObjC and then fall in love with it ;-) = tmk = > -- > - Jack Jansen <Jac...@or...> > http://www.cwi.nl/~jack - > - If I can't dance I don't want to be part of your revolution -- Emma > Goldman - > > > > ------------------------------------------------------- > This sf.net email is sponsored by: viaVerio will pay you up to > $1,000 for every account that you consolidate with us. > http://ad.doubleclick.net/clk;4749864;7604308;v? > http://www.viaverio.com/consolidator/osdn.cfm > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev > |