D on the Objective-C runtime?

Michel Fortin michel.fortin at michelf.com
Sun Sep 6 03:51:34 PDT 2009


On 2009-09-06 06:10:03 -0400, Jacob Carlborg <doob at 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 at michelf.com
http://michelf.com/




More information about the Digitalmars-d mailing list