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
-~----------~----~----~----~------~----~------~--~---

Reply via email to