From: Ken A. <kan...@bb...> - 2004-09-01 18:26:23
|
Here's an example of how powerful Scheme can be. You can replace over 5,000 lines of Java with less than 100 lines of Scheme! I've been working with Jena, a Java framework for building Semantic Web applications, with RDF and OWL, http://jena.sourceforge.net. RDF is a XML way of representing Statements of the form of triples like (subject predicate object), but uglier. A set of such statements is called a Model. Jena provides RDQL, an RDF query language. Here's two examples: SELECT ?property WHERE (?person, <vCard:FN>, "John Smith") , (?person, ?property, ?obj) USING vCard FOR <http://www.w3.org/2001/vcard-rdf/3.0#> , rdf FOR <http://www.w3.org/1999/02/22-rdf-syntax-ns#> This says "find the person who's full name is "John Smith" and list the names of the properties he has". SELECT ?resource WHERE (?resource, <info:age>, ?age) AND ?age >= 24 USING info FOR <http://somewhere/peopleInfo#> RDF has a primitive for querying a model to return a sequence of statements that match the given subject predicate and object, which #null meaning "don't care". (.listStatements model subject predicate object) I figured it wouldn't be hard to implement this kind of query language in JScheme. Here are two examples using "http://jena.sourceforge.net/tutorial/RDQL/vc-db-2.rdf" as a model. (select (?property) (join (?person VCARD.FN$ "John Smith") (?person ?property ?object) (from db))) produces: (http://www.w3.org/2001/vcard-rdf/3.0#N) (http://www.w3.org/2001/vcard-rdf/3.0#FN) (http://somewhere/peopleInfo#age) Its macroexpansion is: (map* (lambda (r) (let ((?person (.getSubject r)) (?property (.getPredicate r)) (?object (obj r))) (list ?property))) (let ((source (from db))) (apply append (map* (lambda (r) (let ((?person (.getSubject r))) (jenaq source ?person #null #null))) (jenaq source #null VCARD.FN$ "John Smith"))))) ;;; Select any resource who's age is >= 24. (select (?resource) (filter (>= (string->number ?age) 24) (where (?resource INFO:AGE ?age) (from "http://jena.sourceforge.net/tutorial/RDQL/vc-db-2.rdf")))) produces: ((http://somewhere/JohnSmith/)) Its macroexpansion is: (map* (lambda (r) (let ((?resource (.getSubject r)) (?age (obj r))) (list ?resource))) (filter (lambda (r) (let ((?resource (.getSubject r)) (?age (obj r))) (>= (string->number ?age) 24))) (jenaq (from "http://jena.sourceforge.net/tutorial/RDQL/vc-db-2.rdf") #null INFO:AGE #null))) One might argue that i must have cut some corners, which i have. For example, there is no syntax checking and the query could be written more efficiently (by combining the map* and filter into a single pass). But i can't imagine this taking up much more code. k |