Hacker News new | past | comments | ask | show | jobs | submit login
Noir - The Clojure web framework (webnoir.org)
145 points by abp on June 22, 2011 | hide | past | web | favorite | 71 comments

The examples uses Clojure as the language for defining the HTML. I've also seen Common Lisp examples (such as in Practical Common Lisp, http://goo.gl/CuUZQ) that use CL for the same purpose. In frameworks built for other languages, it is most common to have a separate template language for defining the HTML.

It seems much easier to use the same language when using a Lisp dialect compared to for instance Java, which would be a lot more verbose, but it is also done this way to separate logic from presentation, and because it's (supposedly) easier for front-end developers. Coming from non-CL frameworks, it was natural for me to choose a template framework for my small (and now outdated) tutorial on writing a blog in CL (http://goo.gl/YHCw).

However, I'm wondering if anyone has any experience developing web applications using a Lisp-dialect for generating the HTML (as Noire and the example in Practical Common Lisp), and if this is scalable to a team where front-end developers might not be used to or familiar with Lisp.

The syntax seems easy on the eyes, so perhaps it's not such a big problem once they get over the unfamiliarity.

That will depend very much upon your HTML developers. Some will be able to do it, a large number will not.

Even when using simple template languages I have experienced the I didn't understand those funny bits in the HTML so I have removed them far too many times.

