the new release of ABCL-web (a web-framework using Armed Bear Common Lisp
as a Java Servlet) includes bindings to Jena Semantic Web Framework that
make possible useage of RDF-style database (triple store) in web
applications.
together with it's web-engine, this makes very easy and kewl web
application development experience (well, there are some glitches
because of lack of maturity, so it might be not really easy, but it's
ok for demo purposes).
you can find brief overview, feature highlights and examples below,
for general info about ABCL-web go here: http://abcl-web.sf.net/
the ABCL-web's web-engine appears to be easiest 'web programming framework'
i've seen so far, i find it very good for prototyping, but it might be not
acceptable for 'real' use so far. this engine (actually there's a bit of
irony calling it engine, since it's actually just two macros) is based on
a continuation-passing style, although it doesn't do CPS-transformation
automatically (as opposed to thing i did before) and requires programmer
to explicitly specify action (code) that would be called when user submits
a form or uses a link. for example:
(html
(:p (action-link "click here" (form-called param param param))))
this will produce a <p> tag with a link labeled "click here", when user
will click there, code will be executed. action-link is a macro that
creates a closure and associates ID with it, and then creates a HTML link
for that ID. the second macro does this for HTML form:
(action-form
(((:input :name "a"))
((:input :name "b"))
(form-submit "add"))
(with-form-fields (a b) (show-result-page a b)))
so it's possible to define a form with inputs, and immidiately define an
action for this form, that will be able to use input values. i find this
way is very handy, and it's made handy because of uniform Lisp syntax,
that allows to make HTML presentation code and application code look same
and be used together.
you can find description of this web-engine here:
http://abcl-web.sf.net/web-engine.html
but it gets more interesting with RDF bindings -- it's possible to query
data from triple store and manipulate that data with same uniform syntax,
and even do relatively complex queries (with multiple JOINs in SQL terms)
naturally embedded into LML2 HTML templates. these queries are implemented
via a wrapper that creates SPARQL queries programmatically (luckily, it's
straightforward with ARQ library), and a macro
that automagically binds data into query and fetches it back into variables.
here's an example:
(rdf-do-query
((?user :username ?uname) ;query expressed as triple patterns
(?user :salary ?salary) ;where ?xxx are variables
(?user :department ?dept)
(?dept :name ?dept-name))
(html
(:tr
(:td (:princ ?uname))
(:td (:princ ?dept-name))
(:td (:princ ?salary)))))))
(if you don't know how RDF and triple store stuff work, you can find
some description here: http://abcl-web.sf.net/rdf.html)
compared to SQL, ORM-wrappers and CLOS object persistence, i find this
triple store stuff more convenient -- it can be as easy as using CLOS
objects:
CLOS: (setf (slot-value *user* :name) "udo")
RDF: (setf (rdf-prop :name *user*) "udo")
CLOS: (user-name *user*) => "udo"
RDF: (rdfp:name *user*) => "udo"
but it's more powerful than generic CLOS -- it's able to do queries,
for example, it's able to find user by name:
(rdf-query-1 (? :name "udo"))
and it's able to do complex queries for a whole triple pattern,
fetching multiple values -- with a straightforward syntax that is
easier that SQL JOINs. RDF queries can be done efficiently -- underlying
RDF/SPARQL implementation -- Jena/ARQ -- can work with SQL tables, rewriting
RDF queries into SQL ones. or it can work with special database.
also, as one of important features that add a lot to easyness of use, it
doesn't need a defined 'schema' -- all those properties can be defined on
fly.
while it's arguable if it's a plus, we are using dynamic language (Common
Lisp), thus it's quite natural to use dynamic database, at least for
prototyping..
it's possible to add RDFS or similar schema support later if needed
(actually,
Jena suports that, so only some bindings should be added). there's one more
connected feature that is not yet used -- inference is posible in RDF, but
i find it a bit too complex, so i've focused only on simple things so far.
so, if you're interested, you can find more detailed RDF bindings
description
here: http://abcl-web.sf.net/rdf.html and check a demo application:
http://abcl-web.sf.net/tutorial.html