Last active
November 24, 2015 12:45
-
-
Save mveytsman/9d77ab50a92e9a592d29 to your computer and use it in GitHub Desktop.
expression problem in clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns expression-problem) | |
;; Shapes have area | |
(defprotocol Areable | |
(area [this])) | |
;; We have circles | |
(defrecord Circle [radius]) | |
;; Circles have area | |
(extend-type Circle | |
Areable | |
(area [{radius :radius}] (* Math/PI radius radius))) | |
(def my-circle (Circle. 5)) | |
(assert (== (area my-circle) (* Math/PI 25))) | |
;; We have squares | |
(defrecord Square [side]) | |
;; Squares have area | |
(extend-type Square | |
Areable | |
(area [{side :side}] (* side side))) | |
(def my-square (Square. 5)) | |
(assert (== (area my-square)) 25) | |
;; Now we want to add perimeters | |
(defprotocol Perimeterable | |
(perimeter [this])) | |
;; Circles and Squares have perimeters | |
(extend-protocol Perimeterable | |
Circle | |
(perimeter [{radius :radius}] (* 2 Math/PI radius)) | |
Square | |
(perimeter [{side :side}] (* 4 side))) | |
(assert (== (perimeter my-circle) (* 10 Math/PI))) | |
(assert (== (perimeter my-square) 20)) | |
;; Now we want to add triangles | |
(defrecord Triangle [a b c]) | |
;; Triangles have areas and perimeters | |
(extend-type Triangle | |
Areable | |
;; The hardest part of solving the expression problem in Clojure is looking up highschool geometry | |
;; Heron's formula | |
(area [{:keys [a b c]}] | |
(let [s (/ (+ a b c) 2)] | |
(Math/sqrt (* s (- s a) (- s b) (- s c))))) | |
Perimeterable | |
(perimeter [{:keys [a b c]}] (+ a b c))) | |
(def my-triangle (Triangle. 3 4 5)) | |
(assert (== (area my-triangle) 6. | |
(assert (== (perimeter my-triangle) 12)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment