4 ms·
In Common Lisp (without cheating or handwaving; this is it): (defpackage :add-nums (:use :cl :hunchentoot :cl-who)) (in-package :add-nums) (def
by mahmud 16y ago
In Common Lisp (without cheating or handwaving; this is it):
(defpackage :add-nums
(:use :cl :hunchentoot :cl-who))
(in-package :add-nums)
(defmacro with-html (&body body)
`(with-html-output-to-string (*standard-output* nil :prologue t :indent t)
,@body))
(define-easy-handler (add-nums :uri "/add-nums")
((a :parameter-type 'integer)
(b :parameter-type 'integer))
(with-html
(:html
(:head (:title "Add two numbers"))
(:body
(if (and a b)
(htm (:p (str (+ a b)))))
(:form :method :get
(:input :type :text :name "a")
(:input :type :text :name "b")
(:input :type :submit))))))
(defparameter *site* (make-instance 'acceptor :port 8080))
(start *site*)
- swannodette 16y agoEr, Clojure has CL style macros so you can easily get to this level of brevity if that is desired.
- mahmud 16y agoThe one custom macro I wrote is already in there. The rest is just the web server and cl-who. I have been screaming for ages telling Clojurists to rip CL APIs and implement them in clojure. They're more tasteful and cultured than that entrerprisey crap that java is smearing all over this nice Lisp dialect. The majority of open source clojure code that I have seen looks like Java FFI stubs; you need to tuck those loose ends in and tidy them up with macros. But this probably wont happen until Clojure is ported to another runtime/platform; portability is a surefire way to distill the essence of a language from its implementation detail.
- ghotli 16y ago"I have been screaming for ages telling Clojurists to rip CL APIs and implement them in clojure." Care to help? If you feel this strongly about it, surely you can contribute to the community.
- mahmud 16y agoFor the same reason that everyone who retweeted an #iranelection did not book a flight to Tehran to fight with their comrades. I have things to do, and my immediate needs to take care of: that pretty much means Common Lisp, which I depend on for my work. My advice is just that, advice, and it's given in the hope that with our mutual situations improved, maybe we can meet for coffee somewhere down the road and kick it back.
- swannodette 16y agoI won't venture to saying anything about CL libs - I don't know or use them. But clearly you don't know much about the Clojure library landscape. All the ones I use are Lisp-y and delicious.
- weavejester 16y agoWhat's so great about the CL APIs for web applications? Could you provide some examples?
- ataggart 16y agoBut you are cheating: * you've omitted code to control the output content-type and the associated response headers (xhtml vs html) * you've removed text, formatting from the form page * you've discarded the results page altogether * you aren't properly distinguishing between GET and POST Do the same to the clojure code and it'll be about the same length as well.
- mahmud 16y agoYour requests, when they're valid, are embarrassingly simple one-liners. you've omitted code to control the output content-type and the associated response headers (xhtml vs html) Add this single line to your WITH-HTML macro. (setf (html-mode) :xml) ; for XML or :sgml for HTML. http://weitz.de/cl-who/#html-mode http://weitz.de/cl-who/#html-mode you've removed text, formatting from the form page Add one line for a CSS file inclusion and style it to your heart's content. In real web apps I use html-template to template the code, and do not sloppily generate html like I did with the example; but I had to do what the clojure code did, in the same manner. you've discarded the results page altogether I am printing the results on the same page. Yeah, that's a better usability. you aren't properly distinguishing between GET and POST Says who? the DEFINE-EASY-HANDLER takes arguments, which correspond to the submitted form elements, via GET or POST. In fact, that macro also does some type conversion for you as well; since you declared your parameters to be integers they will be converted to integers when you get them, and not remain strings. This stuff is built into the web server. http://weitz.de/hunchentoot/#define-easy-handler http://weitz.de/hunchentoot/#define-easy-handler If you're gonna implement a full REST then you have no business generating your display html from within your container. What else do you think I omitted?
- ataggart 16y agoIt would have been easier and no less accurate for you to write, "yes, my cl code was shorter only because I omitted a bunch of stuff." If you're going to start a dick-waving contest, at least man-up and write your code so it has the same behavior.
- 16y ago
- weavejester 16y agoThe equivalent Clojure code is actually a few lines shorter than your example: (ns add-nums (:use compojure.core [hiccup core page-helpers] ring.adapter.jetty)) (defroutes handler (GET "/add-nums" [a b] (let [a (Integer/parseInt a) b (Integer/parseInt b)] (html [:html [:head [:title "Add two numbers"]] [:body (if (and a b) [:p (+ a b)]) (form-to [:get "/add-nums"] (text-field :a) (text-field :b) (submit-button))]]))) (run-jetty handler {:port 8080}) Mark's tutorial code is a little more complete than your example, and doesn't aim for brevity. It also doesn't use any of the form functions from Hiccup (admittedly, they're not as well documented as they could be).
- mahmud 16y agoFinally, an actual programmer's response. Thank you! It's good to know that verbosity was for the sake pedagogy and completeness, and not necessity.