From: Mike Hamburg <hamburg@fas.harvard.edu>
To: caml-list@inria.fr
Subject: [Caml-list] O'Caml <=> Objective-C bridge
Date: Mon, 19 Apr 2004 21:10:29 -0400 [thread overview]
Message-ID: <836F0A79-9267-11D8-806B-0003939A19AA@fas.harvard.edu> (raw)
[-- Attachment #1: Type: text/plain, Size: 3224 bytes --]
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
[-- Attachment #2: Type: text/enriched, Size: 3244 bytes --]
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:
<excerpt>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;;<color><param>0000,6363,1212</param>
</color></excerpt>
Any suggestions would be much appreciated.
Thanks a lot for your time,
Mike Hamburg
reply other threads:[~2004-04-20 1:02 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=836F0A79-9267-11D8-806B-0003939A19AA@fas.harvard.edu \
--to=hamburg@fas.harvard.edu \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).