In Clojure, Enlive (https://github.com/cgrand/enlive) is a better solution because the HTML remains as HTML.

The main advantage of writing HTML using a tool like Hiccup is that you can factor out repeated sections of markup into functions.

For example, one might write a page like:

  (defn user-settings [user]
    (settings-for [user]
      (breadcrumbs (link home) (link settings))
      (text-field :login)
      (text-field :email)))
And the functions used would take care of generating the page, layout, form, fields, error notices, flash messages, CSRF protection and so forth. By the time you've finished with all that, those 4 lines of Clojure will be 50 lines of HTML.

Hiccup tends to lend itself toward user interfaces that are uniform and predictable, with repeatable elements. Think Facebook or Github, for instance.

I don't see how this any different from what Enlive provides. Enlive templates/snippets create functions which generate HTML. In anycase, using Hiccup with Enlive seems to combine the best of both worlds.

HTML is a markup language, rather than a Turing Complete programming language, so there's a lot of redundancy in a HTML file that could be avoided in a programming language.

You can get around this in Enlive and other HTML-based templating methods by taking a hybrid approach. The layout HTML is written by a designer, but all the tedious repeatable elements are written by programmers in helper functions, or factored out into dozens of smaller templates.

I'm not sure I like this approach, as it (a) glues together several different methods for generating HTML, (b) encourages people to write the HTML around the page design, rather than treating HTML as purely semantic markup.

I admit to being something of a purist when it comes to HTML. I'd prefer to keep the style and design of the page out of my HTML as much as possible; idiomatic HTML should be semantic markup, whilst the design of the page should be defined in CSS.

I don't see anything in Enlive which is at odds with your viewpoint.

My viewpoint is that HTML shouldn't be written directly, because the language isn't designed to be particularly DRY. Isn't that very much at odds with Enlive?

Enlive does exactly what Hiccup does with the additional bonus that it allows designers who are comfortable with HTML to be a part of the process. Enlive is not page centric - that's the whole point of snippets.

But if none of your designers are writing HTML, what benefit does Enlive have over Hiccup? Whilst Enlive could probably mimic Hiccup's style through aggressive use of snippets, it seems to me that it would need more code to produce the same result. Enlive seems the wrong tool for the job if you want to use it in the same fashion as Hiccup.

Enlive vs Hiccup seems entirely dependent on the composition of your group. For a group of programmers, Hiccup is an efficient means of not repeating yourself. Add a single designer and you'll find programmers implementing a lot of mockup images to be compatible with IE7. Try hiring more designers, especially ones who can use existing design tools, and you'll find Hiccup-style to be completely unusable. Enlive-style allows a company to hire designers who can produce HTML that works in all the browsers that you support, leaving programmers to work on functionality.

In short, step 1 Hiccup, step 2 ???, step 3 profit!, step 4 Enlive.

(Also: dealing with browser induced styling edge cases while you're trying to focus on substantial features is every programmers hell.)

(Edit: I'm a compojure/hiccup fanboy in my spare time, but during the day I work at a large company who can't hire enough programmers.)

For the record, I think Enlive is incredibly useful for a large number of teams.

However, I'm a HTML purist at heart. I believe HTML should be semantic markup, and that the page design should be independent of the HTML generated, whenever possible. Ideally, it's the CSS that should determine the page layout and style.

I also work for a company that produces very uniform web interfaces, and where the developers significantly outnumber the UX guys. Hiccup would work very well in this environment, but perhaps not so well in an environment with many designers :)

Using them together does seem ideal, but it turns out it is pretty inefficient in practice: http://groups.google.com/group/enlive-clj/browse_thread/thre...

I agree that it depends pretty heavily on who is doing your HTML. That being said, you can just not use the defpartial stuff and instead include Enlive to use with Noir just as well. There are purposefully no constraints on what you use to generate HTML. The main purpose of settling on Hiccup in this case is to provide something that I think the Clojure web community desperately needs: a single place to start and build something. The only way I can provide that start pointing is by making some choices and running with them.

Also, I really love html functions as opposed to JQuery-esque template filling. It's cleaner and more flexible to me.

Is anyone aware of something similar to enlive in pure Java? I would certainly like to give it a try.

Wicket and Tapestry are trying to do the similar thing. Not as good as Enlive though.

The same philosophy is applied in the Seaside framework for Smalltalk. See for example [1].

[1]: http://onsmalltalk.com/page-templates-and-seaside

If a front-end creates a mockup using a certain DOM, it is easy for the back-end to generate that DOM (or tell the front what needs changing). If the back-end generates a DOM, it is typically easy for the front-end to create CSS/Javascript to fit (or tell the back-end what needs changing). Also, learning that (:a :href uri name) maps to <a href=uri>name</a> is not hard, so usually the front-end will be capable of making basic changes.

It is not a significant obstacle.

The examples uses Clojure as the language for defining the HTML

See this Stackoverflow question... CL-WHO-like HTML templating for other languages? (http://stackoverflow.com/questions/671572/cl-who-like-html-t...) which provides some examples in other languages.

However, I'm wondering if anyone has any experience developing web applications using a Lisp-dialect for generating the HTML (as Noire and the example in Practical Common Lisp), and if this is scalable to a team where front-end developers might not be used to or familiar with Lisp.

I like keeping the HTML markup within the back-end developers domain and leave the front-end developers/designers to just use Javascript & CSS around it. (disclaimer: In most cases I'm both the back-end and front-end developer :)

Looks promising!

One question: form rendering, validation and handling are the most important as well as the most annoying things you have to do while writing a web application. Do you plan to incorporate something for that into the framework?

Why would I use Noir instead of compojure or ring + moustache?

Zak's characterization is basically correct. Noir isn't really a replacement for those things, more of an abstraction over them. It was born out of seeing how a real web-app evolved and what was missing from the ring/compojure/hiccup stack as I built http://www.typewire.io. Also, as I mentioned in one of the other comments, I hope that it will serve as the single "package" to start with web development in Clojure, instead of having to try and cobble it together from the pieces that are out there now. By controlling all of it, I can create a much more cohesive and well defined story for helping people get started. I can also share what I've learned about maintaining websites in Clojure and hopefully encourage patterns that avoid some of the pits I fell into.

I'm encouraged that Noir builds on top of existing tools. It indicates that our current set of web libraries is flexible and modular enough to act as a good foundation for more sophisticated frameworks.

It looks like Noir uses a custom "lein run" command to start the server. Have you considered using the lein-ring plugin, instead?

I've found that this is a really nice "feature" of Clojure, and maybe other Lisps. Most libraries are very small and tend to all speak in terms of the same de facto standard interfaces (functions, seqs, hash maps, vectors, etc.) so they can be easily composed. Trying to fit together Java or C# libraries like this is basically impossible without some mediating standard base classes or interfaces.

Not about Clojure, and has probaby been posted before, but: http://gbracha.blogspot.com/2011/06/types-are-anti-modular.h...

I also wonder if this isn't a result of using a Lisp. In Node.js you see an absurd proliferation of libraries that do essentially the same thing but provide slightly different syntax. In Lisp you can reuse an existing library, provide your own surface syntax and not incur any overhead.

I did originally, but I wanted more control on how middleware gets wrapped around the app, as well as the ability to have dev and production "modes". Each of these adjusts what middleware goes into the stack and how it reacts.

Ah, I see. Have you considered writing a "lein noir server" command that starts the server? That way people could use the same `:ring {:handler blah}` syntax in their project.clj file, and have their application work with lein-ring and other plugins such as lein-beanstalk.

Thanks for this - it has just worked as a good start point for me. As a grumpy person who doesn't like searching for libraries, these "low barrier to entry" and "meta-library" ideas make me less grumpy.

It looks like Noir is a library of convenience functions built on top of Compojure, Ring and Hiccup. Some of it looks useful, though the fact that it uses SHA1 to hash passwords is not a good sign.

An oversight on my part :) Luckily, that is an exceptionally easy thing to fix.

Edit: and now it is :D

Still some nits -

* SHA-x is not an "encryption" algorithm, it's merely a cryptographically secure, one-way hash. The function name and the documentation are thus misleading.

* You shouldn't use SHA-x or MD5, etc. for password hashing anyway, because they are just way too fast! You should use BCrypt for password hashing.

I can submit patches if you wish :)

Just out of interest, what do you mean by 'way too fast'? I would think that having a fast hash would be a good thing. Or is it because an attacker can generate hashes for some dictionary very fast? Isn't this why you'd use a salt as well?

Sorry if these seem like dumb questions, just trying to learn.

Hashing algorithms like SHA-256 have a very interesting property, they are designed to be extremely fast (even with large amounts of data). That lets you generate millions of hashes per second on any modern CPU (much faster with GPUs). Salting doesn't help much because if your DB is compromised, you are still open to brute force or dictionary attacks.

BCrypt is a very good algorithm for hashing passwords because it's very slow (compared to SHA-x) and thus are extremely time consuming for an attacker. BCrypt also allows to incorporate a "work-factor" which makes the hashing even slower; that allows us to choose a higher work factor when more powerful computers become commonplace.

There are a lot of articles online that discuss this subject.

The faster you hash, the faster I can run a brute force attack on your password form.

No, this is technically wrong. There are better ways of stopping a brute-force attack on a password form, such as attack detection, and black-lists. If you rely on a computational delay to slow attackers down on your servers, you will merely open yourself to a simpler DDOS attack. The purpose of a computationally expensive hashing algorithm is that it prevents brute-force attacks against a stolen copy of your password database, where the attacker no longer has to deal with your other defenses.

Quick question, if you have the db but not the salt, does the speed of the hashing algorithm still matter?

The salt is usually in the db as you should have a different salt per password. The purpose of the salt is to add some complexity so that each password is in fact hashed by a slightly different algorithm (in order to defeat pre-computation based attacks.) If the attacker does not know that salt, then he does not know the full hash algorithm and cannot brute-force the password. So technically no, I don't think so. However, if the attacker can get your password db he can also get your salt db so I wouldn't rely on this by any means.

Disclaimer: I'm absolutely not a security professional.

It wouldn't, but it's a Bad Plan not to have per-user salt, so the circumstances where you'd have the passwords but not the salts that go with them would be... odd.

Thanks to you and astine, I just learned today about per-user salts. I thought that you only needed a site-wide salt and after reading on the topic, I now understand why it's better to have a per-user salt stored in the db.

I was also confused by these frameworks (e.g., Django) that ask you for a secret key and I thought that the secret key was a site-wide salt. Fortunately, they knew better than me ;-)

