I think one of the things that made Ruby on Rails so popular was the screencasts where you could write a blog site in 20 minutes, integrate with Flickr in 5 minutes, or setup database migrations in 20 minutes. It’s hard to overstate how mindblowing those were in 2005 (or whenever they came out). At that point, the only languages I had ever used were Pascal, C, C++ (all in school) and C#/.Net (in jobs). I was used to (and blind to) the big, industrial scale, industrial pain in the butt that those languages consist of. Ruby on Rails just seemed to dance, seemed so easy and flexible. I didn’t ever end up getting into RoR, but interest in it did start me on the language learning, abstraction seeking path I’m on today.
Lisp happens to have a number of similar screencasts. I’ve looked at a couple of them, both by Marco Barringer. I watched the first half of the SLIME movie and was blown away (I only watched the first half because 3:30am isn’t a great time to stay awake through a screencast). He was just throwing out tricks right and left: Linux tricks, emacs tricks, slime tricks, Lisp tricks. I kept rewinding and rewatching parts, like a bunch of Cub Scouts trying to figure out how a magician makes a handkerchief disappear. I have installed and played with emacs and SLIME, but I didn’t get the gist of what it could do. Everyone said it’s so powerful, and I believed them. They said it was extensible and reprogrammable, but I’m not ready to take on that. I tried looking at the documentation, but everything is presented so evenly that I couldn’t get a sense of where to start. I decided that the SLIME movie was too good of documentation to be stuck inside a non-search-indexable video format, so I re-downloaded it and started watching it, frequently pausing and taking meticulous notes on key chords, exact times that different things happen, and setup commands, with the intention that the lessons it contains could easily be referred to later. Well, I had to stop that because my download is corrupted, I only have the first 8 minutes, and right now the download link isn’t working. So I moved on to the next video (which was actually the first video), the UCW “Hello World” screencast (download 51MB .mov or torrent).
In this 20 minute video, Marco created a simple website using UCW, the UnCommon Web application framework (that Marco created). The focus was teaching how to write a simple site and what each of the commands and components means, so it was a little slower and had less “zing” than the RoR screencasts, which just demonstrated how quick it was to work with without waiting for you to figure out what’s going on. Also, since it was focused on the basics of UCW, it didn’t give a good feel for how powerful UCW actually is. I think it would be a great Part I in a series of screencasts showing the progression to use more and more of the power of the framework. Regardless, I have my notes anyway. I haven’t done any special formatting or cleaning up. I plan on doing this for more of the Lisp movies and I’ll wait until I’ve found a style I like, then go back and clean them up. The only thing special is that actual Lisp code is marked with “—” on the lines immediately above and below it. Here goes:
Assume UCW is already downloaded and installed and ready to run
0:14 Startup Script
cd lisp/ucw
openmcl -l bin/start.lisp
0:27 Apache and mod_lisp as backend
0:38 example application
http://127.0.0.1:8080/ucw/examples/index.ucw
1:11 go to emacs
M-x slime, 127.0.0.1, 4005
1:23 change directory
Command: !d
~/lisp/ucw/examples
1:27 setup package
Command: !p
Package: IT.BESE.UCW-USER
2:00 new file
~/lisp/ucw/examples/hello.lisp
—-
(in-package :it.bese.ucw.user)
(defvar *hello-world*
(make-instance ‘cookie-session-application :url-prefix “/hello/”)) ;applications are regular CLOS instances
(register-application *default-server* *hello-world*) ;tell server to handle requests for this application
; generally all UCW installations just use the default server object
—-
3:34 Entry Point – publicly accislble url that represents the way users begin to interact with the app
—-
(defentry-point “index.ucw” (:application *hello-world*) ()
(call ‘hello-world-home-page)) ; UCW UI is represented by components – objects
(defcomponent hello-world-home-page (simple-window-component) ;subcomponent since it has to manage the whole page
())
(defmethod render-on ((hello hello-world-home-page)) ; specify how components are transformed to HTML
(<:p “Hello, World!”))
—-
6:00 Compile file, get error in render-on
—-
(defmethod render-on ((res response) (hello hello-world-home-page)) ; specify how components are transformed to HTML
(<:p “Hello, World!”))
; most render-on methods can ignore the response object
—-
6:39 Go to browser
http://127.0.0.1:8080/hello/index.ucw
Page Source – other HTML generated by simple-window-component
7:22 finding render-on for simple-window-component
M-. (search for simple-window-component)
7:56 Title tags
—
(defentry-point “index.ucw” (:application *hello-world*) ()
(call ‘hello-world-home-page :title “Hello, World!”)) ; UCW UI is represented by components – objects
—
8:36 Macro expansion: C-c RET
8:53 recompile and go back to browser
9:07 title and other things set in defcomponent, not defentry-point
undo last code change
—-
(defcomponent hello-world-home-page (simple-window-component) ;subcomponent since it has to manage the whole page
()
(:default-initargs :title “Hello, World!”))
—-
9:54 review of first part
10:14 improve app, ask for name, create personalized greeting
—
(defentry-point “index.ucw” (:application *hello-world*) ()
(let ((name (call ‘hello-world-home-page))) ; name input form will be on hello-world-home-page
(call ‘personalized-greeting :name name))) ; new page = passing control to another component
—
11:12 adding form to home page
—
(defmethod render-on ((res response) (hello hello-world-home-page)) ; specify how components are transformed to HTML
(<:p “Hello, World!”)
(let ((name “”))
(<ucw:form
:action (ok hello name) ; actions are special methods
(<ucw:input :type “text” :accessor name)
(<:submit))))
—
13:15 compile and go back to browser
13:40 common mistake – didn’t define personalized-greeting component
—
(defcomponent personalized-greeting (simple-window-component)
((name :accessor name :initart :name))
(:default-initargs :title “Greetings!”))
(defmethod render-on ((res response) (greeting personalized-greeting))
(<:p “Hi, ” (<:as-html (name greeting)) “, how are you?”))
—
14:59 compile and return to SLIME debugger, hit RETRY
15:25 back to browser – name rendered
15:47 back to emacs
15:59 all of the logic and code about page flow is contained in defentrypoint “index.ucw”
16:30 let the user supply name multiple times and get multiple greeting pages
16:53 make (call ‘personalized-greeting :name name) terminate
—
(defmethod render-on ((res response) (greeting personalized-greeting))
(<:p “Hi, ” (<:as-html (name greeting)) “, how are you?”))
(<ucw:a :action (ok greeting) “Done.”))
—
17:28 recompile
17:38 add loop to defentry-point
—
(defentry-point “index.ucw” (:application *hello-world*) ()
(loop
(let ((name (call ‘hello-world-home-page)))
(call ‘personalized-greeting :name name))))
—
17:53 back to browser – Done link appears, but doesn’t link right
18:10 back to emacs
component is still using code for old enty point, so start fresh from the URL
19:30 Conclusion and wrapup
entry points = URLs that correspont to the beginning of a page flow, definition of page flow
components = pages in the page flow
render-on = how to make each component into HTML
20:15 final code
—
(in-package :it.bese.ucw.user)
(defvar *hello-world*
(make-instance ‘cookie-session-application :url-prefix “/hello/”))
(register-application *default-server* *hello-world*)
(defentry-point “index.ucw” (:application *hello-world*) ()
(loop
(let ((name (call ‘hello-world-home-page)))
(call ‘personalized-greeting :name name))))
(defcomponent hello-world-home-page (simple-window-component)
()
(:default-initargs :title “Hello, World!”))
(defmethod render-on ((res response) (hello hello-world-home-page)) ; specify how components are transformed to HTML
(<:p “Hello, World!”)
(let ((name “”))
(<ucw:form
:action (ok hello name) ; actions are special methods
(<ucw:input :type “text” :accessor name)
(<:submit))))
(defcomponent personalized-greeting (simple-window-component)
((name :accessor name :initart :name))
(:default-initargs :title “Greetings!”))
(defmethod render-on ((res response) (greeting personalized-greeting))
(<:p “Hi, ” (<:as-html (name greeting)) “, how are you?”))
(<ucw:a :action (ok greeting) “Done.”))
ch3laru says
You can watch free Hello World or watch it online.also you can watch all the new movies or downloaded. iwatch-free-movies-online.com