https://github.com/schani/clojurec
A Clojure implementation on top of C
https://github.com/schani/clojurec
Last synced: 2 months ago
JSON representation
A Clojure implementation on top of C
- Host: GitHub
- URL: https://github.com/schani/clojurec
- Owner: schani
- Created: 2012-06-06T13:24:19.000Z (about 13 years ago)
- Default Branch: master
- Last Pushed: 2018-04-25T22:28:20.000Z (about 7 years ago)
- Last Synced: 2024-10-14T09:35:19.831Z (8 months ago)
- Language: Clojure
- Size: 1.14 MB
- Stars: 922
- Watchers: 77
- Forks: 56
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ClojureC
This is compiler for the Clojure programming language that targets C as a backend. It is based on ClojureScript and was started off ClojureScript's commit `0e0aa7fdd379649bf87f8fff5c6a64e37fe616a4`.
# Status
This project is no longer actively maintained, though PRs and such are still welcome.
# Background, Features, and Limitations
Forked off of a version of ClojureScript circa 2012 (prior to Clojure and ClojureScript being refactored to use the same compiler or front end), ClojureC provides:
* Generation of C or Objective-C code, enabling faster startup than JVM-based executables
Objective-C message sending uses the section character (§) in place of the at-sign (@), as the latter is already used by Clojure.
* Ability to statically expose any C function to ClojureC (dynamic loading might be possible but is not currently implemented)
See **clojurec/binder/**.
* An implementation of the Boehm Garbage Collector (GC)
* Incomplete support for native threads
Exception handling currently uses two global variables (could be replaced with thread-local vars?).
Extending protocols might also not be threadsafe.
* No support for "modern" Clojure language features such as transducers
* No **eval**
* Limited optimization, really only as demanded by the language
For example, **loop**/**recur** is turned into a real loop.
* Exception support
Implemented via **setjmp**/**longjmp**.
# Alternatives to ClojureC
If native threads are not important, but fast startup is, consider using **ClojureScript** instead of ClojureC, as the startup time for the **v8** engine is reportedly much faster than for the JVM.
# Future Plans
As there seem to be few known use cases for programs that need to both start up quickly _and_ use native threading, it is perhaps not surprising that there's little apparent interest in making the necessary changes to "productize" ClojureC. Such changes could include:
* Full support for native threads
* Supporting the latest version of the Clojure language
* Supporting a C++ back end
* Retargeting the GCC compiler back end
* Implementing a proper optimizer
* Providing improved debugger support
Other than (perhaps) full native-thread support, each of the above item would represent a substantial investment of resources that are not, at present, available.
# Historical Info
## Community and Organization
We use a [Trello board](https://trello.com/board/clojurec/500e79c3b8ec5a3d7f1786d1) to keep track of ideas, proposals, TODOs, bugs and who's doing what. If you plan to contribute, please do join the board.
Additional documentation for the project can be found at [the wiki](https://github.com/schani/clojurec/wiki).
## Preparations
### Submodules
ClojureC includes a submodule. To fetch it, do
git submodule init
git submodule update### Dependencies
Before you can run anything make sure you have [GLib 2](http://developer.gnome.org/glib/) and the [Boehm-Demers-Weiser garbage collector](http://www.hpl.hp.com/personal/Hans_Boehm/gc/) installed. If
pkg-config --cflags glib-2.0
pkg-config --cflags bdw-gcdon't report errors you should be good.
Make sure you're using [Leiningen 2](https://github.com/technomancy/leiningen/) - older versions of Leiningen won't work. Run the testsuite:
lein test
All tests should pass.
## Using ClojureC
Note that ClojureC is still in its experimental phase, so please don't expect a polished experience, yet.
### From the command line
ClojureC provides a very simple command line compiler interface. Let's say we want to compile `samples/echo.cljc`:
(ns cljc.user)
(defn -main [& args]
(apply println args))If you do the following in the `clojurec` directory
lein run -c src/cljc/cljc/core.cljc cljc.core run run
lein run -c samples/echo.cljc cljc.user run run
lein run -d cljc.user/-main run
cd run
make -f c/Makefileyou should have a `cljc` executable in the `run` directory that acts mostly like `echo`.
### Objective-C bridge
ClojureC features a very rudimentary Objective-C bridge. Here's an example:
(ns cljc.user
(:require [cljc.objc :as objc]))(extend-type (§ NSString)
ICounted
(-count [self]
(§ self length)))(defn -main [& args]
(let [app (§ (§ NSApplication) sharedApplication)
date (§ (§ NSDate) :dateWithTimeIntervalSinceNow 3600)
locale (§ (§ NSLocale) currentLocale)
desc (§ date :descriptionWithLocale locale)]
(println "Hello, NSApplication: `" desc "` has count " (count desc))))If you have that code in `/tmp/nsdate.cljc`, then this will build and run it:
lein run -c src/cljc/cljc/core.cljc cljc.core run run
lein run -c src/cljc/cljc/objc.cljc cljc.objc run run -m
lein run -c /tmp/nsdate.cljc cljc.user run run -m
lein run -d cljc.user/-main run -m
cd run
makeFor a more involved example, see `samples/ios.cljc`.
### iOS sample app
To build the iOS sample app, do
cd samples
./build-ios.shThe last step will open an XCode project that will build and run the iOS app that `build-ios.sh` compiled from `samples/ios.cljc`.
### From the REPL
The easiest way to play around with ClojureC interactively is in the namespace `clojurec.core-test`. For example:
(core-run '(pr (+ 1 2)))
=> [3]## Mobile Platform Notes
### Android
See the README.md file in "clojurec/run/android".