I feel awkward writing mathematical functions as s-exps

Clojure's thread-first macro eases the pain a bit..

..but it's still pretty loaded with parens, and not very clear.

```
(defn quadratic-1 [a b c]
(let [d (* 4 a c),
D (Math/sqrt (- (* b b) d)),
t (* 2 a), -b (- b)]
[(/ (+ -b D) t)
(/ (- -b D) t)]))
```

Clojure's thread-first macro eases the pain a bit..

```
(defn quadratic-2 [a b c]
(let [d (* 4 a c),
D (-> (* b b) (- d) Math/sqrt),
t (* 2 a), -b (- b)]
[(-> -b (+ D) (/ t))
(-> -b (- D) (/ t))]))
```

..but it's still pretty loaded with parens, and not very clear.

We need a math DSL that

*looks infixy*and uses*fewer parens*.
Luckily, we can hack one for ourselves in no time.

**~*~**

**Step 1-**Thread mathematical expressions

`(defmacro math-> "(math-> 1 + 5 * 2 / 3) ;=> (-> 1 (+ 5) (* 2) (/ 3)) ;=> 4" [exp & f-x-pairs] (if (even? (count f-x-pairs)) `(-> ~exp ~@(for [[f x] (partition 2 f-x-pairs)] (list f x))) (throw (Exception. "f-x-pairs should be even."))))`

Step 2-Allow temporary bindings`(defmacro maya "(maya 1 + 5 :as six, six * 2 :as twelve, twelve / 3 * 2) ;=> 8" [& exprs] (let [[exp [_ ?as & next-exprs :as E]] (split-with #(not= :as %) exprs)] (if (empty? E) (cons `math-> exp) `(let [~?as (math-> ~@exp)] (maya ~@next-exprs)))))`

Step 3-Profit?

```
(defn quadratic [a b c]
(maya 4 * a * c :as d,
b * b - d -> Math/sqrt :as D,
2 * a :as t, (- b) :as -b,
-b + D / t :as x1,
-b - D / t :as x2,
[x1 x2]))
```

**~*~**

**Edit:**Here's the original gist.

## No comments:

## Post a Comment