Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] O'Caml <=> Objective-C bridge
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Mike Hamburg <hamburg@f...>
Subject: [Caml-list] O'Caml <=> Objective-C bridge
Greetings to the List!

Having learned ML and several other functional languages in a 
programming class, I decided that it would be nice to be able to 
program in a functional language on my Mac.  I chose caml for various 
reasons, partly because of the clean foreign-function interface.  To 
make the language useful for more than command-line apps, I'm writing a 
bridge between caml and Objective-C (specifically, Cocoa).

I have little experience in caml itself, and so have no intuition about 
idiomatic programming, especially with objects (most of my functional 
experience is in ML).  What I want to know is, what would be a clean 
and idiomatic interface to this bridge on the caml side?

Things that I've been considering in the design:
-- Except by parsing the objective-c header files, you can't know what 
types a function takes and returns, and in particular it may return 
null.  This is especially the case in objective-c because types and 
bindings are dynamic.  As a result, you can't know much about a method 
when calling it from caml other than the number of arguments it takes, 
or even if the object answers it.  (if it doesn't, this should throw an 
exception).
-- You can send messages to nil in objc, and it will return nil.
-- Objective-C uses 32-bit integers, but most methods that use them 
accept and return small numbers.  The current model is to use ints, but 
throw an exception if it overflows... I'll probably add an int32 type 
to the interface as well for those times when this is unacceptable.
-- Common things that would have to go across the interface quite often 
would be NSArray <=> list and NSString <=> string.  These may be 
important enough to warrant special handling.
-- Memory management can be messy.

  I've written the core of the bridge, at least in the caml->objc 
direction, and it works on a hello world program.  The model is to look 
up classes and selectors (essentially methods) by name, and then to 
pass messages to a class or to an object.

It consists of some datatypes and foreign functions in a module:

> module ObjCGlue = struct
> type objcid
> type objcclass
> type objcsel
>
> type cobj = NULL
>     | BOOL of bool
>     | INT of int
>     | CHAR of char
>     | STR of string
>     | FLOAT of float
>     | ID of objcid
>     | SEL of objcsel
>     | CLASS of objcclass
>
>   (* starts up the runtime system, allocates an autoreleasepool *)
>   external _start : unit -> unit = "camlGlueStartup"
>
>   (* returns a selector of the given name. remember those colons! *)
>   external _selNamed : string -> objcsel = "camlGlueStrToSel"
>
>   (* returns a class of the given name, or null if none exists.  
> perhaps should throw an exception instead *)
>   external _classNamed : string -> cobj = "camlGlueStrToClass"
>
>   (* sends a message to an object *)
>   external _message : objcid -> objcsel -> cobj list -> cobj
>       = "camlGlueMessageSend"
>
>   (* invokes a class method *)
>   external _classMethod : objcclass -> objcsel -> cobj list -> cobj
>       = "camlGlueClassMethod"
>
>  (* ... lots convenience functions to make testing easier ... *)
> end;;

Any suggestions would be much appreciated.

Thanks a lot for your time,
Mike Hamburg