Mercurial > repos > other > SevenLanguagesInSevenWeeks
comparison 6-Clojure/bearings.clj @ 83:eccc649d49a2
Add Day 2 and Day 3 notes and example code
Clojure STILL doesn't make much sense in lots of places
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 08 Jun 2019 21:23:27 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
82:cf7182bca068 | 83:eccc649d49a2 |
---|---|
1 ; Based on Compass | |
2 (def directions [:north :east :south :west]) | |
3 | |
4 ; Define a "fixed movement" protocol - "m" is effectively "this" | |
5 (defprotocol FixedMovement | |
6 (direction [m]) ; Find your current direction | |
7 (left [m]) ; turn left one position | |
8 (right [m])) ; turn right one position | |
9 | |
10 ; Define an implementation with a single field (not a parameter - although it's defined the same) | |
11 (defrecord CompassBearings [bearing] | |
12 ; Specify which protocol we're implementing | |
13 FixedMovement | |
14 ; And define the methods | |
15 (direction [_] (directions bearing)) ; Look-up our index in the list | |
16 ; Clojure uses immutable values, so these functions create new CompassBearing objects | |
17 (left [_] (CompassBearings. (mod (- bearing 1) (count directions)))) ; Create a new instance (ClassName.) with a value from rotating one slot left | |
18 (right [_] (CompassBearings. (mod (+ bearing 1) (count directions)))) | |
19 ; And we can specify more | |
20 Object | |
21 (toString [this] (str "[" (direction this) "]")) ; Presumably we could also call (directions bearing) directly. | |
22 ; 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. | |
23 ) | |
24 | |
25 ; Define a thing that has bearings - e.g. an actor in a scene | |
26 ; It'd be nice if we could do an automated default so that we're not passing in magic numbers | |
27 (def actor (CompassBearings. 0)) | |
28 (println actor) ; Prints default internal format | |
29 (println (:bearing actor)) ; Access a field using the keyword as a function. Because keywords with meaning happen EVERYWHERE in Clojure! | |
30 (println (str actor)) ; Uses our toString method | |
31 (println (str (left actor))) | |
32 (println (str (right (right actor)))) | |
33 |