项目作者: dijonkitchen

项目描述 :
99 Bottles of Beer in Clojure
高级语言: Clojure
项目地址: git://github.com/dijonkitchen/bottles.git
创建时间: 2019-06-16T23:27:13Z
项目社区:https://github.com/dijonkitchen/bottles

开源协议:Eclipse Public License 2.0

下载


bottles

CircleCI

codecov

99 Bottles of Beer in Clojure.

Inspired by https://www.sandimetz.com/99bottles and https://github.com/sandimetz/99bottles

Installation

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

Usage

Full song:

  1. lein run

Options

A single verse:

  1. lein run [verse-number]

Multiple verses:

  1. lein run [starting-verse ending-verse]

Examples

  1. lein run 2
  2. ;; 2 bottles of beer on the wall, 2 bottles of beer.
  3. ;; Take one down and pass it around, 1 bottle of beer on the wall.
  1. lein run 2 1
  2. ;; 2 bottles of beer on the wall, 2 bottles of beer.
  3. ;; Take one down and pass it around, 1 bottle of beer on the wall.
  4. ;; 1 bottle of beer on the wall, 1 bottle of beer.
  5. ;; Take it down and pass it around, no more bottles of beer on the wall.

Testing

  1. lein test

Beliefs/Desires

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.

Process

  1. Documenting hypotheses (this Readme!)
  2. Design
  3. Behavioral testing
  4. Domain modeling
  5. recur

Findings

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.

License

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.