Last active
December 29, 2015 09:39
-
-
Save zoldar/7651739 to your computer and use it in GitHub Desktop.
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
;; WARNING: the code here wasn't tested in REPL | |
(ns space-age) | |
(def earth-year-in-seconds 31557600.0) | |
(def orbital-periods | |
{:mercury 0.2408467 | |
:venus 0.61519726 | |
:mars 1.8808158 | |
:jupiter 11.862615 | |
:saturn 29.447498 | |
:uranus 84.016846 | |
:neptune 164.79132}) | |
;; Instead of implicitly creating root bindings for functions I create a "factory" function. | |
(defn solar-age-calculation-for | |
"Returns a function which, when given an age in seconds, calculates age in given planet's solar years." | |
[planet] | |
(if-let [period (orbital-periods planet)] | |
(fn [seconds] | |
(/ seconds (* period earth-year-in-seconds))) | |
(throw (Exception. (str "Invalid planet " planet))))) | |
;; This way, I can easily extend the API with specialized functions for planets. | |
;; Yes, it's a couple more keystrokes to create these than generating them with | |
;; a macro, but the bindings are explicit and easily discoverable when going through | |
;; the code. | |
(def solar-age-on-mercury (solar-age-calculation-for :mercury)) | |
;; If the space of possibilities would be too big to create all possible bindings | |
;; by hand, I would either use the factory function in contexts where there are | |
;; many values to be calculated for a given planet or use a generalized version: | |
(defn solar-age-on [planet period] | |
(partial solar-age-calculation-for planet)) | |
;; The generalized function has additional benefit of allowing for calculation of the value | |
;; for multiple planets. | |
(defn solar-age-for-all-planets [seconds] | |
(into {} (map (juxt identity solar-age-on) (keys orbital-periods) (repeat seconds)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment