Hello,
2009/3/21 Victor Rodriguez <vict...@gmail.com> > > Here is something I wrote as a Clojure learning exercise. > > I have a suspicion that a serious implementation of this may exist, > please let me know if that is so! In common lisp, there is cl-interpol (for String INTERPOLation) : http://www.weitz.de/cl-interpol/ Your f* function, in terms of data, splits a list into chunks into a seq, and then converts each element of the list in either code, either String part, so you can do this an order of magnitude more concise by using map : (defn f* "Convert a string with ''unquoted'' forms into a list of strings and forms." [s] (loop [tokens (tokenize s) form '(str )] (if-let [token (first tokens)] (recur (rest tokens) (conj form (to-form token))) (reverse form)))) becomes (defn f* "Convert a string with ''unquoted'' forms into a list of strings and forms." [s] (cons 'str (map to-form (tokenize s)))) Ah, and currently it is not possible to use nested levels of parens in expressions, e.g. (f "3 * 4 + 1=~(+ (* 3 4) 1)") does not work. HTH, -- Laurent > ;;; A toy to experiment with Clojure macros. > ;;; > ;;; (f "1 + 2 = ~(+ 1 2)") results in "1 + 2 = 3" > ;;; > ;;; Know of a real implementation of this? Please Let me know at > ;;; vict...@gmail.com. > > > (defn tokenize > "Split a string into a sequence of plain strings and > ''unquoted'' form-strings. For example, it turns > > \"~a = ~(- b c)\" into (\"~a\" \" = \"~(- b c)\")" > [s] > (let [unquote-re > (re-pattern > (str "~\\([^\\)]*\\)" ; a tilde followed by a paren > "|" > "~\\w+" ; a tilde not followed by an open paren... > "|" > "[^~]+" ; anything that is not a tilde > "|" > "~$"))] ; a tilde at the end > (re-seq unquote-re s))) > > (defn to-form > "Convert a strings to forms. For example, it turns > ''~foo'' and ''~(inc a)'' into 'foo' and '(inc a)', > respectively." > [s] > (if (= \~ (first s)) > (read-string (.substring s 1)) > s)) > > (defn f* > "Convert a string with ''unquoted'' forms into a > list of strings and forms." > [s] > (loop [tokens (tokenize s) > form '(str )] > (if-let [token (first tokens)] > (recur (rest tokens) > (conj form (to-form token))) > (reverse form)))) > > (defmacro f > "Compile time string templates!" > [s] > (f* s)) > > (comment > > (let [s "a + b =" > a 1 > b 2 > m {:title 'chihuahua }] > (f "let ~s ~(+ a b) and the title be ~(:title m)")) > ) > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---