Prismatic Schema on Clojure 1.4? - clojure

We are evaluating Prismatic/schema for use on a project that is currently using Clojure 1.4. We would prefer not to upgrade Clojure in our project at this time. Schema requires Clojure 1.5.1, but some basic testing in the repl did not show any problems with the Clojure version changed to 1.4.
Has anyone else tried using schema on Clojure 1.4, and how has it gone?
Here's what I tried (after changing Clojure to 1.4.0 in project.clj):
(require '[schema.core :as s])
(require '[schema.macros :as sm])
(sm/defn foo ...)
(s/with-fn-validation (foo ...))
No problems. The one thing I noticed was that the schema tests completely puke (won't even run) on Clojure 1.4. This I don't really care about, but I would care if there were actual problems with project functionality.

As far as I know, Schema should work fine with 1.4. The tests were failing because they use a marker protocol (with no methods), and 1.4 doesn't like that -- but Schema itself doesn't rely on this feature. I verified that after adding a dummy method to ATestProtocol, all of the Schema tests currently pass under Clojure 1.4.0.
I don't want to promise future support for 1.4, but if you spot any issues or bugs please let us know and we'll see what we can do. As Jared pointed out above, the Google Group is probably a more appropriate place for questions like this.

Related

Hello World - Clojurescript

Beginner here.
Can I compile an existing Clojure script to run it on the web using ClojureScript?
Let's say that I have a script that prints Hello world in my terminal, and I want to print that text on the browser. Should I rewrite a whole script with ClojureScript syntax, or should I just compile it using another compiler?
(ns clojure-hello-world.core
(:gen-class))
(defn -main [& args]
(println "Hello World"))
(Long answer :P)
Even though Clojure and ClojureScript share a good amount of features, there are some that are specific to one or the other. For example there are no real classes in JavaScript so the :gen-class specification in the ns form doesn't make much sense.
One important fact is that the syntax of both Clojure and ClojureScript is exactly the same, differences have to do mostly with the host VM in which they run (Java VM in the case of Clojure and JavaScript VM in the case of ClojureScript).
There is a list of the differences between the two Clojure implementations here.
There's also a tool called cljx to "write a portable codebase targeting Clojure/ClojureScript". Recently there has been some discussion on the Clojure Dev group around finally implementing feature expressions which would on one hand deprecate the use of cljx but on the other complicate the work that tools have to do to extract information from Clojure source files.
I would start with lein-cljsbuild to get started. This will get you going with a nice edit eval and look at browser loop. It's well worth getting this setup first because it makes learning ClojureScript much more fun. I promise it's worth the hassle. If you need more interactive support the folks in #clojure on freenode are very kind and helpful.
Basically, the Browser executes JavaScript. You compile your ClojureScript code to JavaScript. The Browser loads your JavaScript via an HTML page. So, you have to create an HTML Page and point your Browser at it.
The simplest way I got started was to use Luminous (http://www.luminusweb.net/docs/clojurescript.md).
However, Chestnut (https://github.com/plexus/chestnut) looks promising.

Switch to a specific clojure version from REPL

I have two apps app1.jar and app2.jar, with Clojure 1.2 included in app1 and Clojure 1.4 in app2.
When I run:
java -cp app1.jar:app2.jar clojure.main
to open a REPL, it uses Clojure 1.2. Is there a way to switch to Clojure 1.4?
As with many such question the anser is use leiningen lein2 has a profiles feature that lets you properly handle multiple versions of clojure. This is especially useful because the clojure.contrib libraries are very different between those two versions. It took me longer to type this sentence than to install, configure and get a project started with leiningen. It really is worth it.
In practice you will need to have two instances of clojure running, one with each profile (version) and you can then either have two REPLs (one attached to each) or one repl (using nrepl) that you switch back and forth.
There is an unfortunate amount of old documentation on the net for Clojure that predates mass adoption of Leiningen.

Get the Clojurescript repl/connect to not compile when in production?

In my clojurescript code I have the following:
(defn onload [] (repl/connect "http://localhost:9000/repl"))
(set! (.-onload js/window) onload)
The Clojurescript repl is very useful in development, but I am hesitant to leave it in the code during production. What is the cleanest way to have the above code present during development (simple compilation), but absent during production (advanced compilation)?
The modern-cljs tutorial actually describes exactly how to solve this here.
Hope that helps!
Unfortunately there aren't currently any well defined ways to do conditional compilation in ClojureScript.
You could add configuration variables to control whether to start a REPL in a variety of ways, but one quick and easy way would be to get the hostname of the current page, and only invoke repl/connnect if it was "localhost" or whatever other domains you're using for development work.
I think a combination of lein2 profiles and cljsbuild src-paths munging can do the trick. eg, create a namespace that simply loads your repl, and exclude it with a profile run for the final compile (possibly might need to create a dummy namespace in another src-path directory).

Troubles Importing Clojure Libs in Paradise

I occasionally get this problem, and generally work around it, but it's rather frustrating.
I have all of Incanter (check it out if you don't know it: it's superb) on my classpath. I try to import it (through a Slime REPL) like this: user> (use 'incanter.core), but fail.
Doing this: user> (use 'clojure.contrib.def) works just fine, and this file is in the same place–on my classpath.
Regardless, the error isn't anything about classpath: it's this:
Don't know how to create ISeq from: clojure.lang.Symbol
[Thrown class java.lang.IllegalArgumentException]
You can see my entire terminal here (a screenshot.)
I don't know what's going on here, and it's really frustrating, as I really would like to use Incancter, and I can from the Incanter binary's REPL. I definitely don't want to develop from that–and this should work.
Any help would be much appreciated.
EDIT:
It appears as though Incanter requires Clojure 1.2, and lein swank gives me Clojure 1.1. This might be the cause of my problems: if so, is there a way to continue to use Swank & Lein with Clojure 1.2?
Thanks again!
EDIT:
Apparently if you start using Clojure-1.1 and lein swank, you're stuck with it unless you make a new project.
If future people have this problem, this article helped me out, but also, at least for me, you must start a new lein project if you had begun it using leink swank and Clojure-1.1. Simply changing your project.clj file and then lein swanking again doesn't work.
Yes, you can use Leiningen and swank-clojure with Clojure 1.2. You might need to use a recent version of Leiningen (I'm not sure if a certain old limitation affected lein repl only or was it lein swank as well; anyway, try the 1.2-RC2 which you'll find in the downloads section on GitHub). You will also need to use a recent-enough swank-clojure; I use a bleeding edge checkout myself, get yours here.
Other than that, simply use 1.2 jars for Clojure and contrib. (Lein uses it's own Clojure, separate from the one used for lein swank, for its internal workings and you never need to care about it; swank-clojure has no AOT'd namespaces and doesn't particularly care about the Clojure version, except once in a (long!) while something breaks, a patch is applied and joy is restored.)
I hope the above helps, but if it doesn't: your problem description is not entirely sufficient for me to get a clear picture of what is happening. Could you add information on what it means for "all of Incanter" to be on your classpath (do you mean the jars? sources? where do you get them? how do you set your classpath?). Without knowing this, it'll be hard to replicate your setup to try to track down the source of the problem.
Of course if bumping some versions fixes things, please disregard my current confusion. ;-)

webjure vs compojure?

I've heard of two Clojure based web application frameworks: Webjure and Compojure. Can someone let me know which is better?
Now you can add Ring to the list. All of these frameworks are very new and likely to evolve (or die) quickly, but Compojure does seem to be the most actively developed based on the past 6 months or so.
"Better" is too subjective a question to get a definitive answer to. Try them all and see what works.
Compojure has been working very well for me so far. I like the simplicity of the design, the flexibility and the fact that it encourages a nice idiomatic functional style.
Sample server:
(use 'compojure)
(defroutes my-app
(GET "/index.html"
(html
[:h1 "Hello World!!"]
[:body "This is some text"]))
(ANY "*"
[404 "Page not found"]))
(run-server {:port 80}
"/*" (servlet my-app))
Note that Compojure uses Ring internally.
I second Rayne's recommendation on Moustache.
Right now, we are using Ring (base layer, middleware), Moustache (routing), Hiccup (html generation). We just began using Compass for CSS (http://compass-style.org/). So far, I'm happy with this collection of small libraries rather than a big "complete stack" framework (Django, Rails, ect...).
Now, there is also a new one named Noir build on top of compojure. Really recommended, especially with Heroku.
Compojure seems to be getting the most buzz right now. Not necessarily indicative of quality, but the one with the most eyes will probably evolve the fastest.
There is also Moustache, which is what I use in TryClojure, along with Ring. It's pretty awesome.
Compojure is based on Ring, which is a low-level framework that doesn't attempt to hide much of HTTP. It's similar to WSGI (Python) or Rack (Ruby). Ring has a concept of middleware, small pieces of code that can do something meaningful with an HTTP request and/or response, such as dump header infos, manage cookies etc. Compojure is a higher-level framework, somewhat similar to Ruby's Sinatra. Its aim is to provide a convenient API (or DSL, if you prefer) for most tasks a Web app developer faces. It's usually used together with an HTML generation library, such as Hiccup.
I haven't heard much about Webjure in the last few months, I'm not sure it's in active development (but I'd be interested to find out more). It precedes Ring, AFAICT, which seems to have become somewhat of a standard for Clojure Web frameworks.
I've been building a project for my own use using Compojure and it has worked out great. It doesn't really get in the way very much and lets you focus on what's important, your problem domain. The project is about 1100 lines of clojure just to give you an idea of the size.