99 Bottles of Beer in Clojure.
Inspired by https://www.sandimetz.com/99bottles and https://github.com/sandimetz/99bottles
Download from https://github.com/dijonkitchen/bottles
If you want to do the exercise yourself, you can check out the starting branch with the initial test suite: https://github.com/dijonkitchen/bottles/tree/01-starting-test-suite
Full song:
lein run
A single verse:
lein run [verse-number]
Multiple verses:
lein run [starting-verse ending-verse]
lein run 2
;; 2 bottles of beer on the wall, 2 bottles of beer.
;; Take one down and pass it around, 1 bottle of beer on the wall.
lein run 2 1
;; 2 bottles of beer on the wall, 2 bottles of beer.
;; Take one down and pass it around, 1 bottle of beer on the wall.
;; 1 bottle of beer on the wall, 1 bottle of beer.
;; Take it down and pass it around, no more bottles of beer on the wall.
lein test
Hoping to learn something by exercising functional programming in Clojure to figure out a tough problem in object-orieneted programming.
Wondering if it'll be any easier/simpler.
- Documenting hypotheses (this Readme!)
- Design
- Behavioral testing
- Domain modeling
recur
First two-thirds of book seems useful and relevant to most programmers. Having a great test suite that you can lean on while refactoring is essential to slowly evolving your code. The care taken to explicitly edit one line at a time is an important one, particularly for a real-world, larger problem.
The latter third seemed less relevant for functional programmers (FP) and in particular Clojure users. With FP, you get a lot of the simplicity and performance since most everything is a pure function. Additionally, with Clojure's built-in persistent, immutable data structures, garbage collection is very efficient and object instantiation and memory allocation are not relevant. There doesn't need to be a tradeoff of understanding different objects passing messages and performance with mutable state.
I think the Primative Obsession code smell isn't a bad tradeoff since you don't have the indirection of different objects/instances which are introduced by the Extract Class refactoring pattern. This may break the Law of Demeter, but you get the benefit of a huge set of functions that operate on a few useful primative data strutures.
Copyright © 2019 Jonathan Chen
This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.