I have been following clojure for some time, and some of its features are very exciting (persistent data structures, functional approach, immutable state). However, since I am still learning, I would like to understand how to apply in real scenarios, prove its benefits and then evolve and apply for more complex problems. i.e. what are the easy wins with clojure (e.g. in an e-commerce setup) that can be used to learn as well as ascertain its benefits.
I have investigated clojure based web frameworks, but I am not keen on them, as they need hand-written javascript (as against gwt). So for me, it is more about backend processing. Can someone explain where they applied clojure (in real deployments), and how did it prove useful (and the cons, if any, of using clojure)
Further analysis:
Lazy evaluation is an oft example of power of Lisp. Clojure being a Lisp, offers the same advantage. So, a real world example of such an application (in context of clojure) would help me gain insight.
You have mentioned that you work with CSV files. I found these to be very helpful, because I had to parse a csv file -- used clojure-csv; then extract certain columns from that csv file using sequence functions; interleave http form field names using zipmap; and then make http calls to an ASP application using clj-http.client.
(def accumail-url-keys ["CA", "STREET", "STREET2", "CITY", "STATE", "ZIP", "YR", "BILL_NO", "BILL_TYPE"] )
.
.
.
(defn ret-params
"Generates all q-parameters and returns them in a vector of vectors."
[all-csv-rows]
(reduce
(fn [param-vec one-full-csv-row]
(let [q-param (zipmap accumail-url-keys one-full-csv-row)
accu-q-param (first (rest (split-at 3 q-param)))
billing-param (first (split-at 3 q-param))]
(conj param-vec [accu-q-param billing-param])))
[]
all-csv-rows))
That project was an accelerated Clojure learning exercise.
Two sites 4Clojure.com and http://www.cis.upenn.edu/~matuszek/cis554-2010/Assignments/clojure-01-exercises.html are good places to start working on Clojure exercises. You can build on those.
Also the Clojure Google Group is a very helpful place to get information.
The Univ of Penn CIS exercises, as simple as they might seem, have given me a lot to digest, especially getting the skeleton of a tree, and recently the skeleton problem got a long discussion in the Google Clojure group.
Good luck.
cmn
Related
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.
I've recently been much impressed by the work of Chris Granger and his Light Table. This question is not about light table though, but more about the "BOT" architecture he described using in his blog post "The IDE as a value" :
http://www.chris-granger.com/2013/01/24/the-ide-as-data/
Now, I'm pretty new to clojure but would like to better explore this way of programming: Behavior, Object, Tag:
(behavior* :read-only
:triggers #{:init}
:reaction (fn [this]
(set-options this {:readOnly "nocursor"})))
(object* :notifier
:triggers [:notifo.click :notifo.timeout]
:behaviors [:remove-on-timeout :on-click-rem!]
:init (fn [this]
[:ul#notifos
(map-bound (partial notifo this) notifos)]))
(object/tag-behaviors :editor.markdown [:eval-on-change :set-wrap])
Where can I find clojure code that uses that style and those composition principles?
BOT sounds like the Light Table "proprietary" flavor of Entity-Component-System (ECS) architecture. I would start with wikipedia entry and then go to this post with code examples in ActionScript (we are in the world of games).
There are also some examples in the Clojure context.
I was reading this site about the clojure web stack:
http://brehaut.net/blog/2011/ring_introduction
and it has this to say about ORM for clojure:
"There are no SQL/Relational DB ORMs for Clojure for obvious reasons."
The obvious reason I can see is that the mapping to object happens automatically when you do a clojure.contrib.sql or clojureql query. However it seems some extra work is needed to do one-to-many or many-to-many relations (although maybe not too much work).
I found this write up for one-to-many: http://briancarper.net/blog/493/
Which I'm not sure I agree with; it appears to be assuming that both tables are pulled from the database and then the joined table is filtered in memory. In practice I think the sql query would specify the where criteria.
So I'm left wondering, is there some fairly obvious way to automatically do one-to-many relations via clojureql or clojure.contrib.sql? The only thing I can think of is something like this (using the typical blog post/comment example):
(defn post [id]
#(-> (table :posts)
(select (where :id id))))
(defn comments [post_id]
#(-> (table :comments)
(select (where :post_id post_id))))
(defn post-and-comments [id]
(assoc (post id) :comments (comments id)))
Is there any way to sort of automate this concept or is this as good as it gets?
I asked this question quite a while ago, but I ran across the following and decided to add it as an answer in case anyone is interested:
http://sqlkorma.com/
The "obvious" reason you don't need ORM as such in Clojure is because idiomatic Clojure doesn't have objects, per se.
The best way to represent data in a Clojure program is as lazy seqs of simple data strutures (maps & vectors). Mapping these to SQL rows is much less complex, and has much less of an impedance mismatch, than full-blown ORM.
Also, regarding the part of your question relating to forming a complex SQL query... reading your code, it doesn't really have any clear advantages over SQL itself. Don't be afraid of SQL! It's great for what it does: relational data manipulation.
There's still no high-level library to create complex relational queries that I know of. There's many ways to tackle this problem (the link you provided is one way) but even if ClojureQL provides a really nice DSL you can build upon, it still miss some important features. Here's a quick and dirty example of a macro that generate imbricated joins:
(defn parent-id [parent]
(let [id (str (apply str (butlast (name parent))) "_id")]
(keyword (str (name parent) "." id))))
(defn child-id [parent child]
(let [parent (apply str (butlast (name parent)))]
(keyword (str (name child) "." parent "_id"))))
(defn join-on [query parent child]
`(join ~(or query `(table ~parent)) (table ~child)
(where
(~'= ~(parent-id parent)
~(child-id parent child)))))
(defn zip [a b] (map #(vector %1 %2) a b))
(defmacro include [parent & tables]
(let [pairs (zip (conj tables parent) tables)]
(reduce (fn [query [parent child]] (join-on query parent child)) nil pairs)))
With this you could do (include :users :posts :comments) and get this SQL out of it:
SELECT users.*,posts.*,comments.*
FROM users
JOIN posts ON (users.user_id = posts.user_id)
JOIN comments ON (posts.post_id = comments.post_id)
There's one major issue with this technique though. The main problem is that the returned columns for all tables will be bundled together into the same map. As the column names can't be qualified automatically, it won't work if there's similarly named column in different tables. This also will prevent you from grouping the results without having access to the schema. I don't think there's a way around not knowing the database schema for this kind of things so there's still a lot of work to do. I think ClojureQL will always remain a low-level library, so you'll need to wait for some other higher-level library to exist or create your own.
To create such a library, you could always have a look at JDBC's DatabaseMetaData class to provide information about the database schema. I'm still working on a database analyzer for Lobos that use it (and some custom stuff) but I'm still far from starting to work on SQL queries, which I might add in version 2.0.
At the risk of swimming in the waters with some of the SO heavy hitters (to mix my metaphors, thoroughly ;) - surely one of the best features of ORM is that, for the vast majority of cases, the pragmatic programmer has to never use or even think about SQL. At worst some hacky programming with the results of a couple of queries may be required, on the basis that this will be converted in to raw SQL when that optimisation is required, of course, ;).
To say that ORM is not required for the 'obvious' reason, is somewhat missing the point. Further to start using a DSL to model SQL is compounding this mistake. In the vast majority of web frameworks, the object model is a DSL used to describe the data being stored by the web app, and SQL merely the declarative language required to communicate this to the database.
Order of steps when using ROR, django or Spring:
Describe your models in an OOP format
Open REPL and make some example models
Build some views
Check results in web browser
Ok, so you might use a slightly different order, but hopefully you get the point. Thinking in SQL or a DSL that describes it is a long way down the list. Instead, the the model layer abstracts away all the SQL away allowing us to create data objects that closely model the data we wish to use in the web site.
I would fully agree that OOP is no silver bullet, however, modelling data in a web framework is something it is definitely good for, and exploiting clojure's ability to define and manipulate Java classes would seem to be a good match here.
The examples in the question clearly demonstrate how painful SQL can be, and DSLs like Korma are only a part solution: "Let's suppose that we have some tables in a database..." - er, I thought my DSL was going to create those for me? Or is this just something an OOP language does better? ;)
Have you checked out the Korma library http://sqlkorma.com/ ? It allows you to define table relationships and abstract over joins. I think a major reason there aren't any ORM's for clojure is because they go against Rich Hickey's ideas of simplicity that the language was founded on. Check out this talk: http://www.infoq.com/presentations/Simple-Made-Easy
The library known as aggregate can take care of most of the itches you have here. It's not a full-scale ORM, but if you tell it the relationship graph for your database schema, then it provides CRUD implementations that automatically walk the relation graph. It's useful if you are using something like Yesql or raw SQL queries already, because it plugs in easily to an implementation that is using simple result maps.
Whether you want to use them or not, there was already aggregate
and there is toucan now (and they apparently read the same link as you did).
ORM is premature optimization. Walkable is the new sql library for Clojure that takes holistic approach. Check it out here https://github.com/walkable-server/walkable.
A real world example for those skeptical of fancy readmes: https://github.com/walkable-server/realworld
Is there any DSL (Domain Specific Language) implemented in Clojure ?
Like any Lisp dialect, Clojure draws a very fuzzy line between API and DSL and therefore the term doesn't hold the same mystique that it does in other languages. Lisp programmers tend to write their programs as layers of DSLs, each layer serving those above it. Having said that, here are a few that you could say display non-trivial levels of DSL-ness (in no particular order):
Enlive (HTML templating)
LazyTest (Unit testing)
fnparse (parser generator)
Midje (testing & mocking)
byte-spec (binary-formats)
Vijual (graph layout)
Trammel (constraint programming)
Cascalog (Hadoop w/ datalog syntax)
Incanter (R-like environment)
Sandbar (HTML sessions, forms, auth)
ClojureQL (SQL)
mini-kanren (embedded logic programming)
Leiningen (build tool)
sexpbot (IRC bot with plugin arch)
SQL DSL in Clojure, a bit old but may be a showcase
An useful talk on thinking about how to build DSLs using clojure from the 2010 clojure-conj conference by the creator of Enlive, Christophe Grand: http://blip.tv/clojure/christophe-grand-not-dsl-macros-4540700 (slides are here).
I would also count the design of Ring as in the domain of DSL design. See the talk by Ring's creator, Mark McGranaghan: http://clojure.blip.tv/clojure/mark-mcgranaghan-one-ring-to-bind-them-4724955 (slides)
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.