Commit 2db14cdb authored by hayeah's avatar hayeah

Initial Revision

This diff is collapsed.
#!/bin/sed -f
#(#\& "&")
# (#\< "&lt;")
# (#\> "&gt;")
{ s/\&/\&amp;/g
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<html xmlns="" xml:lang="en" lang="en">
<title>Wispy Lisp</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<div class="header">
A SOC project...
Wispy Lisp := A Lispy Web-framework
Howard Yeh
A unified syntax for web-programming.
This web-framework would provide all the necessary tools to
create a respectable, fully dynamic web-application. A
programmer would code in a unified meta-syntax that subsumes
html, css, javascript, sql, and lisp-- effectively blurring
client/server scripting.
HTML/CSS generation should paper over the (perverse)
idiosyncrasies of certain web-browsers, and conform to web
standards. The most infamous being, naturally, the box-model
interpretation. In this case, the framework's generator
should transparently attach the necessary fix
(i.e. box-model hack). User can override this behavior.
Parenscript covers primitive interface scripting. A lisp
syntax to Google's AJAXSLT would allow higher abstraction to
interface programming.
This project would also include a mini data-persistence
language by extending CLSQL. This mini-language would
provide declarative specification of table definitions,
relations, and constraint s. Instead of raw SQL for data
retrieving/storing, a simple pattern matching syntax is
In a typical application under this framework, the
programmer would first specify the app's valid dataset with
a declarative schema. This data schema determines the legal
pattern matching syntax the programmer can use to
access/persist data.
The interface templating system helps the programmer to
establish robust communication channels between client and
server. By declaring "SETFable" places in various
subtemplates, local/remote functions have well defined
places to return their response.
Data Schema:
;; Defines database
;; ;; In later iterations, perhaps redefines database safely.
(def-schemas &lt;schema&gt;)
&lt;schema&gt; := (&lt;table-name&gt; &lt;field&gt;*)
&lt;field&gt; := &lt;simple-field&gt; | &lt;complex-field&gt;
&lt;simple-field&gt; := (&lt;symbol&gt; &lt;data-type&gt;)
&lt;complex-field&gt; := (&lt;relation&gt; &lt;table-name&gt;)
&lt;data-type&gt; := integer | (string &lt;number&gt;) | date
&lt;relation&gt; := :many | :one
;; Example:
(brain (blood-pressure integer)
(color (string 32))
(smell (string 32))
(:many personality)
(:one obsession)
(:many dream))
(personality (complex (string 32))
(mood integer)
(:many brain))
(obsession (nature (string 255))
(shrink (string 32))
(hourly-rate integer))
(dream (expiry-date date)
(price integer))))
The 'id' fields of each schemas are implied. The ':many' relation
generates an auxiliary table, and foreign keys in the related
tables. Similarly, the ':one' relation.
Data Retrieval:
Now that we have a few brains in our database, we can fetch them.
;; Data query mini-language
;; ;; Data persisting is similar
(with-data &lt;variable&gt; &lt;query&gt; &amp;key limit offset)
&lt;query&gt; := (&lt;query-function&gt;? &lt;table-name&gt; &lt;field&gt;*)
&lt;table-name&gt; := (&lt;symbol&gt; &lt;symbol&gt;) | &lt;symbol&gt;
&lt;field&gt; := &lt;field-name&gt; | (&lt;field-name&gt; &lt;test-cond&gt;) | &lt;query&gt;
&lt;test-cond&gt; := (&lt;test-op&gt; &lt;var&gt; &lt;var&gt;*)
&lt;test-op&gt; := &lt; | &lt;= | = | &gt;= | &gt; | or | and
&lt;query-function&gt; := :sum | :max | :min
((b brain) (color (= color "jaundice"))
(smell (or (= smell "rotten")
(= smell "sour")))
((p personality) complex mood
((b2 brain) smell
(blood-pressure (&gt; 150))
((p2 personality) mood))))
(out (h1: "Down the meat grinder:")
(:div (b-smell " stuff and " b-color))
(:div ("Perfectly suited for " b2-mood
" clients with blood-pressure exceeding (or at): "
(:em br-blood-pressure))))
:limit 100)
'let-data' binds the fields of the a matching record to
corresponding symbols (possibly prefixed with table
alias). The second argument provides an action to iterate
over all the matching records. The matching conditions are
collected and combined into the SQL 'where' statement. The
join conditions are generated appropriately as defined by
the schema.
(def-wact ...) ;; Server action
(def-jact ...) ;; Client action
&lt;template&gt; := (&lt;tag&gt; &lt;attribute-pair&gt;* &lt;template&gt;*) | &lt;datum&gt; | &lt;s-exp&gt;
&lt;tag&gt; := &lt;keyword&gt; | &lt;wisp-tag&gt; | &lt;user-tag&gt;
&lt;attribute-pair&gt; := &lt;keyword&gt; &lt;s-exp&gt;
&lt;wisp-tag&gt; := &lt;mk-form&gt; | &lt;mk-target&gt; | &lt;mk-act&gt;
&lt;mk-form&gt; := (mk-form (&lt;symbol&gt;*) &lt;template&gt; &amp;key action)
&lt;mk-target&gt; := (mk-target &lt;symbol&gt; (&lt;target-place&gt;*) &lt;template&gt;)
&lt;mk-act&gt; := (mk-act (s-exp) &amp;key caption)
&lt;target-place&gt; := &lt;symbol&gt; | (&lt;symbol&gt; &lt;s-exp&gt;)
(def-wact enlargement (name age e-mail :key (referral "gink maps"))
(out (:html (:body
(:b :color 'blood-red "LOOK NO FURTHER!! 100% PRIVACY!!!")
(:div :class 'huge-sign
(mk-form (name age e-mail)
(:div :class 'enticing-form
(:input :id name)
(:input :id age)
(:input :id e-mail))
:action (enlargement name age e-mail))
(:a :href (get-partner-url referral)
(mk-act (let ((card-num (prompt "your visa for tiny fee")))
(if (validate card-num)
(redirect 'investment name e-mail age)
(set-target tar1
:caption "DON'T YOU SCAM US!!"
:cuss-word (random-cuss-word))))
:caption (mk-target tar1
(:span caption cuss-word)))))))
This demonstrates a typical use of the templating
system. The 'enlargement' action provides an entry point
into the application. User is redirected to an error page
if arguments don't match. 'mk-form' creates a channel that
redirects back to 'enlargement'.
'mk-act' takes as its first argument an s-exp generate
javascript. If a waction is called inside 'mk-act', the
generator outputs an AJAX remote function call that
transparently return control and result back to client
'waction' and 'jaction' defines, respectively, actions that
are mostly server-scripting or mostly client-scripting.
I will build on these libraries:
TBNL - web front-end
CL-INTERPOL and CL-PCRE - String support
CLSQL - database interface
PostgreSQL - database
CL-WHO - templating
Parenscript or Peter Seibel's javascript macros
AJAXLST - XLST transform
DOJO or Prototype - AJAX support
May 8 -&gt; May 22
-Finish the first draft of wisp grammar.
May 25 -&gt; June 26
- Implement the first draft (or working subset of it).
a) Schema definition polish. (2 days)
b) Data manipulation polish. (2 days)
c) Template. (18 days)
d) Local/remote function call channel. (7 days)
July 1 -&gt; July 30
- Choose one extra feature to implement.
a) Integrate Prototype. (10 days)
b) Schema redefinition. (10 days, if time permits)
c) Integrate AJAXSLT. (10 days, if time permits)
August 1 -&gt; August 15
- Wrap up.
a) Documentation. (5 days)
b) Demo. (10 days)
<p>Back to <a href=""></a>.</p>
<div class="check">
<a href="">Valid XHTML 1.0 Strict</a>
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment