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

Reply via email to