Advertisement
IzhanVarsky

Untitled

Apr 28th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.99 KB | None | 0 0
  1. (defn proto-get [obj key]
  2. (cond
  3. (contains? obj key) (obj key)
  4. :else (proto-get (:prototype obj) key)))
  5.  
  6. (defn field [key] (fn [name] (proto-get name key)))
  7. (defn method [key] (fn [this & args] (apply (proto-get this key) (cons this args))))
  8.  
  9. (def evaluate (method :evaluate))
  10. (def toString (method :toString))
  11. (def diff (method :diff))
  12. (def operands (field :operands))
  13.  
  14. (defn Constant [value]
  15. {
  16. :evaluate (fn [_ _] value)
  17. :toString (fn [_] (format "%.1f" value))
  18. :diff (fn [_ _] (Constant 0))
  19. })
  20.  
  21. (defn Variable [name]
  22. {
  23. :evaluate (fn [_ map] (get map name))
  24. :toString (fn [_] (str name))
  25. :diff (fn [_ v] (if (= v name) (Constant 1) (Constant 0)))
  26. })
  27.  
  28. (defn OperationFactory [action symbol howToDiff]
  29. (fn [& args]
  30. {:prototype {:evaluate (fn [this vars]
  31. (apply ((field :action) this) (mapv #(evaluate % vars) (operands this))))
  32. :toString (fn [this]
  33. (str "("
  34. ((field :symbol) this)
  35. (apply str (mapv #(str " " (toString %)) (operands this)))
  36. ")"))}
  37. :action action
  38. :symbol symbol
  39. :diff howToDiff
  40. :operands args}
  41. ))
  42.  
  43. (defn simple-diff [OP this v] (apply OP (mapv #(diff % v) (operands this))))
  44. ;(def simple-diff #(fn [this v] (apply % (mapv (fn [x] (diff x v)) (operands this)))))
  45. (def Add (OperationFactory + "+" #(apply simple-diff Add %&)))
  46. ;(def Add (Operation + "+" (simple-diff Add)))
  47. (def Subtract (OperationFactory - "-" #(apply simple-diff Subtract %&)))
  48. (def Negate (OperationFactory - "negate" #(apply simple-diff Negate %&)))
  49.  
  50. (def Multiply
  51. (OperationFactory
  52. *
  53. "*"
  54. (fn [this v] (apply Add
  55. (mapv (fn [x] (apply Multiply
  56. (mapv (fn [y] (if (identical? x y) (diff x v) y))
  57. (operands this))))
  58. (operands this))))))
  59.  
  60. (defn nth-among-operands [this x] (nth (operands this) x))
  61.  
  62. (def Divide
  63. (OperationFactory
  64. (fn rec
  65. ([a b] (/ (double a) b))
  66. ([a b & more] (apply rec (rec a b) more)))
  67. "/"
  68. (fn [this v]
  69. (Divide
  70. (Subtract
  71. (Multiply (diff (nth-among-operands this 0) v) (nth-among-operands this 1))
  72. (Multiply (nth-among-operands this 0) (diff (nth-among-operands this 1) v)))
  73. (Multiply (nth-among-operands this 1) (nth-among-operands this 1))))))
  74.  
  75. (def obj-operations {'+ Add
  76. '- Subtract
  77. '* Multiply
  78. '/ Divide
  79. 'negate Negate
  80. })
  81.  
  82. (defn parseList [s]
  83. (if (list? s)
  84. (apply (get obj-operations (first s)) (map parseList (rest s)))
  85. (if (number? s)
  86. (Constant s)
  87. (Variable (str s)))
  88. )
  89. )
  90. (def parseObject #(parseList (read-string %)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement