Hacker News new | comments | show | ask | jobs | submit login
Compile Clojure to Objective-C (github.com)
91 points by dgellow 1297 days ago | hide | past | web | 38 comments | favorite

I took a different tack with clojure-scheme by compiling via Gambit Scheme, which can target Objective-C. https://github.com/takeoutweight/clojure-scheme. This approach made it easier to provide self-hosted compilation, enabling niceties like an on-device repl.

I recently wanted to try out clojure-scheme for a simple Mac OS X or iOS app, but I couldn't easily find an example app that shows how to set up a project to target Objective-C and compile correctly, and what to import to call the Apple frameworks.

Is that even possible? If yes, is there some sort of sample that I didn't see?

The best place to start is actually the scheme iOS repl that comes packaged with the Gambit source. Take a look at the misc/build-gambit-iOS script (mentioned on slide 39,40 of my linked talk slides). It's a bit of a hairy build process (and clojure-scheme only adds more hair into the mix) but once you have the repl working it's easier to see where to slide in the .scm/.m files that clojure-scheme and Gambit generate. Some kind of CMake script would probably ease this pain in setting up all this Xcode stuff.

Check the refactor-fns branch[1] for recent commits.

[1] https://github.com/joshaber/clojurem/tree/refactor-fns

I would be very curious to understand the runtime implications of imposing immutability on an Objective-C program. Presumably porting that was a lot of work.

Many Cocoa classes are immutable (NSString, NSDictionary, NSArray). You can use the mutable versions (i.e. NSMutableString, NSMutableDictionary, NSMutableArray) but there's no reason to if the immutable versions are a better fit for clojurem.

If by runtime implications you mean speed, I think it'd be ok. Objective-C makes heavy use of immutable data structures already, and iPhone apps just don't have that much data, anyway.

I haven't looked at the source, but the avoidance of full copy-on-write, laziness and instrumentation of immutable structures when returning from functions that update / assoc them will be non-trivial to get right. Not even to mention software transactional memory Clojure supports at all.

Immutability in general isn't that big of a deal. The problem is that Clojure uses persistent trees for all datastructures, which will trigger alot of retain/release calls. Other than some RC overhead, it should work just fine. A GC would be ideal however.

Using mutable data structures is pretty easy in clojure, I'm going to dig around and see how they handle this.

Last commit a year ago, unfortunately.

At least it's open source.

I read somewhere it is kind of impossible to implement Clojure without the JVM...

I would really like to see a Clojure on LLVM project though. Maybe speed won't be better, but memory usage and boot times might.

Implementations already exist for the CLR as well as Python, C, Scheme, and of course JavaScript. LLVM appears to be in the thinking stage still: https://github.com/halgari/clojure-metal

To be fair, nothing but JVM and JavaScript are more than just prototypes.

That's not true. In fact, the CLR port has been around and up to date for years and before ClojureScript.

It's used by no one.

You're not only wrong, but incapable of knowing that.

The only dependency to the JVM would be the advantage of integrating with the Java ecosystem.

When compiling Clojure to native code, you won't be able to use Java libraries, unless the native compiler can also generate native code for .class files.

True, but a Clojure-to-native compiler would be able to use native libraries, which isn't exactely in short supply either.

You are right, the main problem being that those native libraries don't know anything about GC and you are forced to create some form of FFI.


I saw the Xcode requirement but I had hopes it would work on Linux.

It's probably all open source and it's just a matter of resources, right?

Couldn't make it work, but I admit I didn't try very hard. A Makefile would probably help a lot.

Clojure's one real advantage is Java interoperability and it is its biggest single selling point.

You just can code nice and quick in a language much nicer than Java, but easily access all that code from our_stalled_corporate_crap.jar, and package/deploy it the way they do it in their Java EE world.

Clojure outside Java ecosystem makes no sense.

Persistent datastructures, STM, CAS concurrency primitives and hygenic macros make no sense outside of the JVM? Please...

Clojure has host language interop, this isn't necessarily the same as Java interop. It would be very nice to write an iOS app using Clojure for instance.

There are at least two alternatives to ClojureM; iOS7 runs js directly so ClojureScript can be used with a certain amount of fiddling. There is also a method of compiling Java into objective-c that is built into the Clojure Nightcode IDE. I ran some basic experiments over the holidays and both methods work, although there are inevitable trade offs.

I'd be delighted for a version of Clojure that both drops the JVM and can bind easily with C.

One of Clojure's big advantages is that it uses the JVM. One of Clojure's big disadvantages is... that it uses the JVM.

Another point is that one have to write a runtime, while Clojure "delegates" almost everything to JRE.

Clojure is a very clever scripting language for JRE.)

I think that it is good idea to marry Arc and Golang in the same way.)

Nitpic: Clojure delegates most things to the VM. The subtle difference that it works just fine on JS engines and CLR.

Arc and Golang would not be a good idea. I'm not trying to be overly negative, but Arc does have it's issues, the main thing being that Arc does not always work, meaning you would need some tool to hunt down leaks. RC is also slower than GC for several reasons, and when you require a runtime anyway for goroutines, you might as well include a GC, especially since Go can have a precise GC.

So, just out of curiosity, how would you even begin planning such a task? Let's say you want to do something simple, like an analogue clock app that takes minimal user input (maybe a few look and feel settings). How would you structure that in Clojure in general, and Clojure-for-iOS in particular?

I would store application state in a atomic reference, and have "time" be updated every second by a timer. I would add a watch to the application state, so that every time application state changes, the UI is re-drawn. At least that's how I do most UI-apps in ClojureScript (re-draw auto magically when state changes).

You'd do the same in Clojure-for-iOS. Of course, since you rely on Apples SDK for UI, you would use interop to subclass whatever needs subclassing, but the principle remains the same.

Something I couldn't have in principle with Common Lisps? Plus predictable and controllable native code generation, efficient zero-copy FFI, come on.)

And, you know, except for reader macros, Haskell..) Let's take it easy - I am familiar with the concepts Clojure is based upon.

You could have that in principle in any language. In Clojure it's built-in and idiomatic.

Besides, there are people who prefer Clojure over Common Lisp and Scheme. You asked why anyone would want Clojure without the JVM, I just told you there are many benefits, especially if your prefered language already is Clojure.

Haskell really is something entirely diffrent than Clojure. Staticly typed, monads, template haskell. It's a nice language, but not as easy to use as Clojure IMHO.

Targeting another popular platform, Objective-C with the Apple libraries, makes a lot of sense to me. That, and C#/.NET (which is already a thing with clojure-clr) seem like the obvious candidates.

ClojureCLR has existed for .NET since very early on. ClojureScript also targets javascript. There is also a Clojure on Python and a Clojure on Lua.

At the very least, ClojureCLR and ClojureScript most certainly do make sense.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact