(define cc (make-parameter #f))
(define (input name) `(input ((type "text") (name ,(format "~a" name)))))
(define (submit) `(input ((type "submit"))))
(define (form . body) `(form ((action ,(cc))) ,@body))
(define (a ref . body) `(a ((href ,ref)) ,@body))
(define-syntax page
(syntax-rules ()
[(page x ...) (send/suspend (lambda (k) (cc k) `(html (body ,x ...))))]))
(define (get name req)
(extract-binding/single name (request-bindings req)))
(define (start initial-request)
(define foo (get 'foo (page (form (input 'foo) (submit)))))
(page (a (cc) "click here"))
(page "you said: " foo))What I mean is most of the other posts demo how to do it with some required (exotic) framework. This example is just using the basic web server APIs of the PLT continuation based web server.
In other words in this example, Eli BOTH writes the framework (in the first 9 lines), then uses the framework in the last 4 lines.
PLT's mzscheme is in effect, a very distant cousin to Scheme. If they weren't all eggheads and had at least one attentive marketing person, they would have labeled it some new fangled SuperLispIncarnateNextGeneration (SLING) moniker and received a bit of buzz.
I haven't looked at exactly how PG implemented Arc over MzScheme, but consider this. Much of what he did _could_ be done using no more then PLT mzscheme's out of the box, macro system, custom language module capability and custom reader capability, by anyone. Yes, even you.
In some sense most of Arc is just what anyone does who develops in PLTs Scheme/laguage system, i.e., create their own custom language/DSL. PG's may have done it a bit better, more extensively, with a general purpose intent.
So what is the secret weapon here Arc, or the underlying system that allows someone to create an Arc so easily?
You could, right now, be using PLT MzScheme to do your own Arc(s), your own, just for you and your friends custom language/DSL.
Ruby, Python are cute, and deserve having a user base, but PLT mzscheme is without doubt, the best and most powerful language system out there that "no one talks about."
-----
While Matthew and Robby are the "drivers" (with lots of co-pilots :-) I think that setting this tone early in the project has placed PLT Scheme naturally in a lonely niche: it is a real scripting language with capabilities that rival those of everything out there and it is also a serious academic infrastructure. Typed Scheme -- the first and only sound 'gradual typing' language so far -- is just an example of what I mean. We can publish about this in the flagship research conference on programming languages and at the same time, we are using it for its intended applications. Sam Tobin-Hochstadt is porting a part of DrScheme to Typed Scheme as I type. It is this kind of experiment -- porting a piece that your "life" depends on -- that puts us squarely on the applied side, too.
-- Matthias
-----
It's quite short and set out in a question and answers style. The thing is, it very gently and very subtlety bends your mind around to the Lisp way of thinking. After reading this, SICP seems so much more accessible.
There are also two follow on books - The Reasoned Schemer and The Seasoned Schemer which are again quite short and use the same interactive approach. I haven't had chance to read them yet but they get rave reviews on Amazon
-----
1 - Paste the following code into a new document test.ss and save in servlet example folder (/usr/plt/collects/web-server/default-web-root/servlets/examples/test.ss) If document name test.ss changes, change the module name on first line.
(module test mzscheme (require (lib "servlet.ss" "web-server")) (provide (all-defined)) (define interface-version 'v1) (define timeout +inf.0)
(define cc (make-parameter #f))
(define (input name) `(input ((type "text") (name ,(format "~a" name)))))
(define (submit) `(input ((type "submit"))))
(define (form . body) `(form ((action ,(cc))) ,@body))
(define (a ref . body) `(a ((href ,ref)) ,@body))
(define-syntax page
(syntax-rules ()
[(page x ...) (send/suspend (lambda (k) (cc k) `(html (body ,x ...))))]))
(define (get name req)
(extract-binding/single name (request-bindings req)))
(define (start initial-request)
(define foo (get 'foo (page (form (input 'foo) (submit)))))
(page (a (cc) "click here"))
(page "you said: " foo))
)2 - Start the PLT web server sudo /usr/plt/bin/plt-web-server
3 - Open a web browser and navigate to http://localhost/servlets/examples/test.ss
An easy way to check for errors is to open it in DrScheme, click "Run" and they would be highlighted in red.
-----