Open moob123 opened 10 years ago
Just feel free to ask here. Btw, Clojure-scheme just compiles Clojure to gambit-scheme, and gambit will do the rest.
I have this simple clj script
(ns test)
(defn whatever
)
I could get it compiled into .scm by starting a clj repl and requiring the cljsm compiler. But I cannot get this properly loaded and run from gsc. This is how I tried:
sh run-clojure-repl .. at this point I do not know how to load the core.cljsm. when I do a load ("tmp/hello.scm") I get this: *\ ERROR IN cljscm.core/-invoke, "cljscm/core.cljscm"@163.1 -- Unbound variable: cljscm.core/-invoke---cljscm_core$String
It might be that I could not properly build cljsm core. When I look at the samples/repl directory the cljsm/core.scm is in the "(source-at ..." form - as most other .scm files.
body was a classic (println "hello"), it was swallowed somehow.
The story : we have a larger pricing calculator we build on clojure, compiled into clojure script end embedded into an HTML app. This runs OK on stronger laptop grade machines but takes around 15-20 sec on a tablet. I hoped if we took it to C on iOS, that would make it perform better.
If the repl successfully built as per the project README, the problem is probably that the core lib isn't loaded when running your sample project. We don't have good dependency-chasing/classpath functionality yet, so in the mean time what you can do is manually pull in the core. (Requiring non-core libs via regular ns :require should work though.)
You can see one way of bootstrapping the core in the clojure-repl.scm. You don't need to be that elaborate, as the repl project needs to fiddle with the Gambit repl, as well as set up the self-hosted compiler to macro-expand Clojure macros via clojure-scheme. A simpler way would be to add something like this at the top of your compiled scm file:
(include "cljscm/source-at.scm") ; a scheme macro needed to track original Clojure source line numbers
(load "cljscm/core.scm")
This loads the core via the interpreter, which is generally easiest when you're getting started.
It's still a bit clunky just because there are multiple ways you can group compilation units together, such as splicing all the libs into a single file, vs separate dynamically loading libraries, vs mixing and matching some compiled vs some interpreted. One obvious thing you might want to do is have a precompiled core for better performance. After compiling core.scm with gsc, the second line might then become something like: (load "lib/cljscm/core")
.
Everything is global in Gambit so you only need to pull in the core once at the program entry point.
You'll know its working when you can load your scm file in the gsc interpreter. You can call your Clojure functions from the scheme repl just by namespace expanding them. For example, if you had a file in the test
namespace, your Clojure function (defn hello [] ...)
could be called in gsc via (test/hello)
Please let me know if I've misunderstood your problem and hopefully we can get you on track!
Success: I could print "hello". Thanks for that :). Following your build.clj finally I got this to be included:
(include "../scm/cljscm/source-at.scm")
(load "scm/cljscm/core.scm")
I put this into repl/src to work. I am still in the woods in terms of classpaths, what context (class path) does gsc work in ? Is there a way to print the loaded namespaces like (ns-all) with clojure ? (sorry to ask I browsed but did not find anything yet)
Now that it works in scheme interpreter can you give me some hints how to take it forward to a gambit ios C compiler ? I have the gambit-iOS build. Could you give me some entry points to how to get started with ios gsc compilation of core.scm ? Thanks.
In the meantime I am test compiling some sample codes. Some compilations work fine, but I have some probems. One is:
CAUTION: :as alias must be unique; offending spec: [clojure.set :refer [rename-keys difference]]
Should I take these seriously ? What causes these ?
The other is one of my sources does not compile and I get this from compilation
AssertionError Assert failed: Can't call nil
(not (nil? op)) cljscm.analyzer/analyze-seq (analyzer.clj:1172)
Is there any way to find out where compilation fails ? Thanks.
As it turned out our code used a construct as follows:
(case
...
(nil)
So, in fact we had a '(nil)'. The question is if scheme (compiler) will treat cases right which use this form to check for a member in a list:
;; You can give multiple values for the same condition by putting
;; those values in a list.
user=> (case 'y
(x y z) "x, y, or z"
"default")
"x, y, or z"
I took the above from: http://clojuredocs.org/clojure_core/clojure.core/case.
Thanks.
We tested the (case op, and - sorry for the accents in the sample - I found different results for the following: clj:
(defn bubu [x] (case x (1) "egy" (2 3) "kéthá" "nemtom"))
(defn baba [x] (case x (1) "egy" [2 3] "kéthá" "nemtom"))
(defn bobo [x] (case x 1 "egy" '(2 3) "kéthá" "nemtom"))
(defn main []
(println "bubu" (map bubu [1 2 3 4 '(2 3) [2 3]]))
(println "baba" (map baba [1 2 3 4 '(2 3) [2 3]]))
(println "bobo" (map bobo [1 2 3 4 '(2 3) [2 3]]))
)
gives this result
user=> (main)
bubu (egy kéthá kéthá nemtom nemtom nemtom)
baba (egy nemtom nemtom nemtom kéthá kéthá)
bobo (egy nemtom nemtom nemtom kéthá kéthá)
after compiling to scm and run in the gsc repl I get this:
> (hello/main)
bubu (egy kéthá kéthá nemtom nemtom nemtom)
baba (egy kéthá kéthá nemtom nemtom nemtom)
bobo (egy nemtom nemtom nemtom nemtom nemtom)
Anything we do wrong ?
Thanks for pointing out the behaviour with case. I'm translating directly to Scheme's "case", but you've highlighted that this may no longer be possible, as vectors can be values in Clojure case statements and I'm not sure off the top of my head how best to do this in Scheme.
For your other questions:
1) How to display all loaded namespaces?
Namespaces and bindings are an atom holding a map. In a gsc repl you can inspect the loaded Clojure symbols like:
(cljscm.core/println (cljscm.core/keys (cljscm.core/deref cljscm.core/namespaces)))
2) How to begin exploring compilation?
I have a talk on InfoQ that gives a very brief high-level look at how compilation works with respect to Objective-C. The second half of the talk outlines where clojure-scheme fits in with respect to Gambit. The best place to start is getting comfortable with Gambit compilation, so referring to the Gambit manual and especially the Gambit iOS repl example project included with the Gambit source distribution.
3) Should I worry about all the compiler warnings like "CAUTION: :as alias must be unique"
?
This is a bug. It appears that the warning condition has been inverted so it's warning precisely when things are OK. I'll look into this.
Thanks for the clear, detailed questions! Let me know if I can help further.
I mainly struggle with gambit, gsc works fine, but I cannot compile, I have OSX SDK 10.8 and gambit needs 10.7. Do you know if Gambit works with the 10.8 SDK? Thanks
Sorry for the delay in responding-- I don't actually know about the 10.8 SDK situation. The best place for help would be the Gambit Scheme mailing list at gambit-list@iro.umontreal.ca which I've found to be very responsive.
Hello,
I do not want to spoil your issues but I am stuck with getting from .clj to .c. Is there a place I could send some questions ?
Thanks, Balazs