Hi guys, I've been working on a problem where I want the user to be able to input an equation in infix notation which includes variables and convert that to a clojure fn that my program can call later.
i.e. the user inputs the string "a*(b+c)" and i generate the unnamed function (fn [a b c] (* a (+ b c))). note: rather than having (fn [a b c] body), (fn [inputs] body), where inputs is a map and reference to variables is replaces with (get inputs variable), is fine, and possibly even simpler to work with later. Is this possible? or will i have to parse and evaluate the infix string on each call to the function, or come up with some way to compile the code and load it back in? Here is what I have attempted so far: http://github.com/tristan/modelmaker/blob/41844b9376b57c05b457c02ac70dfc39c0935a03/infix_parser.clj My (parse) function expects a string containing an infix equation and returns a vector where the first element is a list of symbols reflecting the prefix version of the equation (i.e. (list '* 'a (list '+ 'b 'c))) and the 2nd element is the list of variables (i.e. (list 'a 'b 'c)). It is called by my macro (parse-infix) that takes the result from (parse) and expands to an unnamed function. At first I thought I had solved it, as calling (parse-infix "a*(b+c)") returned the desired function that i could call. However as soon as i attempted to use it in the form (parse-infix users-input) it falls over with a "Don't know how to create ISeq from: clojure.lang.Symbol" error (examples in code at the bottom of the above file). I have fallen victim here to my own lack of understanding of macros. I now understand my folly and have a better understanding of how macro expansion works, however now I'm stuck as to how to solve this problem. Another thing i've attempted is as follows. I thought that I could simply return an unnamed function which accepts a map (i.e {'a 1 'b 2 'c 3}) and change my (parse) function to insert something along the lines of (list 'get 'inputs variable), such that i can just call (eval prefix). So i wrote this: (defn parse-infix [infix] (let [[f v] (parse infix)] (fn [inputs] (if (= (count inputs) (count v)) (eval f) (throw (Exception. (str "expected " (count v) " inputs, got " (count inputs)))))))) but eval doesn't seem to use the same context as the Thread that calls it, so it complains that it's "Unable to resolve symbol: inputs in this context". I've played a bit with with-bindings as well but cannot seem to get any results from it either. thanks .Tristan
-- 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 Note that posts from new members are moderated - please be patient with your first post. 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