
Clojure-Scheme - llambda
https://github.com/takeoutweight/clojure-scheme
======
julian37
Interesting, this means you can theoretically run Clojure code on the iPhone:

<http://jlongster.com/legacy/scheme-iphone-apps.html>

~~~
gukjoon
This is awesome, but what gives me pause is the part where you have to write a
foreign function interface for every single Carbon API call. Also, I would
assume that Cocoa is completely unavailable when going to C. Is that correct?

I'm very happy to see the multi-platform vision of Clojure becoming closer to
reality. I'm not in the "write once, run everywhere" camp. That goal is a bit
ridiculous, but the choice of VM and the choice of language should be
independent decisions. I like Erlang's VM a lot, but the language itself is
not very nice. When writing iPhone code, I don't want to be forced to use
Objective C.

~~~
jlongster
Every new language/environment has the problem of needing interfaces into the
lower-level system. If this takes off, you can expect the people to build the
FFIs and share them.

If not, usually it's not too difficult to only wrap the calls that you need.
There are also methods for automatically generating FFIs, although that only
works with certain APIs.

Cocoa is definitely accessible from C. Objective-C is just a superset of C, so
if you compile all the generated C files as Obj-C you can write any Cocoa code
you want.

~~~
chc
I think you have it backwards what subsets and supersede are. The subset (C)
by definition does not have everything in the superset (Objective-C), and one
of the crucial features missing is Objective-C's object model and message
passing. This is not intractable (BridgeSupport and the runtime API should be
sufficient), but it will definitely be more work than writing Objective-C
directly.

~~~
jlongster
That's what I said, Objective-C is a superset of C. C is a subset of Obj-C.

You can simply do this (the actual FFI call might be wrong, it's been a
while):

(c-lambda (ptr) void "[___arg1 sendThisMessage:1];")

You can literally code Obj-C straight into it.

------
MatthewPhillips
This is my first exposure to gambit scheme. I just compiled this hello world
(in scheme, not clojure):

    
    
      (define hello-world (lambda () (display "Hello world!") (newline)))
    
      (hello-world)
    

And it compiles to 5mb. Is this the standard library? Can I expect to more
complicated applications to not balloon up in size?

~~~
jlongster
Yes, I assume that's the standard library. It's been a while since I've worked
with Gambit but it's typically very fast, small, and portable. I wouldn't
expect it to balloon.

------
mark_l_watson
Nice idea. I have used Gambit-C over the years when I wanted to use a high
level language and be able to produce small and reasonable fast executables.

One thing not mentioned was the memory use: I bet that the compiled to
Gambit-c and then to a native executable code uses a tiny fraction of the
memory of Clojure running in the JVM. That can be important for some
applications.

~~~
MatthewPhillips
Especially if it gets dead-code elimination like the closure compiler gives
ClojureScript for the Clojure->JS target.

------
radarsat1
This is very cool. I like the idea of compiling to scheme.

Although: 1.1 seconds for clojure repl, 0.8 seconds for gsc-compiled version.
That's actually less of a difference in speed than I'd expected. Not being
very familiar with ClojureScript, is this clojure repl running in the JVM or
in V8?

Edit: on that note, it'd be interesting to compare timing after compiling with
Stalin.

~~~
lukev
It's not clear if the 1.1 seconds figure is from the Clojure repl or the
ClojureScript repl. They're very different.

It says "Clojure" Repl, and in that case it would be running directly on the
JVM.

~~~
babebridou
I wondered, too, so I ran the benchmark on a clojure repl on the JVM on my
desktop, it timed at 1028ms.

~~~
amouat
Unfortunately that doesn't tell us a lot, unless you also do each of the other
timings.

~~~
babebridou
You're right, that was my plan actually, but I got sidetracked by the cygwin
beast, sorry.

I timed the fib(36) function from within a clojurescript repl inside a clojure
jvm repl, and it returned in 86 seconds.

Then I timed the generated js function in a Chrome console with a not-so-minor
modification so it would compile, it returned in 13 seconds. The modification
in question was inlining the generated cljs.core.truth_(predicate) javascript
function.

The orders of magnitude don't lie though - for what it's worth, a recursive
fibonacci implementation in plain java returns in about 125ms (and depending
on jvm warm-up, an array-backed computation is a merry jog of 50 to 300µs, but
that's completely off-topic)

I have yet to setup gambit and clone the clojure-scheme project. I'm really
curious though, I like these 800ms that the author advertises.

------
andrewcooke
really cool, but it would be good to see some real benchmarks (ie warm-up time
for jvm + correct clojure coding with "recur" etc).

also, i wonder how much of clojure is lost through not being able to call down
to java?

~~~
chc
This is based on ClojureScript, which already doesn't have Java as a runtime
dependency.

------
gtani
related (last June)

<http://news.ycombinator.com/item?id=2713463>

------
MatthewPhillips
Do you lose anything by doing this?

~~~
spacemanaki
ClojureScript doesn't have all of Clojure's reference types (just atom, I
think) nor STM (yet?) so yes, you do lose something. I would also guess that
while (fib 36) might be faster, you would see different results for more
realistic programs. Gambit Scheme's garbage collector might not be as strong
as HotSpot, which I gather is quite good for long running apps. ClojureScript
also doesn't have runtime eval, so you lose that too.

For command-line programs, this could be pretty rad, as is ClojureScript on
V8. It's also just cool :)

~~~
technomancy
Also ClojureScript only recently got PersistentVectors; IIUC maps are still
copy-on-write.

~~~
takeoutweight
The above comments are accurate: clojure-scheme lacks everything that
ClojureScript lacks. And clojure-scheme is a month or two behind
ClojureScript, so the new structure sharing persistent vectors haven't been
ported over yet.