Absolutely! I don't claim to be an encryption expert, by any means. :)

I am no crypto expert either, but here is your patch - https://github.com/ghoseb/noir/commit/f814ea9d1bc7470197eb73... (pull request already sent).

Noir looks very good. Keep up the good work and let me know if you need any help ;)

I don't know Clojure (not sure how expressive it is), but for a framework isn't the code too less? I have seen other frameworks, but they are quite large (in terms of LOC.) Is it that they contain more functionality?

The clojure culture tents to build extremly small librarys that are really composable. Look at this video about simplicity (http://skillsmatter.com/podcast/java-jee/radical-simplicity/...) it translates very nicly to the web librarys.

In a nutshell: Make small simple things even if thats ends up beeing a bit more verbose then if you would have built it as one thing. If time shows that a set of librarys works very nicly together then you can write something new that combines these in a nice way.

This is what the Noir does it just pulls together some librarys and delivers them in a nice package.

If Clojure is too concise, you can always write a library to apply a more cumbersome syntax if you'd like.

One of the cool things about using a functional language for web development is the potential to use continuation-passing style (CPS) to make http look like a stateful protocol, which makes implementing chains of user interactions a lot simpler.

I know Clojure doesn't support first-class continuations, but does anyone know whether is it possible to use Clojure Noir to program in this style?

Can you give me an example of what that would look like? Or a description of the flow you'd want to achieve?

Hey I really liked the syntax highlighting color scheme you used in the webpage, is there an emacs theme for that?

I use vim ;)

