On Nov 28, 11:11 pm, Dmitri <[EMAIL PROTECTED]> wrote:
> Thanks for the comments, the prefix notation may indeed be something
> that one gets used to. I find it just fine for most cases, just not
> for mathematical expressions. The example function was not meant as a
> complete solution, but rather as an example of how trivial it is to
> switch between the two notations. I do see how the formatting makes it
> more readable, thanks for pointing that out. It does sound that it's
> largely a matter of what you're used to.

If you are translating formulas it might be worth investing the time
to
create a macro to convert from infix to prefix with precedence rules,
as
well as, creating new operators.  I think Peter Norvig covers
something
akin to this in PAIP.  This is where any lisp truly shines; that is
using
macros to express Domain Specific Languages.  That is at compile/load
time
 morph the code to allow new syntax in the language.

See the following for an example implementation

user> (formula (3 + 4 * 2) / 3)
11/3

===== Example code ====

;; used for order of evaluation table and for valid infix operators
(def +precedence+
     {'rem 5,
      '* 4,
      '/ 3,
      '+ 2,
      '- 1})

;; highest level of precedence
(def +highest-precedence+ (apply max (map val +precedence+)))

(defn- operator?
  "Check if is valid operator"
  ([sym]
     (not (nil? (get +precedence+ sym)))))

(defn- find-lowest-precedence
  "find the operator with lowest precedence; search from left to
right"
  ([seq]
     ;; loop through terms in the sequence
     (loop [idx 0
            seq seq
            lowest-idx nil
            lowest-prec +highest-precedence+]
       ;; nothing left to process
       (if (empty? seq)
         ;; return lowest found
         lowest-idx
         ;; otherwise check if current term is lower
         (let [prec (get +precedence+ (first seq))]
           ;; is of lower or equal precedence
           (if (and prec (<= prec lowest-prec))
             (recur (inc idx) (rest seq)
                    idx prec)
             ;; is of high precedence therefore skip for now
             (recur (inc idx) (rest seq)
                    lowest-idx lowest-prec)))))))

(defn- infix-to-prefix
  "Convert from infix notation to prefix notation"
  ([seq]
     (cond
      ;; handle term only
      (not (seq? seq)) seq
      ;; handle sequence containing one term (i.e. handle parens)
      (= (count seq) 1) (infix-to-prefix (first seq))
      ;; handle all other cases
      true (let [lowest (find-lowest-precedence seq)]
             (if (nil? lowest) ;; nothing to split
               seq
               ;; (a b c) bind a to hd, c to tl, and b to op
               (let [[hd tl] (split-at lowest seq)
                     op (first tl)
                     tl (rest tl)]
                 ;; recurse
                 (list op (infix-to-prefix hd) (infix-to-prefix tl))))))))

(defmacro formula
  "Formula macro translates from infix to prefix"
  ([& equation]
     (infix-to-prefix equation))



--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to