core-modules not on path
This project is pretty cool and promisses interesting ways to use c-libraries within clojure. However:
I'm trying to do my first steps with clojure-scheme, but I keep on stumbling. I get up to the scheme-repl. There every-thing works fine when:
- I work in the root of the git-repo (it fails when working from samples/repl)
- I perform (load "src/cljscm/cljscm/core.scm") instead of (load "cljscm_core") as described in your presentation. Next I can load my sample-program and run it on the repl.
However, when compiling the program I get warnings that symbols of core.scm are missing. So it seems like a (dynamically linked) library of clojure-scheme is not found.
When adding the core.scm on the command-line to the compiler before my own file I get an error about duplicatie symbols ___H_cljscm_2e_core_2f_vec in the core.c file. So the compilation fails.
Any suggestions on how to get further.
Probably the build of the core-library failed, due to the compiler-error mentioned above. So if I apply a manual fix to the C-file, compile it and add the .o file to my project it should work.
Where should I store the .o files, such that the gsc finds them automatically when needed/referred?
By the way, did you also investigate other scheme-to-C compilers (like Chicken)? If so, what are the essential advantages of the Gambit-C compiler?
The long compilation times of Gambit-C, seem like a significant disadvantage to me (especially given the O(n^2) scaling in the number of code-lines can become an issue when porting an existing library with large files.
You can take a look at require in core.cljsm, to get an idea of the simplest-thing-that-could-possibly-work way I implemented a pseudo classpath and library loading. You can see that it uses *classpath* for some paths relative to cwd to look for scm files. The sample/repl project is an example of a project layout that reflects this. At the moment the Clojure-ized "require" stuff only works for interpreting the scm output of clojure-scheme -- though it shouldn't be hard in principle to support loading compiled libraries.
The native code I've gotten working so far, unfortunately, is more on the toy side (i.e. just cljscm.core and one other file) so there wasn't a need for much linking support, namespaces, etc. But again there's nothing technical stopping dynamically loading compiled libs, it's simply a TODO.
As for Gambit vs Chicken, at the time I started I was aware of more literature on cross compiling Gambit for iOS at the time. I gather Chicken does work on iOS too, and you're right, the massive C files are a point against Gambit. However, I think that having access to Gambit's interpreter while iteratively developing and saving compilation for the end of the day makes the slow compile times less of a show stopper.
I digged one step deeper why gambit complains about duplicate definitions. When looking in the core.scm file I notice two different definitions of the following three functions:
- cljscm.core/vec
- cljscm.core/rand
- cljscm.core/rand-int I guess these different definitions are part of the bootstrapping of clojure.core (for example the first cljscm.core/vec definition use conj, while the second definition makes use of persistent collections for speedup).
Removing the second definition from the core.scm file allows the code to pass the gambit-compiler again. So it seems that either:
- the gambit compiler changed and the current version can not handle re-definitions
- the enable-single-host option you used is required (I did not use that one as it slows down compilation)
- my gcc compiler acts different (gcc-4.7 on Debian) from yours g++4.8 on Mac For the time being enable-single-host seems the most likely cause. I will check that one first.
Furthermore I wonder whether you have more benchmark info on the performance. As the results of the three benchmarks in your presentation diverge quite a lot. Did you get performance measures on larger chunks of code?
When turning on --enable-single-host the number of issues/error increases, but all errors are related to the same three redefinitions. So option 1 (I should use an older Gambit-c version) seems the most likely issue, as I don't expect that invalid C becomes valid when moving to g++ or an older compiler.
I work with Gambit v4.7.2 (latest github stable release). What is the version of Gambit you use?