Mercurial > repos > other > SevenLanguagesInSevenWeeks
view 6-Clojure/bearings.clj @ 89:7e4afb129bef
Add initial Day 2 notes with functions, partially applied, and currying
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 15 Jun 2019 21:07:27 +0100 |
parents | eccc649d49a2 |
children |
line wrap: on
line source
; Based on Compass (def directions [:north :east :south :west]) ; Define a "fixed movement" protocol - "m" is effectively "this" (defprotocol FixedMovement (direction [m]) ; Find your current direction (left [m]) ; turn left one position (right [m])) ; turn right one position ; Define an implementation with a single field (not a parameter - although it's defined the same) (defrecord CompassBearings [bearing] ; Specify which protocol we're implementing FixedMovement ; And define the methods (direction [_] (directions bearing)) ; Look-up our index in the list ; Clojure uses immutable values, so these functions create new CompassBearing objects (left [_] (CompassBearings. (mod (- bearing 1) (count directions)))) ; Create a new instance (ClassName.) with a value from rotating one slot left (right [_] (CompassBearings. (mod (+ bearing 1) (count directions)))) ; And we can specify more Object (toString [this] (str "[" (direction this) "]")) ; Presumably we could also call (directions bearing) directly. ; We have to pass something to (direction) because we're doing functions and so can't do "obj.function()" to keep the reference to what we're getting directions of. ) ; Define a thing that has bearings - e.g. an actor in a scene ; It'd be nice if we could do an automated default so that we're not passing in magic numbers (def actor (CompassBearings. 0)) (println actor) ; Prints default internal format (println (:bearing actor)) ; Access a field using the keyword as a function. Because keywords with meaning happen EVERYWHERE in Clojure! (println (str actor)) ; Uses our toString method (println (str (left actor))) (println (str (right (right actor))))