digitalmars.D - D on the Objective-C runtime?
- Jacob Carlborg (8/8) Sep 06 2009 I've been thinking for a while what it would take to get D running on
- Michel Fortin (74/82) Sep 06 2009 It certainly could be done, but first you'd need a way to handle the
- Jacob Carlborg (14/86) Sep 06 2009 I was thinking you sill have to create bindings and use objc_msgSend and...
- Michel Fortin (18/66) Sep 06 2009 That doesn't scale very well. Overloading allows both "foo(int arg1,
- Jacob Carlborg (2/64) Sep 06 2009 Yeah, perhaps you're right, I was just thinking out loud.
- Christopher Wright (5/17) Sep 06 2009 Off topic, but this would be a good place for user-defined attributes.
- Michel Fortin (15/19) Sep 06 2009 Indeed... although IBAction isn't so bad as a mixin, it gets much worse
- Jacob Carlborg (9/24) Sep 06 2009 That is actually not necessary. It would be sufficient with a template
I've been thinking for a while what it would take to get D running on the Objective-C runtime, in other words a D object will actually be an objc object, kind of like MacRuby but for D. How difficult it would be, how much work, what needs to change, both the runtime and the compiler? And if it would be worth the trouble. The reason for this is to make it easier to interface with Mac OS X system libraries like Cocoa. /Jacob Carlborg
Sep 06 2009
On 2009-09-06 06:10:03 -0400, Jacob Carlborg <doob me.com> said:I've been thinking for a while what it would take to get D running on the Objective-C runtime, in other words a D object will actually be an objc object, kind of like MacRuby but for D. How difficult it would be, how much work, what needs to change, both the runtime and the compiler? And if it would be worth the trouble. The reason for this is to make it easier to interface with Mac OS X system libraries like Cocoa.It certainly could be done, but first you'd need a way to handle the differences between Objective-C and D methods: - Objective-C methods are of the form "setObject:forKey:", which is difficult to map to D. - Objective-C methods do not support overloading. - Objective-C class methods (equivalent to D static member functions) are "virtual", this is used within Cocoa - Objective-C 2.0 allows a default method implementation in protocols (equivalent to D interfaces). - Templates, exceptions? If all you wanted was to make D work using the Objective-C runtime (with overloading), you could apply some special name mangling rules, but that would make it pretty incompatible with anything really in Objective-C. On the other side, you could change the D method syntax to disallow overloading, use that colon-separated-multiple-part syntax, depend on static methods being "virtual" (this pattern is used at some places in Cocoa) and add the capability to interfaces to have default implementations. but then it wouldn't really be D. Another approach is my D/Objective-C bridge: <http://michelf.com/projects/d-objc-bridge/>, which allows you to write a bridged class like below. It needs D1 and is not multithreaded, only can do classes (no protocols, no categories for now), but it works quite well for what it does. class AppController : NSObject { /** Counter for window title in openWindow. */ uint windowCount; this() { super(); } /** Open this application's website. */ void openWebsite(Object sender) { auto a = NSAlert.alert("Cannot open web site.", "OK", null, null, "The D/Objective-C bridge doesn’t have access to NSWorkspace yet, " "so we cannot open a website. Displaying an alert works though. ;-)"); a.runModal; } /** Open a new window and put it on the center of the screen. */ void openWindow(Object sender) { auto window = new NSWindow(NSMakeRect(20, 20, 300, 200), NSTitledWindowMask + NSClosableWindowMask + NSMiniaturizableWindowMask + NSResizableWindowMask, NSBackingStoreType.BUFFERED, false); window.title = "untitled "~ std.string.toString(++windowCount); window.center(); window.makeKeyAndOrderFront(this); } // Objective-C binding for IB actions. mixin IBAction!(openWindow); mixin IBAction!(openWebsite); // Overrides from NSApplication delegate. bool openUntitledFile(NSApplication sender) { openWindow(sender); return true; } bool shouldTerminateAfterLastWindowClosed(NSApplication sender) { return true; } // Objective-C bindings for the above delegate methods. mixin ObjcBindMethod!(openUntitledFile, bool, "applicationOpenUntitledFile:", NSApplication); mixin ObjcBindMethod!(shouldTerminateAfterLastWindowClosed, bool, "applicationShouldTerminateAfterLastWindowClosed:", NSApplication); } -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Sep 06 2009
On 9/6/09 12:51, Michel Fortin wrote:On 2009-09-06 06:10:03 -0400, Jacob Carlborg <doob me.com> said:I was thinking you sill have to create bindings and use objc_msgSend and friends. Or something like "extern (Objc) void foo (int arg1, int arg2);" would automatically be converted to "objc_msgSend(this, sel_registerName("foo:arg2"), arg1, arg2);".I've been thinking for a while what it would take to get D running on the Objective-C runtime, in other words a D object will actually be an objc object, kind of like MacRuby but for D. How difficult it would be, how much work, what needs to change, both the runtime and the compiler? And if it would be worth the trouble. The reason for this is to make it easier to interface with Mac OS X system libraries like Cocoa.It certainly could be done, but first you'd need a way to handle the differences between Objective-C and D methods: - Objective-C methods are of the form "setObject:forKey:", which is difficult to map to D.- Objective-C methods do not support overloading."void foo (int arg1, int arg2)" could be transformed to "foo:arg2" or similar.- Objective-C class methods (equivalent to D static member functions) are "virtual", this is used within CocoaThis would be a problem.- Objective-C 2.0 allows a default method implementation in protocols (equivalent to D interfaces). - Templates, exceptions?D would use the the objc exceptions and add new exception classes where necessary. Templates would probably be disallowed.If all you wanted was to make D work using the Objective-C runtime (with overloading), you could apply some special name mangling rules, but that would make it pretty incompatible with anything really in Objective-C. On the other side, you could change the D method syntax to disallow overloading, use that colon-separated-multiple-part syntax, depend on static methods being "virtual" (this pattern is used at some places in Cocoa) and add the capability to interfaces to have default implementations. but then it wouldn't really be D.I do not want the colon-separated-multiple-part syntax. I don't want to modify the compiler too much, I sill want it to be D but virtual static methods could be an acceptable modification for example.Another approach is my D/Objective-C bridge: <http://michelf.com/projects/d-objc-bridge/>, which allows you to write a bridged class like below. It needs D1 and is not multithreaded, only can do classes (no protocols, no categories for now), but it works quite well for what it does.Yes I know about your D/objc bridge.class AppController : NSObject { /** Counter for window title in openWindow. */ uint windowCount; this() { super(); } /** Open this application's website. */ void openWebsite(Object sender) { auto a = NSAlert.alert("Cannot open web site.", "OK", null, null, "The D/Objective-C bridge doesn’t have access to NSWorkspace yet, " "so we cannot open a website. Displaying an alert works though. ;-)"); a.runModal; } /** Open a new window and put it on the center of the screen. */ void openWindow(Object sender) { auto window = new NSWindow(NSMakeRect(20, 20, 300, 200), NSTitledWindowMask + NSClosableWindowMask + NSMiniaturizableWindowMask + NSResizableWindowMask, NSBackingStoreType.BUFFERED, false); window.title = "untitled "~ std.string.toString(++windowCount); window.center(); window.makeKeyAndOrderFront(this); } // Objective-C binding for IB actions. mixin IBAction!(openWindow); mixin IBAction!(openWebsite); // Overrides from NSApplication delegate. bool openUntitledFile(NSApplication sender) { openWindow(sender); return true; } bool shouldTerminateAfterLastWindowClosed(NSApplication sender) { return true; } // Objective-C bindings for the above delegate methods. mixin ObjcBindMethod!(openUntitledFile, bool, "applicationOpenUntitledFile:", NSApplication); mixin ObjcBindMethod!(shouldTerminateAfterLastWindowClosed, bool, "applicationShouldTerminateAfterLastWindowClosed:", NSApplication); }
Sep 06 2009
On 2009-09-06 07:52:27 -0400, Jacob Carlborg <doob me.com> said:On 9/6/09 12:51, Michel Fortin wrote:That doesn't scale very well. Overloading allows both "foo(int arg1, int arg2)" and "foo(int arg1, float arg2)" to exist in the same scope, both would become "foo:arg2:".On 2009-09-06 06:10:03 -0400, Jacob Carlborg <doob me.com> said:I was thinking you sill have to create bindings and use objc_msgSend and friends. Or something like "extern (Objc) void foo (int arg1, int arg2);" would automatically be converted to "objc_msgSend(this, sel_registerName("foo:arg2"), arg1, arg2);".I've been thinking for a while what it would take to get D running on the Objective-C runtime, in other words a D object will actually be an objc object, kind of like MacRuby but for D. How difficult it would be, how much work, what needs to change, both the runtime and the compiler? And if it would be worth the trouble. The reason for this is to make it easier to interface with Mac OS X system libraries like Cocoa.It certainly could be done, but first you'd need a way to handle the differences between Objective-C and D methods: - Objective-C methods are of the form "setObject:forKey:", which is difficult to map to D.Yeah, but what if you have foo(int a) and foo(float a)? Then you need some kind of name mangling: foo(int a) becomes - fooInt:(int)a foo(float a) becomes - fooFloat:(int)a and now the two can exist at the same time in the same class.- Objective-C methods do not support overloading."void foo (int arg1, int arg2)" could be transformed to "foo:arg2" or similar.- Objective-C class methods (equivalent to D static member functions) are "virtual", this is used within CocoaThis would be a problem.So now the base exception class is NSException?- Objective-C 2.0 allows a default method implementation in protocols (equivalent to D interfaces). - Templates, exceptions?D would use the the objc exceptions and add new exception classes where necessary. Templates would probably be disallowed.Hum, I think if someone wanted to have Objective-C compatibility it'd be better to just add a different syntax for declaring Objective-C classes than to try to fit them within D classes, much like with Objective-C++. -- Michel Fortin michel.fortin michelf.com http://michelf.com/If all you wanted was to make D work using the Objective-C runtime (with overloading), you could apply some special name mangling rules, but that would make it pretty incompatible with anything really in Objective-C. On the other side, you could change the D method syntax to disallow overloading, use that colon-separated-multiple-part syntax, depend on static methods being "virtual" (this pattern is used at some places in Cocoa) and add the capability to interfaces to have default implementations. but then it wouldn't really be D.I do not want the colon-separated-multiple-part syntax. I don't want to modify the compiler too much, I sill want it to be D but virtual static methods could be an acceptable modification for example.
Sep 06 2009
On 9/6/09 14:18, Michel Fortin wrote:On 2009-09-06 07:52:27 -0400, Jacob Carlborg <doob me.com> said:Yeah, perhaps you're right, I was just thinking out loud.On 9/6/09 12:51, Michel Fortin wrote:That doesn't scale very well. Overloading allows both "foo(int arg1, int arg2)" and "foo(int arg1, float arg2)" to exist in the same scope, both would become "foo:arg2:".On 2009-09-06 06:10:03 -0400, Jacob Carlborg <doob me.com> said:I was thinking you sill have to create bindings and use objc_msgSend and friends. Or something like "extern (Objc) void foo (int arg1, int arg2);" would automatically be converted to "objc_msgSend(this, sel_registerName("foo:arg2"), arg1, arg2);".I've been thinking for a while what it would take to get D running on the Objective-C runtime, in other words a D object will actually be an objc object, kind of like MacRuby but for D. How difficult it would be, how much work, what needs to change, both the runtime and the compiler? And if it would be worth the trouble. The reason for this is to make it easier to interface with Mac OS X system libraries like Cocoa.It certainly could be done, but first you'd need a way to handle the differences between Objective-C and D methods: - Objective-C methods are of the form "setObject:forKey:", which is difficult to map to D.Yeah, but what if you have foo(int a) and foo(float a)? Then you need some kind of name mangling: foo(int a) becomes - fooInt:(int)a foo(float a) becomes - fooFloat:(int)a and now the two can exist at the same time in the same class.- Objective-C methods do not support overloading."void foo (int arg1, int arg2)" could be transformed to "foo:arg2" or similar.- Objective-C class methods (equivalent to D static member functions) are "virtual", this is used within CocoaThis would be a problem.So now the base exception class is NSException?- Objective-C 2.0 allows a default method implementation in protocols (equivalent to D interfaces). - Templates, exceptions?D would use the the objc exceptions and add new exception classes where necessary. Templates would probably be disallowed.Hum, I think if someone wanted to have Objective-C compatibility it'd be better to just add a different syntax for declaring Objective-C classes than to try to fit them within D classes, much like with Objective-C++.If all you wanted was to make D work using the Objective-C runtime (with overloading), you could apply some special name mangling rules, but that would make it pretty incompatible with anything really in Objective-C. On the other side, you could change the D method syntax to disallow overloading, use that colon-separated-multiple-part syntax, depend on static methods being "virtual" (this pattern is used at some places in Cocoa) and add the capability to interfaces to have default implementations. but then it wouldn't really be D.I do not want the colon-separated-multiple-part syntax. I don't want to modify the compiler too much, I sill want it to be D but virtual static methods could be an acceptable modification for example.
Sep 06 2009
Michel Fortin wrote:Another approach is my D/Objective-C bridge: <http://michelf.com/projects/d-objc-bridge/>, which allows you to write a bridged class like below. It needs D1 and is not multithreaded, only can do classes (no protocols, no categories for now), but it works quite well for what it does.<snip>/** Open a new window and put it on the center of the screen. */ void openWindow(Object sender) { } // Objective-C binding for IB actions. mixin IBAction!(openWindow); mixin IBAction!(openWebsite);Off topic, but this would be a good place for user-defined attributes. Then you could write something like: IBAction void openWindow(Object sender) {}
Sep 06 2009
On 2009-09-06 08:32:43 -0400, Christopher Wright <dhasenan gmail.com> said:Off topic, but this would be a good place for user-defined attributes. Then you could write something like: IBAction void openWindow(Object sender) {}Indeed... although IBAction isn't so bad as a mixin, it gets much worse with ObjcMethod where it is necessary to list all the argument types to allow resolving overloaded functions: void doOneAndTwo(int i, int j) {} mixin ObjcMethod(void, doOneAndTwo, "doOne:andTwo:", int, int); Compare to what could be done with a parametrized attribute: ObjcMethod("doOne:andTwo:") void doOneAndTwo(int i, int j); That'd would be a lot more convenient, especially with interfaces for which none of the mixin above can work (they insert some static struct member to store the "attributes"). -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Sep 06 2009
On 9/6/09 15:12, Michel Fortin wrote:On 2009-09-06 08:32:43 -0400, Christopher Wright <dhasenan gmail.com> said:That is actually not necessary. It would be sufficient with a template taking an alias to the method (most of the times). Then you can build a selector string out of the method name and the parameter names. To get the types of the method you can use traits templates/functions available both in phobos and tango. You would probably also need a template taking an alias and a selector string when the above doesn't work. This would work best with new methods when you can control the method and parameter names and not with existing methods.Off topic, but this would be a good place for user-defined attributes. Then you could write something like: IBAction void openWindow(Object sender) {}Indeed... although IBAction isn't so bad as a mixin, it gets much worse with ObjcMethod where it is necessary to list all the argument types to allow resolving overloaded functions: void doOneAndTwo(int i, int j) {} mixin ObjcMethod(void, doOneAndTwo, "doOne:andTwo:", int, int);Compare to what could be done with a parametrized attribute: ObjcMethod("doOne:andTwo:") void doOneAndTwo(int i, int j); That'd would be a lot more convenient, especially with interfaces for which none of the mixin above can work (they insert some static struct member to store the "attributes").
Sep 06 2009