Is there a vim theme for that?

While making a simple web application in Chicken Scheme, I used SXML transformations. From the code samples, that doesn’t appear to be the convention with this web framework. Is there a good reason to use alternatives to SXML? Or is it just preferences?

Very nice, I've been wanting to get into Clojure, but not having a functional background I've found it hard to jump into anything. This looks easy enough that I could transition in slowly, I think I'll give it a try.

I have been doing mostly OOP for several years. I read just about every Clojure book out there, but the functional thing just wasn't clicking. It's a weird feeling. I knew the language, but didn't know how to design a program in a functional style. Maybe part of it is that most of the Clojure books available don't really cover this. Then I read "Learn You a Haskell for Great Good!" Eureka! I have never written a line of Haskell, but I feel like reading that book made me better using other languages.


I would recommend reading books like "Learn You a Haskell for Great Good!" with an open repl. I find it is too difficult to remember new language features until I type and run code.

I agree that learning Haskell as a prelude to learning Scala and Clojure might not be a bad idea (I blogged about this a few days ago).

As a side note, I've found that a very good way to familiarize yourself with a new programming language and its underlying concepts is by solving first 40-50 problems in Project Euler with the language: http://projecteuler.net/

While PE is great keyboard exercise and includes many cool puzzles, I think it is bad way of rewiring your brain for functional thinking. Unless you'll do some exercises that explicitly require new ways of thinking (and read something), you'll probably end up struggling with writing java code in clojure. I advice to do some FP course and then solving some problems in functional way - when you already know the way.

If you need functional background, you could try SICP - there is also a clojure version being developed. I took an Ocaml course on my uni 'strongly inspired' by SICP and I must say that it pretty much rewired my brain for functional.

Running through the Clojure Koans (on Github) is another great way to get some basic familiarity with the language.

I'm surprised that there's no large "Fork me on Github!" link at the top right corner of the screen.

Still, looks very interesting.

