On Apr 3, 2011, at 6:47 PM, John Velman wrote:
I've tinkered with learning scheme off and on for years, but never had enough incentive to stick to it. Now, with Pixie Scheme III, a real programming language implementation, on the iPad, I'm taking another shot at Scheme.
My main computer is an iMac running OS X 10.6.7; My Xcode is 3.2.5; I have the iOS development kit, but haven't yet started any apps for iPad/iPhone. Right now I'm working on a couple of OS X cocoa apps (in addition to coming up to speed on Scheme).
I'd like to be able to do two things with Scheme, hopefully without a lot of difficulty:
- Develop OS X applications in Xcode, using C libraries written in Scheme
for the Model part of MVC, and Cocoa doing the, with Cocoa doing the View-Controller stuff.
Are there any good examples or tutorials available for generating, with Gambit Scheme, C-Library routines that can be copied into an Xcode project and then used with minimum modification to the Xcode project?
- I have an application I'm developing (in Cocoa for OS X) mainly to
explore some math concepts I'm interested in, for my own use. Since it is by nature exploratory, it seems like a good idea to have an extension language. Scheme seems like a good choice.
Are there any good examples or tutorials that would get me started using Gambit to add an embedded extension language to an Xcode project?
---
Googling is frustrating because of so many hits about chess, Xcode schemes, cocoa importing, and so on, but I've tried as many combinations as I can think of. The only thing I've found that is possibly useful is from http://jlongster.com/legacy/scheme-iphone-apps.html, which is stated to be out-of-date, and the link for an up to date reference doesn't work.
I spent a lot of hours a while back getting a Fibonacci generator written in Haskell into a cocoa application. I published this on the Haskell Wiki. The process was so onerous I never tried it again. Hope this isn't also true of Scheme.
It's not particularly hard to write Cocoa apps with Gambit. You have to jump through a few hoops to get your build environment set up appropriately, but once that's done, things are not hard.
There are a couple of ways you can go about it. One is to build the whole app using the Gambit tools. Gambit uses the C compiler underneath to generate machine code. It accepts flags that it passes on to the C compiler, and it can compile inline C code, using the special forms documented as part of the foreign function interface. On Mac OS X, Gambit uses Apple's C compiler, and your inline C code can in fact be Objective-C. You can, for example, write a main program like this:
(c-declare "#include <Cocoa/Cocoa.h>") (c-declare "#include <AppKit/AppKit.h>")
(define cocoa:application-main (c-lambda () int #<<c-code NSApplication *app = [NSApplication sharedApplication]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [NSBundle loadNibNamed: [[[NSBundle mainBundle] infoDictionary] objectForKey: @"NSMainNibFile"] owner: app]; [app run]; [pool release]; ___result = 0; c-code ))
(begin (cocoa:application-main))
A second alternative is to write the main program in Objective-C, and use Gambit to write those parts of the application that are better accomplished in Scheme code. For example, you can write data-handling or application logic in Scheme, compile that code to a library, and then link the library to a UI application written in the normal way with XCode. This is how I implemented my list-handling app, Delectus. It has some advantages, notably that you have the XCode tools for all the things (especially InterfaceBuilder) that are most easily done its way, but at the same time, you have Scheme and its interactive environment for developing and testing the data-handling and application logic.
When working this way, I build the Scheme portion of my app completely independent of the Cocoa UI. It's designed as if Cocoa didn't exist at all, and its only UI is the set of API functions I expose through a C header file. (Those functions are defined in a parallel file full of Gambit c-define forms).
The XCode project that provides the UI is a separate project that simply links the library produced by the Gambit build. Besides making it easy to use Gambit for the non-UI portions of the application, this strategy also has the benefit of localizing problems. With this architecture it's generally easy to tell whether a bug occurs in the UI part of the app or the underlying engine, and when it's in the engine, Gambit's interpreter and interactive tools make debugging pretty easy.
There are two sort of tricky parts to this strategy: first, getting all the pathnames and flags right in your Makefile; and, second, getting the startup code right in your Objective-C main, to initialize the Gambit runtime. For an example of the latter, take a look at the example in the files:
<gambit dist>/tests/ client.c makefile server.h server.scm
There are a lot more details that come up once you've got builds working, but they are just details. For example, passing integers, character, and booleans back and forth between Scheme and Objective-C is easy, but more complex types get more involved. Character strings are not bad, but you have to remember that passing a string from Scheme to C mallocs a new string every time, so you have to be mindful of what happens to that memory. For more complicated structures than strings, you have some work cut out for you figuring out how best to handle them.
--me