7 ms·
Lisp for the Web, Part III
- eudox 11y agoYou can't build a web application on Hunchentoot -- a basic HTTP server -- and call it modern. Take a look at Clack for the actual modern approach: http://clacklisp.org/ http://clacklisp.org/ Or one of the frameworks built on it: http://8arrow.org/caveman/ http://8arrow.org/caveman/ http://8arrow.org/ningle/ http://8arrow.org/ningle/ http://eudoxia.me/lucerne/ http://eudoxia.me/lucerne/
- jlg23 11y ago> You can't build a web application on Hunchentoot -- a basic HTTP server -- and call it modern. The article does a pretty good job of starting with the basics and introducing more complexity step by step. I would argue that the author's approach is better than any attempt to introduce a full-stack framework, which does not help the beginner level lisp programmer (clearly the target audience) understand - one might take away some recipes from that but no real understanding. Which, if any, "modern" frameworks one uses then finally depends on the project and taste. After all, gluing together the various routing-, persistence-, ORM-choices only takes a few lines of code anyway. And, after having been consulting as a lisp programmer for some years now, I would even argue that the overhead of learning some full-stack frameworks is usually not worth the benefits they claim to provide.
- kerkeslager 11y ago> And, after having been consulting as a lisp programmer for some years now, I would even argue that the overhead of learning some full-stack frameworks is usually not worth the benefits they claim to provide. I'm not an experienced Lisp developer, but this jives with my experiences with frameworks in other languages. It seems like frameworks cover 95% use cases: they make your life easier for 95% of what you're trying to do. But for the other 5%, you can't just work outside the framework, because frameworks couple you to their paradigm. So you end up trying to solve problems through the framework that the framework doesn't have good solutions for. You're stuck solving problems without the debugging tools or basic building blocks that writing your own in a programming language offers you; it's like trying to tighten a screw with a hammer in the dark. The result is that you end up spending a lot of time on that 5% of problems. What makes this particularly dangerous is that you typically don't start solving the really unique problems of your project until you've already gotten pretty far into your project: you don't run into the 5% problems until you've already committed heavily to using the framework. A lot of less experienced devs get caught up in this: they start using a framework and everything seems easy. Drunk with their newfound power, they try to do everything in a framework, and each new project reinforces their belief that the frameworks are saving them time. It takes a long time to be on enough long-running projects that you see the pattern and recognize frameworks for the double-edged sword that they are. To be clear, I'm not saying that frameworks are always bad. For simple or short-lived projects, a framework is probably the best way to go: you'll probably never hit those 5% cases where the framework will hurt you. But if you're doing something at scale, or for a long time, or doing something very complex: a framework might not be the best approach. And large-scale, long-running, and complex projects are where the money and job stability are at. There is definitely a middle ground to explore here. For example, in the Python world, there are some great minimalist frameworks (Flask, Bottle) which can be tied together with a template engine (Cheetah, string.Template) and SQLAlchemy to give you most of what a big framework like Django or Pylons gives you, but in a much less coupled way that allows you to create your own extensions points. Libraries are much more flexible than frameworks. Sure, you'll feel more pain up front, but you won't spend your time trying to get an ORM to emit a specific SQL query, or waiting for your cache middleware library to accept your PR on a 10-year-old bug in its invalidation.
- gnaritas 11y agoYour complaint isn't about framework, but about other people's frameworks. A framework is always the best approach, when it's your framework and those 5% never happen because you simply modify the framework to be able to do it.
- lispm 11y agoWhat makes it 'modern' and not just newer?
- eudox 11y agoBecause in the real world of web development applications are hardly ever written directly on top of the server. They are written on a framework, that sits on top of an HTTP server abstraction (like Clack), that has pluggable servers. That way, if a new server comes out (e.g. Woo[0]), you don't have to learn all of its internals and rewrite the entire application using it -- you literally just change a keyword argument in a single function call, and now your application is running on a different, much faster server. If someone writes a plugin for Clack (e.g. clack-errors[1]), all applications built on any Clack framework using whatever server can use it. A Hunchentoot plugin works for Hunchentoot applications. Using Clack is sustainable web development. Sure, for a five minute demo, Hunchentoot is fine. But why teach bad practices? [0]: https://github.com/fukamachi/woo https://github.com/fukamachi/woo [1]: https://github.com/eudoxia0/clack-errors https://github.com/eudoxia0/clack-errors
- TeMPOraL 11y agoWhy would you even change your server if a new one came out? If your old server works and is maintained, there's no reason for a switch. Also, 'jlg23 has a good point - learning full-stack frameworks as a beginner only serves to confuse things. For the same reason I never advocate that people new to programming jump straight into RoR or Node.js or whatever framework is hot this week - a person needs to understand the problem a tool solves before using the tool; otherwise you're training a code monkey, not a programmer.
- eudox 11y ago>Why would you even change your server if a new one came out? Woo is many times faster than Hunchentoot. And projects can die. >a person needs to understand the problem a tool solves before using the tool; otherwise you're training a code monkey, not a programmer. There's a reason we use high-level languages: They hide irrelevant details. You shouldn't have to learn how TCP works or know every detail of HTTP to know what can be done with it.
- copsarebastards 11y agoIf this is true, then this explains why all the "modern" websites are crappy media websites that don't solve any problem except "How do I drive traffic to ads".
- jasonm23 11y agoAlso ditched reading as soon as Hunchentoot was mentioned.
- olewhalehunter 11y agoFor anyone interested in having their application and web testing in the same runtime, I'm making a CL web automation library/front-end out of emacs for testing and botting purposes. https://github.com/olewhalehunter/kommissar https://github.com/olewhalehunter/kommissar
- 616c 11y agoIt is not clear from the sample screenshot, but do you know of Conkeror? Sounds like your wet dream! http://conkeror.org/MozRepl http://conkeror.org/MozRepl
- aidenn0 11y agoThis is a reasonable way to get a simple hello world up, but for those new to lisp, know that this isn't how most people develop. Firstly, it is rare to see the SBCL REPL used directly. Most commonly, lisp is developed via an IDE that will include a full-featured REPL (there are several; for sbcl SLIME is what is most commonly used. ClozureCL has its own IDE on OS X, and commercial lisp implementations will ship with their own). GNU clisp has a more feature-full REPL, so you may see that used occasionally. Secondly, lisp has a build system called ASDF. There is a tiny amount of code needed to setup a simple project, and there is a tool named "quickproject" that will generate it all for you. With all the improvements to ASDF in the past decade, I never do a "write lisp file, then load it" anymore.
- CodyReichert 11y agocl-project[0] is another nice project generator. It's mostly pretty similar - but I like the default layout and having a built-in test suite. 0 - https://github.com/fukamachi/cl-project https://github.com/fukamachi/cl-project
- WalterGR 11y agoGNU clisp has a more feature-full REPL, so you may see that used occasionally. For web programming? My understanding is that clisp doesn't support any kind of threading, which definitely makes it impossible to use at least Hunchentoot. And since this article is about Hunchentoot, my understanding is that using clisp will make it literally impossible to follow this article. EDIT: It looks like clisp has experimental threading support if you compile it correctly: http://www.clisp.org/impnotes/mt.html http://www.clisp.org/impnotes/mt.html So I guess the better question is: does Hunchentoot work on clisp?
- aidenn0 11y agoRegardless of whether hunchentoot works on clisp, the point was if you aren't using CLISP you're probably not developing in the REPL in a terminal.
- mck- 11y agoIn case anyone might find it helpful to have another example: I wrote a similar post a couple years ago: https://kuomarc.wordpress.com/2012/05/13/12-steps-to-build-and-deploy-common-lisp-in-the-cloud-and-comparing-rails/ https://kuomarc.wordpress.com/2012/05/13/12-steps-to-build-a...
- Scarbutt 11y agoDon't know how are things on the Common Lisp side, but on the Clojure side, as much as I prefer it to Javascript I end writing regular web applications in Javascript, because for me, it is the more pragmatic choice when I need to get something done. Javascript/nodejs has lots of good mature libraries with good documentation for anything related to web dev, sponsored by companies that eat their own dog food (ex: the passportjs lib).
- TeMPOraL 11y agoMy impression is that CL has much less libraries, but they're generally much better in quality. Having a really powerful language at your disposal also alleviates some of the pains of not having enough "batteries included". But when doing web, it's hard to avoid JS anyway (ParenScript in CL is cool and all, but you still need to make sure the JS it compiles to actually works).
- Scarbutt 11y agoA more powerful language won't help much in getting things done if there is lack of libs in a domain you are not an expert on. For example: implementing authentication and authorization. So I agree with everything you said but I'm mostly talking about getting shit done.
- klibertp 11y agoClojureScript can be used on both Node.js and frontend and is able to call any JS library without any effort. I don't understand what you're talking about at all. It's like saying that Clojure has very few libraries, conveniently forgetting about all of the Java ecosystem which Clojure integrates with seamlessly...
- Scarbutt 11y agoyeah and half of your code and of your time will be writing interop code in non-idiomatic clojure, unless of course you devote even more time and write a clojure wrapper to use the js or java lib in an idiomatic manner.
- kerkeslager 11y agoDo you have an RSS feed for your blog?
- VitoVan 11y agoSorry, not yet.
- VitoVan 11y agoHere: http://vitovan.com/rss.xml http://vitovan.com/rss.xml It's still hot, I added the code for generating rss one minute ago.
- kerkeslager 11y agoHaha thanks!
- hacker_9 11y ago> Why Lisp? Again > It is awesome. Why do people who write or talk about Lisp always have to start with something like this? To be honest I still can't see the appeal of Lisp. Yes everything is a function so you can add/remove 'language features' as you want, and the syntax is really simple, and code is data (a rare need of mine anyway). But Lisp sacrifices the most important thing of all; readability. Everyone tries to read programming languages as close as possible to plain english in their head, but Lisp goes completely against this and makes you write things like (* 1 (+ 2 (/ 3 4))) where you have to glance back and forth to even understand the equation - is 1 * (2 + 3/4) not easier to read? Even in C# the phrase 'if (!(foo is bar))' annoys me because it reads 'if not foo is bar' when I'd like to say 'if foo is not bar'! So I think me and Lisp have no hope.
- klibertp 11y ago> Yes everything is a function No. Read on macros. > and code is data (a rare need of mine anyway) Rare? Read on macros, then on "Blub paradox". > But Lisp sacrifices the most important thing of all; readability. > Everyone tries to read programming languages as close as possible to plain english in their head No. That's too wrong to even seriously argue against. The best I can do is to paste this: http://blog.ppenev.com/parens.png http://blog.ppenev.com/parens.png without any comment. The rest of what you wrote is completely subjective and I don't want to comment on it. But I think you should go and take a look at Smalltalk, which is another awesome langauge with 4 decades of history, which pretty much reads like plain English.
- hacker_9 11y agoI have read through Paul Grahams essays a few times and do respect his opinion, but I just can't see it myself. The parenthesis are actually the least bit I have a problem with (as the indentation generally makes flow clear). But the actual function within a function with a function syntax and so on just seems to me to hinder the reading of the code and thus the understanding, maintenance and modification of it.
- klibertp 11y ago
- sabya 11y ago>You can imagine Lisp grammar like Pac Man eating the dots: ᗧ••••, and there is no ghosts here. Pac Man is the function in Lisp, and the dots are arguments. After Pac Man eat up all the dots (the function is executed with all these arguments), it becames a dot: • . and a dot is able to be eaten by another Pac Man. Simplest explanation of Lisp grammar I've read!
- nickpsecurity 11y agoIt's funny until you look at XML so many love and wonder why they hated LISP syntax at same time. http://www.defmacro.org/ramblings/lisp.html http://www.defmacro.org/ramblings/lisp.html
- e12e 11y agoPeople loved XML syntax? My impression was that the only thing wrong with XML was the syntax (hence the JSON revolution). After all, apart from syntax, possibly some of the ill-advised "external element" stuff ... I think XML is strictly better in every meaningful sense than JSON.
- nickpsecurity 11y agoThey did. Especially web design crowd. Its syntax and tech are crap, though, compared to what came before it. Another lesson never learned by mainstream IT. That amount of developer and user effort would've achieved more results by using superior technology. Already gave a nice comparison here: https://news.ycombinator.com/item?id=10044598 https://news.ycombinator.com/item?id=10044598
- pjtr 11y agoI'm guessing because they already knew HTML, so it seemed familiar and easy to learn to them. Similar to how many programmers prefer crazy (but familiar) C-like syntax (C, C++, C#, Java, PHP, Javascript, ...) and dismiss anything that looks remotely unfamiliar even if much saner (Lisp, Pascal, ML, ...).
- murftown 11y agoNice tutorial! Note that your sbcl must be built with threading enabled for the example to work. Otherwise, the initial Lisp landing page will show up at URI /, but the handler for /hello?name=Blah will never be executed because sbcl-without-threading silently fails to use threading and instead runs the server in a blocking way in which later code never gets a chance to run. This was confusing for me at first, but once I built sbcl from source using "./make.sh --fancy" everything worked perfectly.