I honestly never really saw the appeal in those... There's a link to the source there though, so that's roughly equivalent :)

Here's what I don't get about Clojure fans: I don't see what problems you are solving. A simple Hello World program is made in Clojure and it gets upvoted all day. On the other hand Ruby on Rails folks are solving real problems today, making strides in integrating CoffeeScript and cleaning up javascript directories.

It's like someone showing off a new garbage collection library built in C. The problem's been solved. Show me something new.

Before we can start doing all the cool stuff, we need a solid foundation. Clojure isn't quite in the position where it can match Ruby on Rails, at least not yet.

However, in my rather biased opinion, many of the core Clojure web development libraries already exceed those built for Ruby, and certainly vastly exceed those that existed when RoR was first released.

For me, the most interesting part of libraries like Noir is how much they use existing libraries. It indicates we're doing something very right with regard to modularity.

Integrating CoffeeScript and cleaning up JavaScript code are not "real" problems either. Just like with new programming languages such as Clojure it's about improving the tools used to solve real problems.

You clearly weren't around the Rails scene six or seven years ago, when it seemed like everybody was writing blogs, to-do lists and similar basic CRUD apps (since it could be done with little more than a "script/generate scaffold"). When a technology is new and there aren't a lot of commercial projects using it yet, you'll get a low S:N ratio of projects coming from the community as people get their feet wet. As the technology matures, you'll see more "real problems" being solved.

I was around before Rails, back when Tapestry, Wicket and Appfuse projects were making my life easier. How does Clojure for Web development make my life easier? is the question that should be asked.

Clojure's been popular in the hacker community for a good 2 years now. That's a weak argument.

Tapestry, Wicket and Appfuse? You're making my point for me: The thinking you're using now to praise Rails and attack Clojure would have been just as valid seven years ago to praise Java and attack Ruby. All you're really remarking on is the maturity of the communities in question, but you're presenting it as a commentary on the usefulness of the technology.

And Clojure has been known for a good two years now, but I would not have said Clojure was popular two years ago. It didn't have a lot of regular users, which is what you're observing when you say people aren't solving "real problems" in it. I'm not sure I'd even say Clojure is popular today. I'd say it's still roughly where Ruby was in 2004 — lots of excitement, but still lots of growing to do.

I studied Clojure and I hope really cool stuff comes out.

When Rails came out it solved all kinds of new problems. For one, by using metaprogramming a whole bunch of files were eliminated. As soon as Rails came out I was much more productive than I was with Tapestry or Wicket. Not so with Clojure.

The metaprogramming capabilities in Clojure greatly exceed those of Ruby, so that's a bit of a weak argument if you're impressed by things of that nature. Also one shouldn't forget about Clojure's concurrency model and functional purity which lend themselves to correctness and scalability.

Just because it doesn't necessarily better solve your class of problems doesn't mean it's unsuitable for other people's.

"bit of a weak argument if you're impressed by things"

I'm impressed by results

Im not sure Clojure does make Web development much easier yet but as in with any language people like the want to develop as much as possible with it. So people trie to lift clojure to the web, this will take some time just as other languages took there time.

The reason why people want Clojure on the web could be (or "How Clojure can make your life easier for webapplications):

1. Use FP in the Web (I mean general imutability not closures) 2. Safe and easy concurency 3. Tons of java librarys for general stuff that you might do 4. Very powerful meta programming. Rails has shown this to be a win and with Clojure much more is possible.

I've been in the Clojure community for some time and the real "boom" of Webapplications in Clojure has only really lifted in the last year. I think its pretty impressiv how the Webstack developed in that time.

Way to go, webnoir! 502 Bad Gateway screen!

Level of confidence instilled in me because of this: 0% Chance I'll come back later to check it out: 0% Probability I'll go visit Enlive right now: 100%

Can't help but suspect you're choking on your own dog food here. Or crapping out a corn-studded loaf, take your pick.

Well done!

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact