Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn proto-get [obj key]
- (cond
- (contains? obj key) (obj key)
- :else (proto-get (:prototype obj) key)))
- (defn field [key] (fn [name] (proto-get name key)))
- (defn method [key] (fn [this & args] (apply (proto-get this key) (cons this args))))
- (def evaluate (method :evaluate))
- (def toString (method :toString))
- (def diff (method :diff))
- (def operands (field :operands))
- (defn Constant [value]
- {
- :evaluate (fn [_ _] value)
- :toString (fn [_] (format "%.1f" value))
- :diff (fn [_ _] (Constant 0))
- })
- (defn Variable [name]
- {
- :evaluate (fn [_ map] (get map name))
- :toString (fn [_] (str name))
- :diff (fn [_ v] (if (= v name) (Constant 1) (Constant 0)))
- })
- (defn OperationFactory [action symbol howToDiff]
- (fn [& args]
- {:prototype {:evaluate (fn [this vars]
- (apply ((field :action) this) (mapv #(evaluate % vars) (operands this))))
- :toString (fn [this]
- (str "("
- ((field :symbol) this)
- (apply str (mapv #(str " " (toString %)) (operands this)))
- ")"))}
- :action action
- :symbol symbol
- :diff howToDiff
- :operands args}
- ))
- (defn simple-diff [OP this v] (apply OP (mapv #(diff % v) (operands this))))
- ;(def simple-diff #(fn [this v] (apply % (mapv (fn [x] (diff x v)) (operands this)))))
- (def Add (OperationFactory + "+" #(apply simple-diff Add %&)))
- ;(def Add (Operation + "+" (simple-diff Add)))
- (def Subtract (OperationFactory - "-" #(apply simple-diff Subtract %&)))
- (def Negate (OperationFactory - "negate" #(apply simple-diff Negate %&)))
- (def Multiply
- (OperationFactory
- *
- "*"
- (fn [this v] (apply Add
- (mapv (fn [x] (apply Multiply
- (mapv (fn [y] (if (identical? x y) (diff x v) y))
- (operands this))))
- (operands this))))))
- (defn nth-among-operands [this x] (nth (operands this) x))
- (def Divide
- (OperationFactory
- (fn rec
- ([a b] (/ (double a) b))
- ([a b & more] (apply rec (rec a b) more)))
- "/"
- (fn [this v]
- (Divide
- (Subtract
- (Multiply (diff (nth-among-operands this 0) v) (nth-among-operands this 1))
- (Multiply (nth-among-operands this 0) (diff (nth-among-operands this 1) v)))
- (Multiply (nth-among-operands this 1) (nth-among-operands this 1))))))
- (def obj-operations {'+ Add
- '- Subtract
- '* Multiply
- '/ Divide
- 'negate Negate
- })
- (defn parseList [s]
- (if (list? s)
- (apply (get obj-operations (first s)) (map parseList (rest s)))
- (if (number? s)
- (Constant s)
- (Variable (str s)))
- )
- )
- (def parseObject #(parseList (read-string %)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement