├── 10
├── README.md
├── code.rb
└── code.clj
├── 11
├── playsync
│ ├── doc
│ │ └── intro.md
│ ├── .gitignore
│ ├── test
│ │ └── playsync
│ │ │ └── core_test.clj
│ ├── project.clj
│ ├── README.md
│ ├── src
│ │ └── playsync
│ │ │ └── core.clj
│ └── LICENSE
├── README.md
└── code.clj
├── 12
├── phrasebook
│ ├── PiratePhrases.java
│ ├── pirate_phrases
│ │ ├── Greetings.java
│ │ └── Farewells.java
│ └── PirateConversation.java
├── README.md
├── code.java
└── code.clj
├── 13
├── README.md
└── code.clj
├── 02
├── profiles.clj
├── jack-handy
└── README.md
├── 01
├── clojure-noob
│ ├── .DS_Store
│ ├── doc
│ │ └── intro.md
│ ├── .gitignore
│ ├── src
│ │ └── clojure_noob
│ │ │ └── core.clj
│ ├── test
│ │ └── clojure_noob
│ │ │ └── core_test.clj
│ ├── project.clj
│ ├── README.md
│ └── LICENSE
└── README.md
├── 04
├── fwpd
│ ├── suspects.csv
│ ├── doc
│ │ └── intro.md
│ ├── .gitignore
│ ├── test
│ │ └── fwpd
│ │ │ └── core_test.clj
│ ├── project.clj
│ ├── README.md
│ ├── src
│ │ └── fwpd
│ │ │ └── core.clj
│ └── LICENSE
├── README.md
├── code.js
└── code.clj
├── 08
├── README.md
└── code.clj
├── 03
├── README.md
└── code.clj
├── 07
├── README.md
└── code.clj
├── 09
├── README.md
└── code.clj
├── 06
├── the-divine-cheese-code
│ ├── doc
│ │ └── intro.md
│ ├── .gitignore
│ ├── test
│ │ └── the_divine_cheese_code
│ │ │ └── core_test.clj
│ ├── project.clj
│ ├── README.md
│ ├── src
│ │ └── the_divine_cheese_code
│ │ │ ├── core.clj
│ │ │ └── visualization
│ │ │ └── svg.clj
│ └── LICENSE
├── README.md
└── code.clj
├── 05
├── README.md
├── code.rb
├── code.js
└── code.clj
└── README.md
/02/profiles.clj:
--------------------------------------------------------------------------------
1 | {:user {:plugins [[cider/cider-nrepl "0.8.1"]]}}
2 |
--------------------------------------------------------------------------------
/01/clojure-noob/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/braveclojure/cftbat-code/HEAD/01/clojure-noob/.DS_Store
--------------------------------------------------------------------------------
/04/fwpd/suspects.csv:
--------------------------------------------------------------------------------
1 | Edward Cullen,10
2 | Bella Swan,0
3 | Charlie Swan,0
4 | Jacob Black,3
5 | Carlisle Cullen,6
--------------------------------------------------------------------------------
/08/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 8: Writing Macros
2 |
3 | [`code.clj`](code.clj) has all the code from the chapter.
4 |
--------------------------------------------------------------------------------
/03/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 3: Do Things: A Clojure Crash Course
2 |
3 | [`code.clj`](code.clj) has all the code from the chapter.
4 |
--------------------------------------------------------------------------------
/04/fwpd/doc/intro.md:
--------------------------------------------------------------------------------
1 | # Introduction to fwpd
2 |
3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
4 |
--------------------------------------------------------------------------------
/11/playsync/doc/intro.md:
--------------------------------------------------------------------------------
1 | # Introduction to playsync
2 |
3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
4 |
--------------------------------------------------------------------------------
/07/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 7: Clojure Alchemy: Reading, Evaluation, and Macros
2 |
3 | [`code.clj`](code.clj) has all the code from the chapter.
4 |
--------------------------------------------------------------------------------
/01/clojure-noob/doc/intro.md:
--------------------------------------------------------------------------------
1 | # Introduction to clojure-noob
2 |
3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
4 |
--------------------------------------------------------------------------------
/09/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 9: The Sacred Art of Concurrent and Parallel Programming
2 |
3 | [`code.clj`](code.clj) has all the code from the chapter.
4 |
--------------------------------------------------------------------------------
/01/clojure-noob/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /classes
3 | /checkouts
4 | pom.xml
5 | pom.xml.asc
6 | *.jar
7 | *.class
8 | /.lein-*
9 | /.nrepl-port
10 |
--------------------------------------------------------------------------------
/04/fwpd/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /classes
3 | /checkouts
4 | pom.xml
5 | pom.xml.asc
6 | *.jar
7 | *.class
8 | /.lein-*
9 | /.nrepl-port
10 | .hgignore
11 | .hg/
12 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/doc/intro.md:
--------------------------------------------------------------------------------
1 | # Introduction to the-divine-cheese-code
2 |
3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/)
4 |
--------------------------------------------------------------------------------
/01/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 1: Getting Started
2 |
3 | This directory contains the `clojure-noob` project that you create at
4 | http://www.braveclojure.com/getting-started/.
5 |
--------------------------------------------------------------------------------
/11/playsync/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /classes
3 | /checkouts
4 | pom.xml
5 | pom.xml.asc
6 | *.jar
7 | *.class
8 | /.lein-*
9 | /.nrepl-port
10 | .hgignore
11 | .hg/
12 |
--------------------------------------------------------------------------------
/13/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 13: Creating and Extending Abstractions with Multimethods, Protocols, and Records
2 |
3 | [`code.clj`](code.clj) has all the Clojure code from the chapter.
4 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /classes
3 | /checkouts
4 | pom.xml
5 | pom.xml.asc
6 | *.jar
7 | *.class
8 | /.lein-*
9 | /.nrepl-port
10 | .hgignore
11 | .hg/
12 |
--------------------------------------------------------------------------------
/12/phrasebook/PiratePhrases.java:
--------------------------------------------------------------------------------
1 | public class PiratePhrases
2 | {
3 | public static void main(String[] args)
4 | {
5 | System.out.println("Shiver me timbers!!!");
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/01/clojure-noob/src/clojure_noob/core.clj:
--------------------------------------------------------------------------------
1 | (ns clojure-noob.core
2 | (:gen-class))
3 |
4 | (defn -main
5 | "I don't do a whole lot ... yet."
6 | [& args]
7 | (println "I'm a little teapot!"))
8 |
--------------------------------------------------------------------------------
/10/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 10: Clojure Metaphysics: Atoms, Refs, Vars, and Cuddle Zombies
2 |
3 | [`code.clj`](code.clj) has all the Clojure code from the chapter.
4 |
5 | [`code.rb`](code.rb) has some Ruby stuff
6 |
--------------------------------------------------------------------------------
/04/fwpd/test/fwpd/core_test.clj:
--------------------------------------------------------------------------------
1 | (ns fwpd.core-test
2 | (:require [clojure.test :refer :all]
3 | [fwpd.core :refer :all]))
4 |
5 | (deftest a-test
6 | (testing "FIXME, I fail."
7 | (is (= 0 1))))
8 |
--------------------------------------------------------------------------------
/06/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 6: Organizing Your Project: A Librarian's Tale
2 |
3 | [`the-divine-cheese-code`] contains the leiningen project for catching
4 | a cheese thief
5 |
6 | [`code.clj`](code.clj) has Clojure snippets
7 |
--------------------------------------------------------------------------------
/12/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 12: Working with the JVM
2 |
3 | [`phrasebook`](phrasebook) has ye pirate phrases, matey.
4 |
5 | [`code.clj`](code.clj) has - you guessed it! - clojure code. Check out
6 | [`code.java`](code.java), too.
7 |
--------------------------------------------------------------------------------
/11/playsync/test/playsync/core_test.clj:
--------------------------------------------------------------------------------
1 | (ns playsync.core-test
2 | (:require [clojure.test :refer :all]
3 | [playsync.core :refer :all]))
4 |
5 | (deftest a-test
6 | (testing "FIXME, I fail."
7 | (is (= 0 1))))
8 |
--------------------------------------------------------------------------------
/12/phrasebook/pirate_phrases/Greetings.java:
--------------------------------------------------------------------------------
1 | package pirate_phrases;
2 |
3 | public class Greetings
4 | {
5 | public static void hello()
6 | {
7 | System.out.println("Shiver me timbers!!!");
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/01/clojure-noob/test/clojure_noob/core_test.clj:
--------------------------------------------------------------------------------
1 | (ns clojure-noob.core-test
2 | (:require [clojure.test :refer :all]
3 | [clojure-noob.core :refer :all]))
4 |
5 | (deftest a-test
6 | (testing "FIXME, I fail."
7 | (is (= 0 1))))
8 |
--------------------------------------------------------------------------------
/04/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 4: Core Functions in Depth
2 |
3 | [`fwpd`](fwpd) has the application for tracking vampires.
4 |
5 | [`code.js`](code.js) has the JavaScript list manipulation example.
6 |
7 | [`code.clj`](code.clj) has all the Clojure examples from the chapter.
8 |
--------------------------------------------------------------------------------
/12/phrasebook/pirate_phrases/Farewells.java:
--------------------------------------------------------------------------------
1 | package pirate_phrases;
2 |
3 | public class Farewells
4 | {
5 | public static void goodbye()
6 | {
7 | System.out.println("A fair turn of the tide ter ye thar, ye magnificent sea friend!!");
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/test/the_divine_cheese_code/core_test.clj:
--------------------------------------------------------------------------------
1 | (ns the-divine-cheese-code.core-test
2 | (:require [clojure.test :refer :all]
3 | [the-divine-cheese-code.core :refer :all]))
4 |
5 | (deftest a-test
6 | (testing "FIXME, I fail."
7 | (is (= 0 1))))
8 |
--------------------------------------------------------------------------------
/12/phrasebook/PirateConversation.java:
--------------------------------------------------------------------------------
1 | import pirate_phrases.*;
2 |
3 | public class PirateConversation
4 | {
5 | public static void main(String[] args)
6 | {
7 | Greetings greetings = new Greetings();
8 | greetings.hello();
9 |
10 | Farewells farewells = new Farewells();
11 | farewells.goodbye();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/05/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 5: Functional Programming
2 |
3 | The main project at the end of the chapter, Peg Thing, is here: https://github.com/flyingmachine/pegthing. Examples of using Peg Thing functions are in [`code.clj`](code.clj), along with the rest of the clojure snippets.
4 |
5 | Inferior JavaScript examples are in [`code.js`](code.js). There's some Ruby code in [`code.rb`](code.rb).
6 |
--------------------------------------------------------------------------------
/05/code.rb:
--------------------------------------------------------------------------------
1 | class GlamourShotCaption
2 | attr_reader :text
3 | def initialize(text)
4 | @text = text
5 | clean!
6 | end
7 |
8 | private
9 | def clean!
10 | text.trim!
11 | text.gsub!(/lol/, "LOL")
12 | end
13 | end
14 |
15 | best = GlamourShotCaption.new("My boa constrictor is so sassy lol! ")
16 | best.text
17 | ; => "My boa constrictor is so sassy LOL!"
18 |
--------------------------------------------------------------------------------
/02/jack-handy:
--------------------------------------------------------------------------------
1 | If you were a pirate, you know what would be the one thing that would
2 | really make you mad? Treasure chests with no handles. How the hell are
3 | you supposed to carry it?!
4 |
5 | The face of a child can say it all, especially the mouth part of the
6 | face.
7 |
8 | To me, boxing is like a ballet, except there's no music, no
9 | choreography, and the dancers hit each other.
10 |
--------------------------------------------------------------------------------
/04/fwpd/project.clj:
--------------------------------------------------------------------------------
1 | (defproject fwpd "0.1.0-SNAPSHOT"
2 | :description "FIXME: write description"
3 | :url "http://example.com/FIXME"
4 | :license {:name "Eclipse Public License"
5 | :url "http://www.eclipse.org/legal/epl-v10.html"}
6 | :dependencies [[org.clojure/clojure "1.6.0"]]
7 | :main ^:skip-aot fwpd.core
8 | :target-path "target/%s"
9 | :profiles {:uberjar {:aot :all}})
10 |
--------------------------------------------------------------------------------
/01/clojure-noob/project.clj:
--------------------------------------------------------------------------------
1 | (defproject clojure-noob "0.1.0-SNAPSHOT"
2 | :description "FIXME: write description"
3 | :url "http://example.com/FIXME"
4 | :license {:name "Eclipse Public License"
5 | :url "http://www.eclipse.org/legal/epl-v10.html"}
6 | :dependencies [[org.clojure/clojure "1.7.0"]]
7 | :main ^:skip-aot clojure-noob.core
8 | :target-path "target/%s"
9 | :profiles {:uberjar {:aot :all}})
10 |
--------------------------------------------------------------------------------
/02/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 2: How to Use Emacs, an Excellent Clojure Editor
2 |
3 | You can find the Clojure-friendly Emacs repo at
4 | https://github.com/flyingmachine/emacs-for-clojure.
5 |
6 | [`profiles.clj`](profiles.clj) contains the code you should put in
7 | `~/.lein/profiles.clj` so that you can easily use emacs with Leiningen
8 | projects.
9 |
10 | [`jack-handy`](jack-handy) has the Jack Handy quotes for you to
11 | practice Emacs key bindings.
12 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/project.clj:
--------------------------------------------------------------------------------
1 | (defproject the-divine-cheese-code "0.1.0-SNAPSHOT"
2 | :description "FIXME: write description"
3 | :url "http://example.com/FIXME"
4 | :license {:name "Eclipse Public License"
5 | :url "http://www.eclipse.org/legal/epl-v10.html"}
6 | :dependencies [[org.clojure/clojure "1.6.0"]]
7 | :main ^:skip-aot the-divine-cheese-code.core
8 | :target-path "target/%s"
9 | :profiles {:uberjar {:aot :all}})
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Clojure for the Brave and True Code
2 |
3 | This contains all the code examples from the book Clojure for the
4 | Brave and True, which you can read at http://braveclojure.com. Also check
5 | out the print version at https://nostarch.com/clojure!
6 |
7 | This repo is organized by chapter, with the `01` directory corresponding to
8 | chapter 1, `02` chapter 2 - you get the idea. Each directory has its own
9 | README with additional notes.
10 |
11 | Have fun!
12 |
--------------------------------------------------------------------------------
/11/playsync/project.clj:
--------------------------------------------------------------------------------
1 | (defproject playsync "0.1.0-SNAPSHOT"
2 | :description "FIXME: write description"
3 | :url "http://example.com/FIXME"
4 | :license {:name "Eclipse Public License"
5 | :url "http://www.eclipse.org/legal/epl-v10.html"}
6 | :dependencies [[org.clojure/clojure "1.7.0"]
7 | [org.clojure/core.async "0.1.346.0-17112a-alpha"]]
8 | :main ^:skip-aot playsync.core
9 | :target-path "target/%s"
10 | :profiles {:uberjar {:aot :all}})
11 |
--------------------------------------------------------------------------------
/11/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 11: Mastering Concurrent Processes with core.async
2 |
3 | [`playsync`](playsync) contains all the functions and definitions
4 | listed in the chapter, and [`code.clj`](code) has the examples of the
5 | functions being used, as well as other snippets. The `playsync`
6 | project is a little funky because it's not really a project. It just
7 | makes it more convenient to use core.async functions, and it does this
8 | by putting the functions in namespace that refers the core.async
9 | functions.
10 |
--------------------------------------------------------------------------------
/12/code.java:
--------------------------------------------------------------------------------
1 | ScaryClown bellyRubsTheClown = new ScaryClown();
2 | bellyRubsTheClown.balloonCount();
3 | // => 0
4 |
5 | bellyRubsTheClown.receiveBalloons(2);
6 | bellyRubsTheClown.balloonCount();
7 | // => 2
8 |
9 | bellyRubsTheClown.makeBalloonArt();
10 | // => "Belly Rubs makes a balloon shaped like a clown, because Belly Rubs
11 | // => is trying to scare you and nothing is scarier than clowns."
12 |
13 | Math.abs(-50);
14 |
15 | "By Bluebeard's bananas!".toUpperCase();
16 | "Let's synergize our bleeding edges".indexOf("y");
17 |
--------------------------------------------------------------------------------
/04/fwpd/README.md:
--------------------------------------------------------------------------------
1 | # fwpd
2 |
3 | FIXME: description
4 |
5 | ## Installation
6 |
7 | Download from http://example.com/FIXME.
8 |
9 | ## Usage
10 |
11 | FIXME: explanation
12 |
13 | $ java -jar fwpd-0.1.0-standalone.jar [args]
14 |
15 | ## Options
16 |
17 | FIXME: listing of options this app accepts.
18 |
19 | ## Examples
20 |
21 | ...
22 |
23 | ### Bugs
24 |
25 | ...
26 |
27 | ### Any Other Sections
28 | ### That You Think
29 | ### Might be Useful
30 |
31 | ## License
32 |
33 | Copyright © 2015 FIXME
34 |
35 | Distributed under the Eclipse Public License either version 1.0 or (at
36 | your option) any later version.
37 |
--------------------------------------------------------------------------------
/11/playsync/README.md:
--------------------------------------------------------------------------------
1 | # playsync
2 |
3 | FIXME: description
4 |
5 | ## Installation
6 |
7 | Download from http://example.com/FIXME.
8 |
9 | ## Usage
10 |
11 | FIXME: explanation
12 |
13 | $ java -jar playsync-0.1.0-standalone.jar [args]
14 |
15 | ## Options
16 |
17 | FIXME: listing of options this app accepts.
18 |
19 | ## Examples
20 |
21 | ...
22 |
23 | ### Bugs
24 |
25 | ...
26 |
27 | ### Any Other Sections
28 | ### That You Think
29 | ### Might be Useful
30 |
31 | ## License
32 |
33 | Copyright © 2015 FIXME
34 |
35 | Distributed under the Eclipse Public License either version 1.0 or (at
36 | your option) any later version.
37 |
--------------------------------------------------------------------------------
/01/clojure-noob/README.md:
--------------------------------------------------------------------------------
1 | # clojure-noob
2 |
3 | FIXME: description
4 |
5 | ## Installation
6 |
7 | Download from http://example.com/FIXME.
8 |
9 | ## Usage
10 |
11 | FIXME: explanation
12 |
13 | $ java -jar clojure-noob-0.1.0-standalone.jar [args]
14 |
15 | ## Options
16 |
17 | FIXME: listing of options this app accepts.
18 |
19 | ## Examples
20 |
21 | ...
22 |
23 | ### Bugs
24 |
25 | ...
26 |
27 | ### Any Other Sections
28 | ### That You Think
29 | ### Might be Useful
30 |
31 | ## License
32 |
33 | Copyright © 2014 FIXME
34 |
35 | Distributed under the Eclipse Public License either version 1.0 or (at
36 | your option) any later version.
37 |
--------------------------------------------------------------------------------
/05/code.js:
--------------------------------------------------------------------------------
1 | var haplessObject = {
2 | emotion: "Carefree!"
3 | };
4 |
5 | var evilMutator = function(object){
6 | object.emotion = "So emo :'(";
7 | }
8 |
9 | evilMutator(haplessObject);
10 | haplessObject.emotion;
11 | // => "So emo :'("
12 |
13 | var wrestlers = getAlligatorWrestlers();
14 | var totalBites = 0;
15 | var l = wrestlers.length;
16 |
17 | for(var i=0; i < l; i++){
18 | totalBites += wrestlers[i].timesBitten;
19 | }
20 |
21 | var allPatients = getArkhamPatients();
22 | var analyzedPatients = [];
23 | var l = allPatients.length;
24 |
25 | for(var i=0; i < l; i++){
26 | if(allPatients[i].analyzed){
27 | analyzedPatients.push(allPatients[i]);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/README.md:
--------------------------------------------------------------------------------
1 | # the-divine-cheese-code
2 |
3 | FIXME: description
4 |
5 | ## Installation
6 |
7 | Download from http://example.com/FIXME.
8 |
9 | ## Usage
10 |
11 | FIXME: explanation
12 |
13 | $ java -jar the-divine-cheese-code-0.1.0-standalone.jar [args]
14 |
15 | ## Options
16 |
17 | FIXME: listing of options this app accepts.
18 |
19 | ## Examples
20 |
21 | ...
22 |
23 | ### Bugs
24 |
25 | ...
26 |
27 | ### Any Other Sections
28 | ### That You Think
29 | ### Might be Useful
30 |
31 | ## License
32 |
33 | Copyright © 2015 FIXME
34 |
35 | Distributed under the Eclipse Public License either version 1.0 or (at
36 | your option) any later version.
37 |
--------------------------------------------------------------------------------
/10/code.rb:
--------------------------------------------------------------------------------
1 | class CuddleZombie
2 | # attr_accessor is just a shorthand way for creating getters and
3 | # setters for the listed instance variables
4 | attr_accessor :cuddle_hunger_level, :percent_deteriorated
5 |
6 | def initialize(cuddle_hunger_level = 1, percent_deteriorated = 0)
7 | self.cuddle_hunger_level = cuddle_hunger_level
8 | self.percent_deteriorated = percent_deteriorated
9 | end
10 | end
11 |
12 | fred = CuddleZombie.new(2, 3)
13 | fred.cuddle_hunger_level # => 2
14 | fred.percent_deteriorated # => 3
15 |
16 | fred.cuddle_hunger_level = 3
17 | fred.cuddle_hunger_level # => 3
18 |
19 |
20 | if fred.percent_deteriorated >= 50
21 | Thread.new { database_logger.log(fred.cuddle_hunger_level) }
22 | end
23 |
24 |
25 | fred.cuddle_hunger_level = fred.cuddle_hunger_level + 1
26 | # At this time, another thread could read fred's attributes and
27 | # "perceive" fred in an inconsistent state unless you use a mutex
28 | fred.percent_deteriorated = fred.percent_deteriorated + 1
29 |
--------------------------------------------------------------------------------
/04/fwpd/src/fwpd/core.clj:
--------------------------------------------------------------------------------
1 | (ns fwpd.core)
2 |
3 | (def filename "suspects.csv")
4 |
5 | (def vamp-keys [:name :glitter-index])
6 |
7 | (defn str->int
8 | [str]
9 | (Integer. str))
10 |
11 | (def conversions {:name identity
12 | :glitter-index str->int})
13 |
14 | (defn convert
15 | [vamp-key value]
16 | ((get conversions vamp-key) value))
17 |
18 | (defn parse
19 | "Convert a CSV into rows of columns"
20 | [string]
21 | (map #(clojure.string/split % #",")
22 | (clojure.string/split string #"\n")))
23 |
24 | (defn mapify
25 | "Return a seq of maps like {:name \"Edward Cullen\" :glitter-index 10}"
26 | [rows]
27 | (map (fn [unmapped-row]
28 | (reduce (fn [row-map [vamp-key value]]
29 | (assoc row-map vamp-key (convert vamp-key value)))
30 | {}
31 | (map vector vamp-keys unmapped-row)))
32 | rows))
33 |
34 | (defn glitter-filter
35 | [minimum-glitter records]
36 | (filter #(>= (:glitter-index %) minimum-glitter) records))
37 |
38 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/src/the_divine_cheese_code/core.clj:
--------------------------------------------------------------------------------
1 | (ns the-divine-cheese-code.core
2 | (:require [clojure.java.browse :as browse]
3 | [the-divine-cheese-code.visualization.svg :refer [xml]])
4 | (:gen-class))
5 |
6 | (def heists [{:location "Cologne, Germany"
7 | :cheese-name "Archbishop Hildebold's Cheese Pretzel"
8 | :lat 50.95
9 | :lng 6.97}
10 | {:location "Zurich, Switzerland"
11 | :cheese-name "The Standard Emmental"
12 | :lat 47.37
13 | :lng 8.55}
14 | {:location "Marseille, France"
15 | :cheese-name "Le Fromage de Cosquer"
16 | :lat 43.30
17 | :lng 5.37}
18 | {:location "Zurich, Switzerland"
19 | :cheese-name "The Lesser Emmental"
20 | :lat 47.37
21 | :lng 8.55}
22 | {:location "Vatican City"
23 | :cheese-name "The Cheese of Turin"
24 | :lat 41.90
25 | :lng 12.45}])
26 |
27 | (defn url
28 | [filename]
29 | (str "file:///"
30 | (System/getProperty "user.dir")
31 | "/"
32 | filename))
33 |
34 | (defn template
35 | [contents]
36 | (str ""
37 | contents))
38 |
39 | (defn -main
40 | [& args]
41 | (let [filename "map.html"]
42 | (->> heists
43 | (xml 50 100)
44 | template
45 | (spit filename))
46 | (browse/browse-url (url filename))))
47 |
--------------------------------------------------------------------------------
/04/code.js:
--------------------------------------------------------------------------------
1 | var node3 = {
2 | value: "last",
3 | next: null
4 | };
5 |
6 | var node2 = {
7 | value: "middle",
8 | next: node3
9 | };
10 |
11 | var node1 = {
12 | value: "first",
13 | next: node2
14 | };
15 |
16 | var first = function(node) {
17 | return node.value;
18 | };
19 |
20 | var rest = function(node) {
21 | return node.next;
22 | };
23 |
24 | var cons = function(newValue, node) {
25 | return {
26 | value: newValue,
27 | next: node
28 | };
29 | };
30 |
31 | first(node1);
32 | // => "first"
33 |
34 | first(rest(node1));
35 | // => "middle"
36 |
37 | first(rest(rest(node1)));
38 | // => "last"
39 |
40 | var node0 = cons("new first", node1);
41 | first(node0);
42 | // => "new first"
43 |
44 | first(rest(node0));
45 | // => "first"
46 |
47 |
48 | var map = function (list, transform) {
49 | if (list === null) {
50 | return null;
51 | } else {
52 | return cons(transform(first(list)), map(rest(list), transform));
53 | }
54 | }
55 |
56 | first(
57 | map(node1, function (val) { return val + " mapped!"})
58 | );
59 | // => "first mapped!"
60 |
61 | var first = function (array) {
62 | return array[0];
63 | }
64 |
65 | var rest = function (array) {
66 | var sliced = array.slice(1, array.length);
67 | if (sliced.length == 0) {
68 | return null;
69 | } else {
70 | return sliced;
71 | }
72 | }
73 |
74 | var cons = function (newValue, array) {
75 | return [newValue].concat(array);
76 | }
77 |
78 | var list = ["Transylvania", "Forks, WA"];
79 | map(list, function (val) { return val + " mapped!"})
80 | // => ["Transylvania mapped!", "Forks, WA mapped!"]
81 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/src/the_divine_cheese_code/visualization/svg.clj:
--------------------------------------------------------------------------------
1 | (ns the-divine-cheese-code.visualization.svg
2 | (:require [clojure.string :as s])
3 | (:refer-clojure :exclude [min max]))
4 |
5 | (defn comparator-over-maps
6 | [comparison-fn ks]
7 | (fn [maps]
8 | (zipmap ks
9 | (map (fn [k] (apply comparison-fn (map k maps)))
10 | ks))))
11 |
12 | (def min (comparator-over-maps clojure.core/min [:lat :lng]))
13 | (def max (comparator-over-maps clojure.core/max [:lat :lng]))
14 |
15 |
16 | (defn translate-to-00
17 | [locations]
18 | (let [mincoords (min locations)]
19 | (map #(merge-with - % mincoords) locations)))
20 |
21 | (defn scale
22 | [width height locations]
23 | (let [maxcoords (max locations)
24 | ratio {:lat (/ height (:lat maxcoords))
25 | :lng (/ width (:lng maxcoords))}]
26 | (map #(merge-with * % ratio) locations)))
27 |
28 | (defn latlng->point
29 | "Convert lat/lng map to comma-separated string"
30 | [latlng]
31 | (str (:lat latlng) "," (:lng latlng)))
32 |
33 | (defn points
34 | [locations]
35 | (clojure.string/join " " (map latlng->point locations)))
36 |
37 | (defn line
38 | [points]
39 | (str ""))
40 |
41 | (defn transform
42 | "Just chains other functions"
43 | [width height locations]
44 | (->> locations
45 | translate-to-00
46 | (scale width height)))
47 |
48 | (defn xml
49 | "svg 'template', which also flips the coordinate system"
50 | [width height locations]
51 | (str ""))
62 |
--------------------------------------------------------------------------------
/11/playsync/src/playsync/core.clj:
--------------------------------------------------------------------------------
1 | (ns playsync.core
2 | (:require [clojure.core.async
3 | :as a
4 | :refer [>! !! !! echo-chan "ketchup")
10 |
11 | (defn hot-dog-machine
12 | []
13 | (let [in (chan)
14 | out (chan)]
15 | (go (! out "hot dog"))
17 | [in out]))
18 |
19 | (defn hot-dog-machine-v2
20 | [hot-dog-count]
21 | (let [in (chan)
22 | out (chan)]
23 | (go (loop [hc hot-dog-count]
24 | (if (> hc 0)
25 | (let [input (! out "hot dog")
28 | (recur (dec hc)))
29 | (do (>! out "wilted lettuce")
30 | (recur hc))))
31 | (do (close! in)
32 | (close! out)))))
33 | [in out]))
34 |
35 | (defn upload
36 | [headshot c]
37 | (go (Thread/sleep (rand 100))
38 | (>! c headshot)))
39 |
40 |
41 | (defn append-to-file
42 | "Write a string to the end of a file"
43 | [filename s]
44 | (spit filename s :append true))
45 |
46 | (defn format-quote
47 | "Delineate the beginning and end of a quote because it's convenient"
48 | [quote]
49 | (str "=== BEGIN QUOTE ===\n" quote "=== END QUOTE ===\n\n"))
50 |
51 | (defn random-quote
52 | "Retrieve a random quote and format it"
53 | []
54 | (format-quote (slurp "http://www.braveclojure.com/random-quote")))
55 |
56 | (defn snag-quotes
57 | [filename num-quotes]
58 | (let [c (chan)]
59 | (go (while true (append-to-file filename (! c (random-quote))))))
61 |
62 | (defn upper-caser
63 | [in]
64 | (let [out (chan)]
65 | (go (while true (>! out (clojure.string/upper-case (! out (clojure.string/reverse (!! (chan) "mustard")
3 |
4 |
5 | (def echo-buffer (chan 2))
6 | (>!! echo-buffer "ketchup")
7 | ; => true
8 | (>!! echo-buffer "ketchup")
9 | ; => true
10 | (>!! echo-buffer "ketchup")
11 | ; This blocks because the channel buffer is full
12 |
13 |
14 | (def hi-chan (chan))
15 | (doseq [n (range 1000)]
16 | (go (>! hi-chan (str "hi " n))))
17 |
18 | (thread (println (!! echo-chan "mustard")
20 | ; => true
21 | ; => mustard
22 |
23 | (let [t (thread "chili")]
24 | ( "chili"
26 |
27 |
28 |
29 | ;; Hot dog machine stuff
30 |
31 | (let [[in out] (hot-dog-machine)]
32 | (>!! in "pocket lint")
33 | ( "hot dog"
35 |
36 | ;; Hot dog machine v2
37 | (let [[in out] (hot-dog-machine-v2 2)]
38 | (>!! in "pocket lint")
39 | (println (!! in 3)
42 | (println (!! in 3)
45 | (println (!! in 3)
48 | ( wilted lettuce
50 | ; => hotdog
51 | ; => hotdog
52 | ; => nil
53 |
54 |
55 | ;; Pipeline
56 | (let [c1 (chan)
57 | c2 (chan)
58 | c3 (chan)]
59 | (go (>! c2 (clojure.string/upper-case (! c3 (clojure.string/reverse (!! c1 "redrum"))
63 | ; => MURDER
64 |
65 |
66 | ;; alts!!
67 | (let [c1 (chan)
68 | c2 (chan)
69 | c3 (chan)]
70 | (upload "serious.jpg" c1)
71 | (upload "fun.jpg" c2)
72 | (upload "sassy.jpg" c3)
73 | (let [[headshot channel] (alts!! [c1 c2 c3])]
74 | (println "Sending headshot notification for" headshot)))
75 | ; => Sending headshot notification for sassy.jpg
76 |
77 | (let [c1 (chan)]
78 | (upload "serious.jpg" c1)
79 | (let [[headshot channel] (alts!! [c1 (timeout 20)])]
80 | (if headshot
81 | (println "Sending headshot notification for" headshot)
82 | (println "Timed out!"))))
83 | ; => Timed out!
84 |
85 | (let [c1 (chan)
86 | c2 (chan)]
87 | (go ( true
92 | ; => true
93 |
94 | ;; reverser
95 | (printer reverser-out)
96 |
97 | (>!! in-chan "redrum")
98 | ; => MURDER
99 |
100 | (>!! in-chan "repaid")
101 | ; => DIAPER
102 |
--------------------------------------------------------------------------------
/12/code.clj:
--------------------------------------------------------------------------------
1 | (.toUpperCase "By Bluebeard's bananas!")
2 | ; => "BY BLUEBEARD'S BANANAS!"
3 |
4 | (.indexOf "Let's synergize our bleeding edges" "y")
5 | ; => 7
6 |
7 | (macroexpand-1 '(.toUpperCase "By Bluebeard's bananas!"))
8 | ; => (. "By Bluebeard's bananas!" toUpperCase)
9 |
10 | (macroexpand-1 '(.indexOf "Let's synergize our bleeding edges" "y"))
11 | ; => (. "Let's synergize our bleeding edges" indexOf "y")
12 |
13 | (macroexpand-1 '(Math/abs -3))
14 | ; => (. Math abs -3)
15 |
16 | (new String)
17 | ; => ""
18 |
19 | (String.)
20 | ; => ""
21 |
22 | (String. "To Davey Jones's Locker with ye hardies")
23 | ; => "To Davey Jones's Locker with ye hardies"
24 |
25 | (java.util.Stack.)
26 | ; => []
27 |
28 | (let [stack (java.util.Stack.)]
29 | (.push stack "Latest episode of Game of Thrones, ho!")
30 | stack)
31 | ; => ["Latest episode of Game of Thrones, ho!"]
32 |
33 |
34 | (let [stack (java.util.Stack.)]
35 | (.push stack "Latest episode of Game of Thrones, ho!")
36 | (first stack))
37 | ; => "Latest episode of Game of Thrones, ho!"
38 |
39 |
40 | (doto (java.util.Stack.)
41 | (.push "Latest episode of Game of Thrones, ho!")
42 | (.push "Whoops, I meant 'Land, ho!'"))
43 | ; => ["Latest episode of Game of Thrones, ho!" "Whoops, I meant 'Land, ho!'"]
44 |
45 |
46 | (macroexpand-1
47 | '(doto (java.util.Stack.)
48 | (.push "Latest episode of Game of Thrones, ho!")
49 | (.push "Whoops, I meant 'Land, ho!'")))
50 | ; => (clojure.core/let
51 | ; => [G__2876 (java.util.Stack.)]
52 | ; => (.push G__2876 "Latest episode of Game of Thrones, ho!")
53 | ; => (.push G__2876 "Whoops, I meant 'Land, ho!'")
54 | ; => G__2876)
55 |
56 | (import java.util.Stack)
57 | (Stack.)
58 | ; => []
59 |
60 | (import [java.util Date Stack]
61 | [java.net Proxy URI])
62 |
63 | (Date.)
64 | ; => #inst "2016-09-19T20:40:02.733-00:00"
65 |
66 | (ns pirate.talk
67 | (:import [java.util Date Stack]
68 | [java.net Proxy URI]))
69 |
70 | (System/getenv)
71 | {"USER" "the-incredible-bulk"
72 | "JAVA_ARCH" "x86_64"}
73 |
74 | (System/getProperty "user.dir")
75 | ; => "/Users/dabulk/projects/dabook"
76 |
77 | (System/getProperty "java.version")
78 | ; => "1.7.0_17"
79 |
80 | #inst "2016-09-19T20:40:02.733-00:00"
81 |
82 | (let [file (java.io.File. "/")]
83 | (println (.exists file))
84 | (println (.canWrite file))
85 | (println (.getPath file)))
86 | ; => true
87 | ; => false
88 | ; => /
89 |
90 | (spit "/tmp/hercules-todo-list"
91 | "- kill dat lion brov
92 | - chop up what nasty multi-headed snake thing")
93 |
94 | (slurp "/tmp/hercules-todo-list")
95 |
96 | ; => "- kill dat lion brov
97 | ; => - chop up what nasty multi-headed snake thing"
98 |
99 | (let [s (java.io.StringWriter.)]
100 | (spit s "- capture cerynian hind like for real")
101 | (.toString s))
102 | ; => "- capture cerynian hind like for real"
103 |
104 |
105 | (let [s (java.io.StringReader. "- get erymanthian pig what with the tusks")]
106 | (slurp s))
107 | ; => "- get erymanthian pig what with the tusks"
108 |
109 |
110 | (with-open [todo-list-rdr (clojure.java.io/reader "/tmp/hercules-todo-list")]
111 | (println (first (line-seq todo-list-rdr))))
112 | ; => - kill dat lion brov
113 |
--------------------------------------------------------------------------------
/07/code.clj:
--------------------------------------------------------------------------------
1 | (defmacro backwards
2 | [form]
3 | (reverse form))
4 |
5 | (backwards (" backwards" " am" "I" str))
6 | ; => "I am backwards"
7 |
8 |
9 | (def addition-list (list + 1 2))
10 | (eval addition-list)
11 | ; => 3
12 |
13 | (eval (concat addition-list [10]))
14 | ; => 13
15 |
16 | (eval (list 'def 'lucky-number (concat addition-list [10])))
17 | ; => #'user/lucky-number
18 |
19 | lucky-number
20 | ; => 13
21 |
22 |
23 | (str "To understand what recursion is," " you must first understand recursion.")
24 | "To understand what recursion is, you must first understand recursion."
25 |
26 | (read-string "(+ 1 2)")
27 | ; => (+ 1 2)
28 |
29 | (list? (read-string "(+ 1 2)"))
30 | ; => true
31 |
32 | (conj (read-string "(+ 1 2)") :zagglewag)
33 | ; => (:zagglewag + 1 2)
34 |
35 |
36 | (eval (read-string "(+ 1 2)"))
37 | ; => 3
38 |
39 | (#(+ 1 %) 3)
40 | ; => 4
41 |
42 | (read-string "#(+ 1 %)")
43 | ; => (fn* [p1__423#] (+ 1 p1__423#))
44 |
45 | (read-string "'(a b c)")
46 | ; => (quote (a b c))
47 |
48 | (read-string "@var")
49 | ; => (clojure.core/deref var)
50 |
51 | (read-string "; ignore!\n(+ 1 2)")
52 | ; => (+ 1 2)
53 |
54 | true
55 | ; => true
56 |
57 | false
58 | ; => false
59 |
60 | {}
61 | ; => {}
62 |
63 | :huzzah
64 | ; => :huzzah
65 |
66 | ()
67 | ; => ()
68 |
69 | (if true :a :b)
70 | ; => :a
71 |
72 | if
73 | ; => CompilerException java.lang.RuntimeException: Unable to resolve symbol: if in this context, compiling:(NO_SOURCE_PATH:0:0)
74 |
75 | (let [x 5]
76 | (+ x 3))
77 | ; => 8
78 |
79 | (def x 15)
80 | (+ x 3)
81 | ; => 18
82 |
83 | (def x 15)
84 | (let [x 5]
85 | (+ x 3))
86 | ; => 8
87 |
88 | (let [x 5]
89 | (let [x 6]
90 | (+ x 3)))
91 | ; => 9
92 |
93 | (defn exclaim
94 | [exclamation]
95 | (str exclamation "!"))
96 |
97 | (exclaim "Hadoken")
98 | ; => "Hadoken!"
99 |
100 | (map inc [1 2 3])
101 | ; => (2 3 4)
102 |
103 | (read-string ("+"))
104 | ; => +
105 |
106 | (type (read-string "+"))
107 | ; => clojure.lang.Symbol
108 |
109 | (list (read-string "+") 1 2)
110 | ; => (+ 1 2)
111 |
112 | (eval (list (read-string "+") 1 2))
113 | ; => 3
114 |
115 | (eval (read-string "()"))
116 | ; => ()
117 |
118 | (+ 1 2)
119 | ; => 3
120 |
121 | (+ 1 (+ 2 3))
122 | ; => 6
123 |
124 | (if true 1 2)
125 | ; => 1
126 |
127 | '(a b c)
128 |
129 | (quote (a b c))
130 |
131 | (read-string "(1 + 1)")
132 | ; => (1 + 1)
133 |
134 | (eval (read-string "(1 + 1)"))
135 | ; => ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
136 |
137 | (let [infix (read-string "(1 + 1)")]
138 | (list (second infix) (first infix) (last infix)))
139 | ; => (+ 1 1)
140 |
141 | (eval
142 | (let [infix (read-string "(1 + 1)")]
143 | (list (second infix) (first infix) (last infix))))
144 | ; => 2
145 |
146 | (defmacro ignore-last-operand
147 | [function-call]
148 | (butlast function-call))
149 |
150 | (ignore-last-operand (+ 1 2 10))
151 | ; => 3
152 |
153 | ;; This will not print anything
154 | (ignore-last-operand (+ 1 2 (println "look at me!!!")))
155 | ; => 3
156 |
157 | (macroexpand '(ignore-last-operand (+ 1 2 10)))
158 | ; => (+ 1 2)
159 |
160 | (macroexpand '(ignore-last-operand (+ 1 2 (println "look at me!!!"))))
161 | ; => (+ 1 2)
162 |
163 | (defmacro infix
164 | [infixed]
165 | (list (second infixed)
166 | (first infixed)
167 | (last infixed)))
168 |
169 | (infix (1 + 2))
170 | ; => 3
171 |
172 | (defn read-resource
173 | "Read a resource into a string"
174 | [path]
175 | (read-string (slurp (clojure.java.io/resource path))))
176 |
177 | (defn read-resource
178 | [path]
179 | (-> path
180 | clojure.java.io/resource
181 | slurp
182 | read-string))
183 |
--------------------------------------------------------------------------------
/05/code.clj:
--------------------------------------------------------------------------------
1 | (+ 1 2)
2 | ; => 3
3 |
4 | (defn wisdom
5 | [words]
6 | (str words ", Daniel-san"))
7 |
8 | (wisdom "Always bathe on Fridays")
9 | ; => "Always bathe on Fridays, Daniel-san"
10 |
11 | (defn year-end-evaluation
12 | []
13 | (if (> (rand) 0.5)
14 | "You get a raise!"
15 | "Better luck next year!"))
16 |
17 | (defn analyze-file
18 | [filename]
19 | (analysis (slurp filename)))
20 |
21 | (defn analysis
22 | [text]
23 | (str "Character count: " (count text)))
24 |
25 | (def great-baby-name "Rosanthony")
26 | great-baby-name
27 | ; => "Rosanthony"
28 |
29 | (let [great-baby-name "Bloodthunder"]
30 | great-baby-name)
31 | ; => "Bloodthunder"
32 |
33 | great-baby-name
34 | ; => "Rosanthony"
35 |
36 | (defn sum
37 | ([vals] (sum vals 0))
38 | ([vals accumulating-total]
39 | (if (empty? vals)
40 | accumulating-total
41 | (sum (rest vals) (+ (first vals) accumulating-total)))))
42 |
43 | (sum [39 5 1]) ; single-arity body calls two-arity body
44 | (sum [39 5 1] 0)
45 | (sum [5 1] 39)
46 | (sum [1] 44)
47 | (sum [] 45) ; base case is reached, so return accumulating-total
48 | ; => 45
49 |
50 | (defn sum
51 | ([vals]
52 | (sum vals 0))
53 | ([vals accumulating-total]
54 | (if (empty? vals)
55 | accumulating-total
56 | (recur (rest vals) (+ (first vals) accumulating-total)))))
57 |
58 |
59 | (require '[clojure.string :as s])
60 | (defn clean
61 | [text]
62 | (s/replace (s/trim text) #"lol" "LOL"))
63 |
64 | (clean "My boa constrictor is so sassy lol! ")
65 | ; => "My boa constrictor is so sassy LOL!"
66 |
67 | ((comp inc *) 2 3)
68 | ; => 7
69 |
70 | (def character
71 | {:name "Smooches McCutes"
72 | :attributes {:intelligence 10
73 | :strength 4
74 | :dexterity 5}})
75 | (def c-int (comp :intelligence :attributes))
76 | (def c-str (comp :strength :attributes))
77 | (def c-dex (comp :dexterity :attributes))
78 |
79 | (c-int character)
80 | ; => 10
81 |
82 | (c-str character)
83 | ; => 4
84 |
85 | (c-dex character)
86 | ; => 5
87 |
88 |
89 | (fn [c] (:strength (:attributes c)))
90 |
91 | (defn spell-slots
92 | [char]
93 | (int (inc (/ (c-int char) 2))))
94 |
95 | (spell-slots character)
96 | ; => 6
97 |
98 | (def spell-slots-comp (comp int inc #(/ % 2) c-int))
99 |
100 | (defn two-comp
101 | [f g]
102 | (fn [& args]
103 | (f (apply g args))))
104 |
105 | (+ 3 (+ 5 8))
106 |
107 | (+ 3 13)
108 |
109 | 16
110 |
111 | (defn sleepy-identity
112 | "Returns the given value after 1 second"
113 | [x]
114 | (Thread/sleep 1000)
115 | x)
116 |
117 | (sleepy-identity "Mr. Fantastico")
118 | ; => "Mr. Fantastico" after 1 second
119 |
120 | (sleepy-identity "Mr. Fantastico")
121 | ; => "Mr. Fantastico" after 1 second
122 |
123 |
124 | (def memo-sleepy-identity (memoize sleepy-identity))
125 | (memo-sleepy-identity "Mr. Fantastico")
126 | ; => "Mr. Fantastico" after 1 second
127 |
128 | (memo-sleepy-identity "Mr. Fantastico")
129 | ; => "Mr. Fantastico" immediately
130 |
131 |
132 | ;; Peg Thing examples
133 |
134 | (take 5 tri)
135 | ; => (1 3 6 10 15)
136 |
137 | (triangular? 5)
138 | ; => false
139 |
140 | (triangular? 6)
141 | ; => true
142 |
143 | (row-tri 1)
144 | ; => 1
145 |
146 | (row-tri 2)
147 | ; => 3
148 |
149 | (row-tri 3)
150 | ; => 6
151 |
152 | (row-num 1)
153 | ; => 1
154 | (row-num 5)
155 | ; => 3
156 |
157 |
158 | (connect {} 15 1 2 4)
159 | ; => {1 {:connections {4 2}}
160 | ; => 4 {:connections {1 2}}}
161 |
162 | (assoc-in {} [:cookie :monster :vocals] "Finntroll")
163 | ; => {:cookie {:monster {:vocals "Finntroll"}}}
164 |
165 | (get-in {:cookie {:monster {:vocals "Finntroll"}}} [:cookie :monster])
166 | ; => {:vocals "Finntroll"}
167 |
168 | (assoc-in {} [1 :connections 4] 2)
169 | ; => {1 {:connections {4 2}}}
170 |
171 | (connect-down-left {} 15 1)
172 | ; => {1 {:connections {4 2}
173 | ; => 4 {:connections {1 2}}}}
174 |
175 | (connect-down-right {} 15 3)
176 | ; => {3 {:connections {10 6}}
177 | ; => 10 {:connections {3 6}}}
178 |
179 | (add-pos {} 15 1)
180 | {1 {:connections {6 3, 4 2}, :pegged true}
181 | 4 {:connections {1 2}}
182 | 6 {:connections {1 3}}}
183 |
184 | (valid-moves my-board 1) ; => {4 2}
185 | (valid-moves my-board 6) ; => {4 5}
186 | (valid-moves my-board 11) ; => {4 7}
187 | (valid-moves my-board 5) ; => {}
188 | (valid-moves my-board 8) ; => {}
189 |
190 |
191 | (valid-move? my-board 8 4) ; => nil
192 | (valid-move? my-board 1 4) ; => 2
193 |
194 | (characters-as-strings "a b")
195 | ; => ("a" "b")
196 |
197 | (characters-as-strings "a cb")
198 | ; => ("a" "c" "b")
199 |
--------------------------------------------------------------------------------
/06/code.clj:
--------------------------------------------------------------------------------
1 | (ns-name *ns*)
2 | ; => user
3 |
4 | inc
5 | ; => #
6 |
7 | 'inc
8 | ; => inc
9 |
10 | (map inc [1 2])
11 | ; => (2 3)
12 |
13 | '(map inc [1 2])
14 | ; => (map inc [1 2])
15 |
16 | (def great-books ["East of Eden" "The Glass Bead Game"])
17 | ; => #'user/great-books
18 |
19 | great-books
20 | ; => ["East of Eden" "The Glass Bead Game"]
21 |
22 | (ns-interns *ns*)
23 | ; => {great-books #'user/great-books}
24 |
25 | (get (ns-interns *ns*) 'great-books)
26 | ; => #'user/great-books
27 |
28 | (deref #'user/great-books)
29 | ; => ["East of Eden" "The Glass Bead Game"]
30 |
31 | great-books
32 | ; => ["East of Eden" "The Glass Bead Game"]
33 |
34 | (def great-books ["The Power of Bees" "Journey to Upstairs"])
35 | great-books
36 | ; => ["The Power of Bees" "Journey to Upstairs"]
37 |
38 | (create-ns 'cheese.taxonomy)
39 | ; => #
40 |
41 | (ns-name (create-ns 'cheese.taxonomy))
42 | ; => cheese-taxonomy
43 |
44 | (in-ns 'cheese.analysis)
45 | ; => #
46 |
47 |
48 | (in-ns 'cheese.taxonomy)
49 | (def cheddars ["mild" "medium" "strong" "sharp" "extra sharp"])
50 | (in-ns 'cheese.analysis)
51 | cheddars
52 | ; => Exception: Unable to resolve symbol: cheddars in this context
53 |
54 | cheese.taxonomy/cheddars
55 | ; => ["mild" "medium" "strong" "sharp" "extra sharp"]
56 |
57 |
58 | (in-ns 'cheese.taxonomy)
59 | (def cheddars ["mild" "medium" "strong" "sharp" "extra sharp"])
60 | (def bries ["Wisconsin" "Somerset" "Brie de Meaux" "Brie de Melun"])
61 | (in-ns 'cheese.analysis)
62 | (clojure.core/refer 'cheese.taxonomy)
63 | bries
64 | ; => ["Wisconsin" "Somerset" "Brie de Meaux" "Brie de Melun"]
65 |
66 | cheddars
67 | ; => ["mild" "medium" "strong" "sharp" "extra sharp"]
68 |
69 | (clojure.core/get (clojure.core/ns-map clojure.core/*ns*) 'bries)
70 | ; => #'cheese.taxonomy/bries
71 |
72 | (clojure.core/get (clojure.core/ns-map clojure.core/*ns*) 'cheddars)
73 | ; => #'cheese.taxonomy/cheddars
74 |
75 |
76 | (clojure.core/refer 'cheese.taxonomy :only ['bries])
77 | bries
78 | ; => ["Wisconsin" "Somerset" "Brie de Meaux" "Brie de Melun"]
79 | cheddars
80 | ; => RuntimeException: Unable to resolve symbol: cheddars
81 |
82 |
83 | (clojure.core/refer 'cheese.taxonomy :exclude ['bries])
84 | bries
85 | ; => RuntimeException: Unable to resolve symbol: bries
86 | cheddars
87 | ; => ["mild" "medium" "strong" "sharp" "extra sharp"]
88 |
89 |
90 | (clojure.core/refer 'cheese.taxonomy :rename {'bries 'yummy-bries})
91 | bries
92 | ; => RuntimeException: Unable to resolve symbol: bries
93 | yummy-bries
94 | ; => ["Wisconsin" "Somerset" "Brie de Meaux" "Brie de Melun"]
95 |
96 |
97 | (in-ns 'cheese.analysis)
98 | ;; Notice the dash after "defn"
99 | (defn- private-function
100 | "Just an example function that does nothing"
101 | [])
102 |
103 | (in-ns 'cheese.taxonomy)
104 | (clojure.core/refer-clojure)
105 | (cheese.analysis/private-function)
106 | (refer 'cheese.analysis :only ['private-function])
107 |
108 | (clojure.core/alias 'taxonomy 'cheese.taxonomy)
109 | taxonomy/bries
110 | ; => ["Wisconsin" "Somerset" "Brie de Meaux" "Brie de Melun"]
111 |
112 |
113 | ;; this:
114 | (require '[the-divine-cheese-code.visualization.svg :as svg])
115 | ;; is the same as this:
116 | (require 'the-divine-cheese-code.visualization.svg)
117 | (alias 'svg 'the-divine-cheese-code.visualization.svg)
118 |
119 | (svg/points heists)
120 | ; => "50.95,6.97 47.37,8.55 43.3,5.37 47.37,8.55 41.9,12.45"
121 |
122 |
123 | (use '[the-divine-cheese-code.visualization.svg :as svg])
124 | (= svg/points points)
125 | ; => true
126 |
127 | (= svg/latlng->point latlng->point)
128 | ; => true
129 |
130 | (require 'the-divine-cheese-code.visualization.svg)
131 | (use '[the-divine-cheese-code.visualization.svg :as svg :only [points]])
132 | (refer 'the-divine-cheese-code.visualization.svg :as svg :only ['points])
133 | (= svg/points points)
134 | ; => true
135 |
136 | ;; We can use the alias to reach latlng->point
137 | svg/latlng->point
138 | ; This doesn't throw an exception
139 |
140 | ;; But we can't use the bare name
141 | latlng->point
142 | ; This does throw an exception!
143 |
144 |
145 | (ns the-divine-cheese-code.visualization.svg
146 | (:require [clojure.string :as s])
147 | (:refer-clojure :exclude [min max]))
148 |
149 | (defn comparator-over-maps
150 | [comparison-fn ks]
151 | (fn [maps]
152 | (zipmap ks
153 | (map (fn [k] (apply comparison-fn (map k maps)))
154 | ks))))
155 |
156 | (def min (comparator-over-maps clojure.core/min [:lat :lng]))
157 | (def max (comparator-over-maps clojure.core/max [:lat :lng]))
158 |
159 |
160 | (min [{:a 1 :b 3} {:a 5 :b 0}])
161 | ; => {:a 1 :b 0}
162 |
163 |
164 | (zipmap [:a :b] [1 2])
165 | ; => {:a 1 :b 2}
166 |
167 |
168 | (merge-with - {:lat 50 :lng 10} {:lat 5 :lng 5})
169 | ; => {:lat 45 :lng 5}
170 |
--------------------------------------------------------------------------------
/09/code.clj:
--------------------------------------------------------------------------------
1 | (future (Thread/sleep 4000)
2 | (println "I'll print after 4 seconds"))
3 | (println "I'll print immediately")
4 |
5 |
6 | (let [result (future (println "this prints once")
7 | (+ 1 1))]
8 | (println "deref: " (deref result))
9 | (println "@: " @result))
10 | ; => "this prints once"
11 | ; => deref: 2
12 | ; => @: 2
13 |
14 |
15 | (let [result (future (Thread/sleep 3000)
16 | (+ 1 1))]
17 | (println "The result is: " @result)
18 | (println "It will be at least 3 seconds before I print"))
19 | ; => The result is: 2
20 | ; => It will be at least 3 seconds before I print
21 |
22 |
23 | (deref (future (Thread/sleep 1000) 0) 10 5)
24 | ; => 5
25 |
26 |
27 | (realized? (future (Thread/sleep 1000)))
28 | ; => false
29 |
30 | (let [f (future)]
31 | @f
32 | (realized? f))
33 | ; => true
34 |
35 |
36 | (def jackson-5-delay
37 | (delay (let [message "Just call my name and I'll be there"]
38 | (println "First deref:" message)
39 | message)))
40 |
41 | (force jackson-5-delay)
42 | ; => First deref: Just call my name and I'll be there
43 | ; => "Just call my name and I'll be there"
44 |
45 |
46 | @jackson-5-delay
47 | ; => "Just call my name and I'll be there"
48 |
49 |
50 | (def gimli-headshots ["serious.jpg" "fun.jpg" "playful.jpg"])
51 | (defn email-user
52 | [email-address]
53 | (println "Sending headshot notification to" email-address))
54 | (defn upload-document
55 | "Needs to be implemented"
56 | [headshot]
57 | true)
58 | (let [notify (delay (email-user "and-my-axe@gmail.com"))]
59 | (doseq [headshot gimli-headshots]
60 | (future (upload-document headshot)
61 | (force notify))))
62 |
63 |
64 | (def my-promise (promise))
65 | (deliver my-promise (+ 1 2))
66 | @my-promise
67 | ; => 3
68 |
69 |
70 | (def yak-butter-international
71 | {:store "Yak Butter International"
72 | :price 90
73 | :smoothness 90})
74 | (def butter-than-nothing
75 | {:store "Butter Than Nothing"
76 | :price 150
77 | :smoothness 83})
78 | ;; This is the butter that meets our requirements
79 | (def baby-got-yak
80 | {:store "Baby Got Yak"
81 | :price 94
82 | :smoothness 99})
83 |
84 | (defn mock-api-call
85 | [result]
86 | (Thread/sleep 1000)
87 | result)
88 |
89 | (defn satisfactory?
90 | "If the butter meets our criteria, return the butter, else return false"
91 | [butter]
92 | (and (<= (:price butter) 100)
93 | (>= (:smoothness butter) 97)
94 | butter))
95 |
96 |
97 | (time (some (comp satisfactory? mock-api-call)
98 | [yak-butter-international butter-than-nothing baby-got-yak]))
99 | ; => "Elapsed time: 3002.132 msecs"
100 | ; => {:store "Baby Got Yak", :smoothness 99, :price 94}
101 |
102 |
103 | (time
104 | (let [butter-promise (promise)]
105 | (doseq [butter [yak-butter-international butter-than-nothing baby-got-yak]]
106 | (future (if-let [satisfactory-butter (satisfactory? (mock-api-call butter))]
107 | (deliver butter-promise satisfactory-butter))))
108 | (println "And the winner is:" @butter-promise)))
109 | ; => "Elapsed time: 1002.652 msecs"
110 | ; => And the winner is: {:store Baby Got Yak, :smoothness 99, :price 94}
111 |
112 |
113 | (let [p (promise)]
114 | (deref p 100 "timed out"))
115 |
116 |
117 | (let [ferengi-wisdom-promise (promise)]
118 | (future (println "Here's some Ferengi wisdom:" @ferengi-wisdom-promise))
119 | (Thread/sleep 100)
120 | (deliver ferengi-wisdom-promise "Whisper your way to success."))
121 | ; => Here's some Ferengi wisdom: Whisper your way to success.
122 |
123 |
124 | (defmacro wait
125 | "Sleep `timeout` seconds before evaluating body"
126 | [timeout & body]
127 | `(do (Thread/sleep ~timeout) ~@body))
128 |
129 |
130 | (let [saying3 (promise)]
131 | (future (deliver saying3 (wait 100 "Cheerio!")))
132 | @(let [saying2 (promise)]
133 | (future (deliver saying2 (wait 400 "Pip pip!")))
134 | @(let [saying1 (promise)]
135 | (future (deliver saying1 (wait 200 "'Ello, gov'na!")))
136 | (println @saying1)
137 | saying1)
138 | (println @saying2)
139 | saying2)
140 | (println @saying3)
141 | saying3)
142 |
143 |
144 | (-> (enqueue saying (wait 200 "'Ello, gov'na!") (println @saying))
145 | (enqueue saying (wait 400 "Pip pip!") (println @saying))
146 | (enqueue saying (wait 100 "Cheerio!") (println @saying)))
147 |
148 |
149 | (defmacro enqueue
150 | ([q concurrent-promise-name concurrent serialized]
151 | `(let [~concurrent-promise-name (promise)]
152 | (future (deliver ~concurrent-promise-name ~concurrent))
153 | (deref ~q)
154 | ~serialized
155 | ~concurrent-promise-name))
156 | ([concurrent-promise-name concurrent serialized]
157 | `(enqueue (future) ~concurrent-promise-name ~concurrent ~serialized)))
158 |
159 |
160 | (time @(-> (enqueue saying (wait 200 "'Ello, gov'na!") (println @saying))
161 | (enqueue saying (wait 400 "Pip pip!") (println @saying))
162 | (enqueue saying (wait 100 "Cheerio!") (println @saying))))
163 | ; => 'Ello, gov'na!
164 | ; => Pip pip!
165 | ; => Cheerio!
166 | ; => "Elapsed time: 401.635 msecs"
167 |
--------------------------------------------------------------------------------
/13/code.clj:
--------------------------------------------------------------------------------
1 | (ns were-creatures)
2 |
3 | (defmulti full-moon-behavior (fn [were-creature] (:were-type were-creature)))
4 |
5 | (defmethod full-moon-behavior :wolf
6 | [were-creature]
7 | (str (:name were-creature) " will howl and murder"))
8 |
9 | (defmethod full-moon-behavior :simmons
10 | [were-creature]
11 | (str (:name were-creature) " will encourage people and sweat to the oldies"))
12 |
13 | (full-moon-behavior {:were-type :wolf
14 | :name "Rachel from next door"})
15 | ; => "Rachel from next door will howl and murder"
16 |
17 | (full-moon-behavior {:name "Andy the baker"
18 | :were-type :simmons})
19 | ; => "Andy the baker will encourage people and sweat to the oldies"
20 |
21 | (defmethod full-moon-behavior nil
22 | [were-creature]
23 | (str (:name were-creature) " will stay at home and eat ice cream"))
24 |
25 | (full-moon-behavior {:were-type nil
26 | :name "Martin the nurse"})
27 | ; => "Martin the nurse will stay at home and eat ice cream"
28 |
29 | (defmethod full-moon-behavior :default
30 | [were-creature]
31 | (str (:name were-creature) " will stay up all night fantasy footballing"))
32 |
33 | (full-moon-behavior {:were-type :office-worker
34 | :name "Jimmy from sales"})
35 | ; => "Jimmy from sales will stay up all night fantasy footballing"
36 |
37 |
38 | (ns random-namespace
39 | (:require [were-creatures]))
40 | (defmethod were-creatures/full-moon-behavior :bill-murray
41 | [were-creature]
42 | (str (:name were-creature) " will be the most likeable celebrity"))
43 | (were-creatures/full-moon-behavior {:name "Laura the intern"
44 | :were-type :bill-murray})
45 | ; => "Laura the intern will be the most likeable celebrity"
46 |
47 | (ns user)
48 | (defmulti types (fn [x y] [(class x) (class y)]))
49 | (defmethod types [java.lang.String java.lang.String]
50 | [x y]
51 | "Two strings!")
52 |
53 | (types "String 1" "String 2")
54 | ; => "Two strings!"
55 |
56 | (ns data-psychology)
57 | (defprotocol Psychodynamics
58 | "Plumb the inner depths of your data types"
59 | (thoughts [x] "The data type's innermost thoughts")
60 | (feelings-about [x] [x y] "Feelings about self or other"))
61 |
62 | (feelings-about [x] [x & others])
63 |
64 | (extend-type java.lang.String
65 | Psychodynamics
66 | (thoughts [x] (str x " thinks, 'Truly, the character defines the data type'")
67 | (feelings-about
68 | ([x] (str x " is longing for a simpler way of life"))
69 | ([x y] (str x " is envious of " y "'s simpler way of life")))))
70 |
71 | (thoughts "blorb")
72 | ; => "blorb thinks, 'Truly, the character defines the data type'"
73 |
74 | (feelings-about "schmorb")
75 | ; => "schmorb is longing for a simpler way of life"
76 |
77 | (feelings-about "schmorb" 2)
78 | ; => "schmorb is envious of 2's simpler way of life"
79 |
80 | (extend-type java.lang.Object
81 | Psychodynamics
82 | (thoughts [x] "Maybe the Internet is just a vector for toxoplasmosis")
83 | (feelings-about
84 | ([x] "meh")
85 | ([x y] (str "meh about " y))))
86 |
87 | (thoughts 3)
88 | ; => "Maybe the Internet is just a vector for toxoplasmosis"
89 |
90 | (feelings-about 3)
91 | ; => "meh"
92 |
93 | (feelings-about 3 "blorb")
94 | ; => "meh about blorb"
95 |
96 | (extend-protocol Psychodynamics
97 | java.lang.String
98 | (thoughts [x] "Truly, the character defines the data type")
99 | (feelings-about
100 | ([x] "longing for a simpler way of life")
101 | ([x y] (str "envious of " y "'s simpler way of life")))
102 |
103 | java.lang.Object
104 | (thoughts [x] "Maybe the Internet is just a vector for toxoplasmosis")
105 | (feelings-about
106 | ([x] "meh")
107 | ([x y] (str "meh about " y))))
108 |
109 | (ns were-records)
110 | (defrecord WereWolf [name title])
111 |
112 | (WereWolf. "David" "London Tourist")
113 | ; => #were_records.WereWolf{:name "David", :title "London Tourist"}
114 |
115 | (->WereWolf "Jacob" "Lead Shirt Discarder")
116 | ; => #were_records.WereWolf{:name "Jacob", :title "Lead Shirt Discarder"}
117 |
118 | (map->WereWolf {:name "Lucian" :title "CEO of Melodrama"})
119 | ; => #were_records.WereWolf{:name "Lucian", :title "CEO of Melodrama"}
120 |
121 | (ns monster-mash
122 | (:import [were_records WereWolf]))
123 | (WereWolf. "David" "London Tourist")
124 | ; => #were_records.WereWolf{:name "David", :title "London Tourist"}
125 |
126 | (def jacob (->WereWolf "Jacob" "Lead Shirt Discarder"))
127 | (.name jacob)
128 | ; => "Jacob"
129 |
130 | (:name jacob)
131 | ; => "Jacob"
132 |
133 | (get jacob :name)
134 | ; => "Jacob"
135 |
136 | (= jacob (->WereWolf "Jacob" "Lead Shirt Discarder"))
137 | ; => true
138 |
139 | (= jacob (WereWolf. "David" "London Tourist"))
140 | ; => false
141 |
142 | (= jacob {:name "Jacob" :title "Lead Shirt Discarder"})
143 | ; => false
144 |
145 | (assoc jacob :title "Lead Third Wheel")
146 | ; => #were_records.WereWolf{:name "Jacob", :title "Lead Third Wheel"}
147 |
148 | (dissoc jacob :title)
149 | ; => {:name "Jacob"} <- that's not a were_records.WereWolf
150 |
151 |
152 | (defprotocol WereCreature
153 | (full-moon-behavior [x]))
154 |
155 | (defrecord WereWolf [name title]
156 | WereCreature
157 | (full-moon-behavior [x]
158 | (str name " will howl and murder")))
159 |
160 | (full-moon-behavior (map->WereWolf {:name "Lucian" :title "CEO of Melodrama"}))
161 | ; => "Lucian will howl and murder"
162 |
--------------------------------------------------------------------------------
/04/code.clj:
--------------------------------------------------------------------------------
1 | (defn titleize
2 | [topic]
3 | (str topic " for the Brave and True"))
4 |
5 | (map titleize ["Hamsters" "Ragnarok"])
6 | ; => ("Hamsters for the Brave and True" "Ragnarok for the Brave and True")
7 |
8 | (map titleize '("Empathy" "Decorating"))
9 | ; => ("Empathy for the Brave and True" "Decorating for the Brave and True")
10 |
11 | (map titleize #{"Elbows" "Soap Carving"})
12 | ; => ("Elbows for the Brave and True" "Soap Carving for the Brave and True")
13 |
14 | (map #(titleize (second %)) {:uncomfortable-thing "Winking"})
15 | ; => ("Winking for the Brave and True")
16 |
17 | (seq '(1 2 3))
18 | ; => (1 2 3)
19 |
20 | (seq [1 2 3])
21 | ; => (1 2 3)
22 |
23 | (seq #{1 2 3})
24 | ; => (1 2 3)
25 |
26 | (seq {:name "Bill Compton" :occupation "Dead mopey guy"})
27 | ; => ([:name "Bill Compton"] [:occupation "Dead mopey guy"])
28 |
29 | (into {} (seq {:a 1 :b 2 :c 3}))
30 | ; => {:a 1, :c 3, :b 2}
31 |
32 | (map inc [1 2 3])
33 | ; => (2 3 4)
34 |
35 | (map str ["a" "b" "c"] ["A" "B" "C"])
36 | ; => ("aA" "bB" "cC")
37 |
38 | (list (str "a" "A") (str "b" "B") (str "c" "C"))
39 |
40 | (def human-consumption [8.1 7.3 6.6 5.0])
41 | (def critter-consumption [0.0 0.2 0.3 1.1])
42 | (defn unify-diet-data
43 | [human critter]
44 | {:human human
45 | :critter critter})
46 |
47 | (map unify-diet-data human-consumption critter-consumption)
48 | ; => ({:human 8.1, :critter 0.0}
49 | {:human 7.3, :critter 0.2}
50 | {:human 6.6, :critter 0.3}
51 | {:human 5.0, :critter 1.8}
52 |
53 |
54 | (def sum #(reduce + %))
55 | (def avg #(/ (sum %) (count %)))
56 | (defn stats
57 | [numbers]
58 | (map #(% numbers) [sum count avg]))
59 |
60 | (stats [3 4 10])
61 | ; => (17 3 17/3)
62 |
63 | (stats [80 1 44 13 6])
64 | ; => (144 5 144/5)
65 |
66 |
67 | (def identities
68 | [{:alias "Batman" :real "Bruce Wayne"}
69 | {:alias "Spider-Man" :real "Peter Parker"}
70 | {:alias "Santa" :real "Your mom"}
71 | {:alias "Easter Bunny" :real "Your dad"}])
72 |
73 | (map :real identities)
74 | ; => ("Bruce Wayne" "Peter Parker" "Your mom" "Your dad")
75 |
76 | (reduce (fn [new-map [key val]]
77 | (assoc new-map key (inc val)))
78 | {}
79 | {:max 30 :min 10})
80 | ; => {:max 31, :min 11}
81 |
82 | (assoc (assoc {} :max (inc 30))
83 | :min (inc 10))
84 |
85 | (reduce (fn [new-map [key val]]
86 | (if (> val 4)
87 | (assoc new-map key val)
88 | new-map))
89 | {}
90 | {:human 4.1
91 | :critter 3.9})
92 | ; => {:human 4.1}
93 |
94 | (take 3 [1 2 3 4 5 6 7 8 9 10])
95 | ; => (1 2 3)
96 |
97 | (drop 3 [1 2 3 4 5 6 7 8 9 10])
98 | ; => (4 5 6 7 8 9 10)
99 |
100 | (def food-journal
101 | [{:month 1 :day 1 :human 5.3 :critter 2.3}
102 | {:month 1 :day 2 :human 5.1 :critter 2.0}
103 | {:month 2 :day 1 :human 4.9 :critter 2.1}
104 | {:month 2 :day 2 :human 5.0 :critter 2.5}
105 | {:month 3 :day 1 :human 4.2 :critter 3.3}
106 | {:month 3 :day 2 :human 4.0 :critter 3.8}
107 | {:month 4 :day 1 :human 3.7 :critter 3.9}
108 | {:month 4 :day 2 :human 3.7 :critter 3.6}])
109 |
110 | (take-while #(< (:month %) 3) food-journal)
111 | ; => ({:month 1 :day 1 :human 5.3 :critter 2.3}
112 | {:month 1 :day 2 :human 5.1 :critter 2.0}
113 | {:month 2 :day 1 :human 4.9 :critter 2.1}
114 | {:month 2 :day 2 :human 5.0 :critter 2.5}
115 |
116 | (drop-while #(< (:month %) 3) food-journal)
117 | ; => ({:month 3 :day 1 :human 4.2 :critter 3.3}
118 | {:month 3 :day 2 :human 4.0 :critter 3.8}
119 | {:month 4 :day 1 :human 3.7 :critter 3.9}
120 | {:month 4 :day 2 :human 3.7 :critter 3.6}
121 |
122 | (take-while #(< (:month %) 4)
123 | (drop-while #(< (:month %) 2) food-journal))
124 | ; => ({:month 2 :day 1 :human 4.9 :critter 2.1}
125 | {:month 2 :day 2 :human 5.0 :critter 2.5}
126 | {:month 3 :day 1 :human 4.2 :critter 3.3}
127 | {:month 3 :day 2 :human 4.0 :critter 3.8}
128 |
129 | (filter #(< (:human %) 5) food-journal)
130 | ; => ({:month 2 :day 1 :human 4.9 :critter 2.1}
131 | {:month 3 :day 1 :human 4.2 :critter 3.3}
132 | {:month 3 :day 2 :human 4.0 :critter 3.8}
133 | {:month 4 :day 1 :human 3.7 :critter 3.9}
134 | {:month 4 :day 2 :human 3.7 :critter 3.6}
135 |
136 | (filter #(< (:month %) 3) food-journal)
137 | ; => ({:month 1 :day 1 :human 5.3 :critter 2.3}
138 | {:month 1 :day 2 :human 5.1 :critter 2.0}
139 | {:month 2 :day 1 :human 4.9 :critter 2.1}
140 | {:month 2 :day 2 :human 5.0 :critter 2.5}
141 |
142 | (some #(> (:critter %) 5) food-journal)
143 | ; => nil
144 |
145 | (some #(> (:critter %) 3) food-journal)
146 | ; => true
147 |
148 | (some #(and (> (:critter %) 3) %) food-journal)
149 | ; => {:month 3 :day 1 :human 4.2 :critter 3.3}
150 |
151 | (sort [3 1 2])
152 | ; => (1 2 3)
153 |
154 | (sort-by count ["aaa" "c" "bb"])
155 | ; => ("c" "bb" "aaa")
156 |
157 | (concat [1 2] [3 4])
158 | ; => (1 2 3 4)
159 |
160 | (def vampire-database
161 | {0 {:makes-blood-puns? false, :has-pulse? true :name "McFishwich"}
162 | 1 {:makes-blood-puns? false, :has-pulse? true :name "McMackson"}
163 | 2 {:makes-blood-puns? true, :has-pulse? false :name "Damon Salvatore"}
164 | 3 {:makes-blood-puns? true, :has-pulse? true :name "Mickey Mouse"}})
165 |
166 | (defn vampire-related-details
167 | [social-security-number]
168 | (Thread/sleep 1000)
169 | (get vampire-database social-security-number))
170 |
171 | (defn vampire?
172 | [record]
173 | (and (:makes-blood-puns? record)
174 | (not (:has-pulse? record))
175 | record))
176 |
177 | (defn identify-vampire
178 | [social-security-numbers]
179 | (first (filter vampire?
180 | (map vampire-related-details social-security-numbers))))
181 |
182 |
183 | (time (vampire-related-details 0))
184 | ; => "Elapsed time: 1001.042 msecs"
185 | ; => {:name "McFishwich", :makes-blood-puns? false, :has-pulse? true}
186 |
187 | (time (def mapped-details (map vampire-related-details (range 0 1000000))))
188 | ; => "Elapsed time: 0.049 msecs"
189 | ; => #'user/mapped-details
190 |
191 | (time (first mapped-details))
192 | ; => "Elapsed time: 32030.767 msecs"
193 | ; => {:name "McFishwich", :makes-blood-puns? false, :has-pulse? true}
194 |
195 | (time (first mapped-details))
196 | ; => "Elapsed time: 0.022 msecs"
197 | ; => {:name "McFishwich", :makes-blood-puns? false, :has-pulse? true}
198 |
199 | (time (identify-vampire (range 0 1000000)))
200 | "Elapsed time: 32019.912 msecs"
201 | ; => {:name "Damon Salvatore", :makes-blood-puns? true, :has-pulse? false}
202 |
203 | (concat (take 8 (repeat "na")) ["Batman!"])
204 | ; => ("na" "na" "na" "na" "na" "na" "na" "na" "Batman!")
205 |
206 | (take 3 (repeatedly (fn [] (rand-int 10))))
207 | ; => (1 4 0)
208 |
209 | (defn even-numbers
210 | ([] (even-numbers 0))
211 | ([n] (cons n (lazy-seq (even-numbers (+ n 2))))))
212 |
213 | (take 10 (even-numbers))
214 | ; => (0 2 4 6 8 10 12 14 16 18)
215 |
216 | (cons 0 '(2 4 6))
217 | ; => (0 2 4 6)
218 |
219 | (empty? [])
220 | ; => true
221 |
222 | (empty? ["no!"])
223 | ; => false
224 |
225 | (map identity {:sunlight-reaction "Glitter!"})
226 | ; => ([:sunlight-reaction "Glitter!"])
227 |
228 | (into {} (map identity {:sunlight-reaction "Glitter!"}))
229 | ; => {:sunlight-reaction "Glitter!"}
230 |
231 | (map identity [:garlic :sesame-oil :fried-eggs])
232 | ; => (:garlic :sesame-oil :fried-eggs)
233 |
234 | (into [] (map identity [:garlic :sesame-oil :fried-eggs]))
235 | ; => [:garlic :sesame-oil :fried-eggs]
236 |
237 | (map identity [:garlic-clove :garlic-clove])
238 | ; => (:garlic-clove :garlic-clove)
239 |
240 | (into #{} (map identity [:garlic-clove :garlic-clove]))
241 | ; => #{:garlic-clove}
242 |
243 | (into {:favorite-emotion "gloomy"} [[:sunlight-reaction "Glitter!"]])
244 | ; => {:favorite-emotion "gloomy" :sunlight-reaction "Glitter!"}
245 |
246 | (into ["cherry"] '("pine" "spruce"))
247 | ; => ["cherry" "pine" "spruce"]
248 |
249 | (into {:favorite-animal "kitty"} {:least-favorite-smell "dog"
250 | :relationship-with-teenager "creepy"})
251 | ; => {:favorite-animal "kitty"
252 | ; => :relationship-with-teenager "creepy"
253 | ; => :least-favorite-smell "dog"}
254 |
255 | (conj [0] [1])
256 | ; => [0 [1]]
257 |
258 | (into [0] [1])
259 | ; => [0 1]
260 |
261 | (conj [0] 1)
262 | ; => [0 1]
263 |
264 | (conj [0] 1 2 3 4)
265 | ; => [0 1 2 3 4]
266 |
267 | (conj {:time "midnight"} [:place "ye olde cemetarium"])
268 | ; => {:place "ye olde cemetarium" :time "midnight"}
269 |
270 | (defn my-conj
271 | [target & additions]
272 | (into target additions))
273 |
274 | (my-conj [0] 1 2 3)
275 | ; => [0 1 2 3]
276 |
277 | (max 0 1 2)
278 | ; => 2
279 |
280 | (max [0 1 2])
281 | ; => [0 1 2]
282 |
283 | (apply max [0 1 2])
284 | ; => 2
285 |
286 | (defn my-into
287 | [target additions]
288 | (apply conj target additions))
289 |
290 | (my-into [0] [1 2 3])
291 | ; => [0 1 2 3]
292 |
293 | (def add10 (partial + 10))
294 | (add10 3)
295 | ; => 13
296 | (add10 5)
297 | ; => 15
298 |
299 | (def add-missing-elements
300 | (partial conj ["water" "earth" "air"]))
301 |
302 | (add-missing-elements "unobtainium" "adamantium")
303 | ; => ["water" "earth" "air" "unobtainium" "adamantium"]
304 |
305 |
306 | (defn my-partial
307 | [partialized-fn & args]
308 | (fn [& more-args]
309 | (apply partialized-fn (into args more-args))))
310 |
311 | (def add20 (my-partial + 20))
312 | (add20 3)
313 | ; => 23
314 |
315 | (fn [& more-args]
316 | (apply + (into [20] more-args)))
317 |
318 | (defn lousy-logger
319 | [log-level message]
320 | (condp = log-level
321 | :warn (clojure.string/lower-case message)
322 | :emergency (clojure.string/upper-case message)))
323 |
324 | (def warn (partial lousy-logger :warn))
325 |
326 | (warn "Red light ahead")
327 | ; => "red light ahead"
328 |
329 | (defn identify-humans
330 | [social-security-numbers]
331 | (filter #(not (vampire? %))
332 | (map vampire-related-details social-security-numbers)))
333 |
334 | (def not-vampire? (complement vampire?))
335 | (defn identify-humans
336 | [social-security-numbers]
337 | (filter not-vampire?
338 | (map vampire-related-details social-security-numbers)))
339 |
340 | (defn my-complement
341 | [fun]
342 | (fn [& args]
343 | (not (apply fun args))))
344 |
345 | (def my-pos? (complement neg?))
346 | (my-pos? 1)
347 | ; => true
348 |
349 | (my-pos? -1)
350 | ; => false
351 |
352 |
353 | ;; Examples from FWPD
354 |
355 | (slurp filename)
356 | ; => "Edward Cullen,10\nBella Swan,0\nCharlie Swan,0\nJacob Black,3\nCarlisle Cullen,6"
357 |
358 | (parse (slurp filename))
359 | ; => (["Edward Cullen" "10"] ["Bella Swan" "0"] ["Charlie Swan" "0"]
360 | ; => ["Jacob Black" "3"] ["Carlisle Cullen" "6"])
361 |
362 |
363 | (first (mapify (parse (slurp filename))))
364 | ; => {:glitter-index 10, :name "Edward Cullen"}
365 |
366 | (glitter-filter 3 (mapify (parse (slurp filename))))
367 | ({:name "Edward Cullen", :glitter-index 10}
368 | {:name "Jacob Black", :glitter-index 3}
369 | {:name "Carlisle Cullen", :glitter-index 6})
370 |
--------------------------------------------------------------------------------
/08/code.clj:
--------------------------------------------------------------------------------
1 | (macroexpand '(when boolean-expression
2 | expression-1
3 | expression-2
4 | expression-3))
5 | ; => (if boolean-expression
6 | ; => (do expression-1
7 | ; => expression-2
8 | ; => expression-3))
9 |
10 |
11 | (defmacro infix
12 | "Use this macro when you pine for the notation of your childhood"
13 | [infixed]
14 | (list (second infixed) (first infixed) (last infixed)))
15 |
16 |
17 | (infix (1 + 1))
18 | ; => 2
19 |
20 |
21 | (macroexpand '(infix (1 + 1)))
22 | ; => (+ 1 1)
23 |
24 |
25 | (defmacro infix-2
26 | [[operand1 op operand2]]
27 | (list op operand1 operand2))
28 |
29 |
30 | (defmacro and
31 | "Evaluates exprs one at a time, from left to right. If a form
32 | returns logical false (nil or false), and returns that value and
33 | doesn't evaluate any of the other expressions, otherwise it returns
34 | the value of the last expr. (and) returns true."
35 | {:added "1.0"}
36 | ([] true)
37 | ([x] x)
38 | ([x & next]
39 | `(let [and# ~x]
40 | (if and# (and ~@next) and#))))
41 |
42 |
43 | (let [result expression]
44 | (println result)
45 | result)
46 |
47 |
48 | (defmacro my-print-whoopsie
49 | [expression]
50 | (list let [result expression]
51 | (list println result)
52 | result))
53 |
54 |
55 | (defmacro my-print
56 | [expression]
57 | (list 'let ['result expression]
58 | (list 'println 'result)
59 | 'result))
60 |
61 |
62 | (+ 1 2)
63 | ; => 3
64 |
65 |
66 | (quote (+ 1 2))
67 | ; => (+ 1 2)
68 |
69 |
70 | +
71 | ; => #
72 |
73 |
74 | (quote +)
75 | ; => +
76 |
77 |
78 | sweating-to-the-oldies
79 | ; => Unable to resolve symbol: sweating-to-the-oldies in this context
80 |
81 |
82 | (quote sweating-to-the-oldies)
83 | ; => sweating-to-the-oldies
84 |
85 |
86 | '(+ 1 2)
87 | ; => (+ 1 2)
88 |
89 | 'dr-jekyll-and-richard-simmons
90 | ; => dr-jekyll-and-richard-simmons
91 |
92 |
93 | (defmacro when
94 | "Evaluates test. If logical true, evaluates body in an implicit do."
95 | {:added "1.0"}
96 | [test & body]
97 | (list 'if test (cons 'do body)))
98 |
99 |
100 | (macroexpand '(when (the-cows-come :home)
101 | (call me :pappy)
102 | (slap me :silly)))
103 | ; => (if (the-cows-come :home)
104 | (do (call me :pappy)
105 | (slap me :silly)))
106 |
107 |
108 | (defmacro unless
109 | "Inverted 'if'"
110 | [test & branches]
111 | (conj (reverse branches) test 'if))
112 |
113 |
114 | (macroexpand '(unless (done-been slapped? me)
115 | (slap me :silly)
116 | (say "I reckon that'll learn me")))
117 | ; => (if (done-been slapped? me)
118 | (say "I reckon that'll learn me")
119 | (slap me :silly))
120 |
121 |
122 | '+
123 | ; => +
124 |
125 |
126 | 'clojure.core/+
127 | ; => clojure.core/+
128 |
129 |
130 | `+
131 | ; => clojure.core/+
132 |
133 |
134 | '(+ 1 2)
135 | ; => (+ 1 2)
136 |
137 |
138 | `(+ 1 2)
139 | ; => (clojure.core/+ 1 2)
140 |
141 |
142 | `(+ 1 ~(inc 1))
143 | ; => (clojure.core/+ 1 2)
144 |
145 |
146 | `(+ 1 (inc 1))
147 | ; => (clojure.core/+ 1 (clojure.core/inc 1))
148 |
149 |
150 | (list '+ 1 (inc 1))
151 | ; => (+ 1 2)
152 |
153 | `(+ 1 ~(inc 1))
154 | ; => (clojure.core/+ 1 2)
155 |
156 |
157 | (defmacro code-critic
158 | "Phrases are courtesy Hermes Conrad from Futurama"
159 | [bad good]
160 | (list 'do
161 | (list 'println
162 | "Great squid of Madrid, this is bad code:"
163 | (list 'quote bad))
164 | (list 'println
165 | "Sweet gorilla of Manila, this is good code:"
166 | (list 'quote good))))
167 |
168 | (code-critic (1 + 1) (+ 1 1))
169 | ; => Great squid of Madrid, this is bad code: (1 + 1)
170 | ; => Sweet gorilla of Manila, this is good code: (+ 1 1)
171 |
172 |
173 | (defmacro code-critic
174 | "Phrases are courtesy Hermes Conrad from Futurama"
175 | [bad good]
176 | `(do (println "Great squid of Madrid, this is bad code:"
177 | (quote ~bad))
178 | (println "Sweet gorilla of Manila, this is good code:"
179 | (quote ~good))))
180 |
181 |
182 | (defn criticize-code
183 | [criticism code]
184 | `(println ~criticism (quote ~code)))
185 |
186 | (defmacro code-critic
187 | [bad good]
188 | `(do ~(criticize-code "Cursed bacteria of Liberia, this is bad code:" bad)
189 | ~(criticize-code "Sweet sacred boa of Western and Eastern Samoa, this is good code:" good)))
190 |
191 |
192 | (defmacro code-critic
193 | [bad good]
194 | `(do ~(map #(apply criticize-code %)
195 | [["Great squid of Madrid, this is bad code:" bad]
196 | ["Sweet gorilla of Manila, this is good code:" good]])))
197 |
198 |
199 | (code-critic (1 + 1) (+ 1 1))
200 | ; => NullPointerException
201 |
202 |
203 | (do
204 | ((clojure.core/println "criticism" '(1 + 1))
205 | (clojure.core/println "criticism" '(+ 1 1))))
206 |
207 |
208 | (do
209 | (nil
210 | (clojure.core/println "criticism" '(+ 1 1))))
211 |
212 |
213 | (do
214 | (nil nil))
215 |
216 |
217 | `(+ ~(list 1 2 3))
218 | ; => (clojure.core/+ (1 2 3))
219 |
220 |
221 | `(+ ~@(list 1 2 3))
222 | ; => (clojure.core/+ 1 2 3)
223 |
224 |
225 | (defmacro code-critic
226 | [{:keys [good bad]}]
227 | `(do ~@(map #(apply criticize-code %)
228 | [["Sweet lion of Zion, this is bad code:" bad]
229 | ["Great cow of Moscow, this is good code:" good]])))
230 |
231 | (code-critic {:good (+ 1 1) :bad (1 + 1)})
232 | ; => Sweet lion of Zion, this is bad code: (1 + 1)
233 | ; => Great cow of Moscow, this is good code: (+ 1 1)
234 |
235 |
236 | (def message "Good job!")
237 | (defmacro with-mischief
238 | [& stuff-to-do]
239 | (concat (list 'let ['message "Oh, big deal!"])
240 | stuff-to-do))
241 |
242 | (with-mischief
243 | (println "Here's how I feel about that thing you did: " message))
244 | ; => Here's how I feel about that thing you did: Oh, big deal!
245 |
246 |
247 | (def message "Good job!")
248 | (defmacro with-mischief
249 | [& stuff-to-do]
250 | `(let [message "Oh, big deal!"]
251 | ~@stuff-to-do))
252 |
253 | (with-mischief
254 | (println "Here's how I feel about that thing you did: " message))
255 | ; Exception: Can't let qualified name: user/message
256 |
257 |
258 | (gensym)
259 | ; => G__655
260 |
261 | (gensym 'message)
262 | ; => message4760
263 |
264 | (defmacro without-mischief
265 | [& stuff-to-do]
266 | (let [macro-message (gensym 'message)]
267 | `(let [~macro-message "Oh, big deal!"]
268 | ~@stuff-to-do
269 | (println "I still need to say: " ~macro-message))))
270 |
271 | (without-mischief
272 | (println "Here's how I feel about that thing you did: " message))
273 | ; => Here's how I feel about that thing you did: Good job!
274 | ; => I still need to say: Oh, big deal!
275 |
276 |
277 | `(blarg# blarg#)
278 | (blarg__2869__auto__ blarg__2869__auto__)
279 |
280 | `(let [name# "Larry Potter"] name#)
281 | ; => (clojure.core/let [name__2872__auto__ "Larry Potter"] name__2872__auto__)
282 |
283 |
284 | (defmacro report
285 | [to-try]
286 | `(if ~to-try
287 | (println (quote ~to-try) "was successful:" ~to-try)
288 | (println (quote ~to-try) "was not successful:" ~to-try)))
289 |
290 | ;; Thread/sleep takes a number of milliseconds to sleep for
291 | (report (do (Thread/sleep 1000) (+ 1 1)))
292 |
293 |
294 | (if (do (Thread/sleep 1000) (+ 1 1))
295 | (println '(do (Thread/sleep 1000) (+ 1 1))
296 | "was successful:"
297 | (do (Thread/sleep 1000) (+ 1 1)))
298 |
299 | (println '(do (Thread/sleep 1000) (+ 1 1))
300 | "was not successful:"
301 | (do (Thread/sleep 1000) (+ 1 1))))
302 |
303 |
304 | (defmacro report
305 | [to-try]
306 | `(let [result# ~to-try]
307 | (if result#
308 | (println (quote ~to-try) "was successful:" result#)
309 | (println (quote ~to-try) "was not successful:" result#))))
310 |
311 |
312 | (report (= 1 1))
313 | ; => (= 1 1) was successful: true
314 |
315 | (report (= 1 2))
316 | ; => (= 1 2) was not successful: false
317 |
318 |
319 | (doseq [code ['(= 1 1) '(= 1 2)]]
320 | (report code))
321 | ; => code was successful: (= 1 1)
322 | ; => code was successful: (= 1 2)
323 |
324 |
325 | (if
326 | code
327 | (clojure.core/println 'code "was successful:" code)
328 | (clojure.core/println 'code "was not successful:" code))
329 |
330 |
331 | (defmacro doseq-macro
332 | [macroname & args]
333 | `(do
334 | ~@(map (fn [arg] (list macroname arg)) args)))
335 |
336 | (doseq-macro report (= 1 1) (= 1 2))
337 | ; => (= 1 1) was successful: true
338 | ; => (= 1 2) was not successful: false
339 |
340 |
341 | (def order-details
342 | {:name "Mitchard Blimmons"
343 | :email "mitchard.blimmonsgmail.com"})
344 |
345 |
346 | (validate order-details order-details-validations)
347 | ; => {:email ["Your email address doesn't look like an email address."]}
348 |
349 |
350 | (def order-details-validations
351 | {:name
352 | ["Please enter a name" not-empty]
353 |
354 | :email
355 | ["Please enter an email address" not-empty
356 |
357 | "Your email address doesn't look like an email address"
358 | #(or (empty? %) (re-seq #"@" %))]})
359 |
360 |
361 | (defn error-messages-for
362 | "Return a seq of error messages"
363 | [to-validate message-validator-pairs]
364 | (map first (filter #(not ((second %) to-validate))
365 | (partition 2 message-validator-pairs))))
366 |
367 |
368 | (error-messages-for "" ["Please enter a name" not-empty])
369 | ; => ("Please enter a name")
370 |
371 |
372 | (defn validate
373 | "Returns a map with a vector of errors for each key"
374 | [to-validate validations]
375 | (reduce (fn [errors validation]
376 | (let [[fieldname validation-check-groups] validation
377 | value (get to-validate fieldname)
378 | error-messages (error-messages-for value validation-check-groups)]
379 | (if (empty? error-messages)
380 | errors
381 | (assoc errors fieldname error-messages))))
382 | {}
383 | validations))
384 |
385 | (validate order-details order-details-validations)
386 | ; => {:email ["Your email address doesn't look like an email address"]}
387 |
388 |
389 | (let [errors (validate order-details order-details-validations)]
390 | (if (empty? errors)
391 | (println :success)
392 | (println :failure errors)))
393 |
394 |
395 | (defn if-valid
396 | [record validations success-code failure-code]
397 | (let [errors (validate record validations)]
398 | (if (empty? errors)
399 | success-code
400 | failure-code)))
401 |
402 |
403 | (if-valid order-details order-details-validations errors
404 | (render :success)
405 | (render :failure errors))
406 |
407 |
408 | (defmacro if-valid
409 | "Handle validation more concisely"
410 | [to-validate validations errors-name & then-else]
411 | `(let [~errors-name (validate ~to-validate ~validations)]
412 | (if (empty? ~errors-name)
413 | ~@then-else)))
414 |
415 |
416 | (macroexpand
417 | '(if-valid order-details order-details-validations my-error-name
418 | (println :success)
419 | (println :failure my-error-name)))
420 | (let*
421 | [my-error-name (user/validate order-details order-details-validations)]
422 | (if (clojure.core/empty? my-error-name)
423 | (println :success)
424 | (println :failure my-error-name)))
425 |
--------------------------------------------------------------------------------
/04/fwpd/LICENSE:
--------------------------------------------------------------------------------
1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
4 |
5 | 1. DEFINITIONS
6 |
7 | "Contribution" means:
8 |
9 | a) in the case of the initial Contributor, the initial code and
10 | documentation distributed under this Agreement, and
11 |
12 | b) in the case of each subsequent Contributor:
13 |
14 | i) changes to the Program, and
15 |
16 | ii) additions to the Program;
17 |
18 | where such changes and/or additions to the Program originate from and are
19 | distributed by that particular Contributor. A Contribution 'originates' from
20 | a Contributor if it was added to the Program by such Contributor itself or
21 | anyone acting on such Contributor's behalf. Contributions do not include
22 | additions to the Program which: (i) are separate modules of software
23 | distributed in conjunction with the Program under their own license
24 | agreement, and (ii) are not derivative works of the Program.
25 |
26 | "Contributor" means any person or entity that distributes the Program.
27 |
28 | "Licensed Patents" mean patent claims licensable by a Contributor which are
29 | necessarily infringed by the use or sale of its Contribution alone or when
30 | combined with the Program.
31 |
32 | "Program" means the Contributions distributed in accordance with this
33 | Agreement.
34 |
35 | "Recipient" means anyone who receives the Program under this Agreement,
36 | including all Contributors.
37 |
38 | 2. GRANT OF RIGHTS
39 |
40 | a) Subject to the terms of this Agreement, each Contributor hereby grants
41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
42 | reproduce, prepare derivative works of, publicly display, publicly perform,
43 | distribute and sublicense the Contribution of such Contributor, if any, and
44 | such derivative works, in source code and object code form.
45 |
46 | b) Subject to the terms of this Agreement, each Contributor hereby grants
47 | Recipient a non-exclusive, worldwide, royalty-free patent license under
48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
49 | transfer the Contribution of such Contributor, if any, in source code and
50 | object code form. This patent license shall apply to the combination of the
51 | Contribution and the Program if, at the time the Contribution is added by the
52 | Contributor, such addition of the Contribution causes such combination to be
53 | covered by the Licensed Patents. The patent license shall not apply to any
54 | other combinations which include the Contribution. No hardware per se is
55 | licensed hereunder.
56 |
57 | c) Recipient understands that although each Contributor grants the licenses
58 | to its Contributions set forth herein, no assurances are provided by any
59 | Contributor that the Program does not infringe the patent or other
60 | intellectual property rights of any other entity. Each Contributor disclaims
61 | any liability to Recipient for claims brought by any other entity based on
62 | infringement of intellectual property rights or otherwise. As a condition to
63 | exercising the rights and licenses granted hereunder, each Recipient hereby
64 | assumes sole responsibility to secure any other intellectual property rights
65 | needed, if any. For example, if a third party patent license is required to
66 | allow Recipient to distribute the Program, it is Recipient's responsibility
67 | to acquire that license before distributing the Program.
68 |
69 | d) Each Contributor represents that to its knowledge it has sufficient
70 | copyright rights in its Contribution, if any, to grant the copyright license
71 | set forth in this Agreement.
72 |
73 | 3. REQUIREMENTS
74 |
75 | A Contributor may choose to distribute the Program in object code form under
76 | its own license agreement, provided that:
77 |
78 | a) it complies with the terms and conditions of this Agreement; and
79 |
80 | b) its license agreement:
81 |
82 | i) effectively disclaims on behalf of all Contributors all warranties and
83 | conditions, express and implied, including warranties or conditions of title
84 | and non-infringement, and implied warranties or conditions of merchantability
85 | and fitness for a particular purpose;
86 |
87 | ii) effectively excludes on behalf of all Contributors all liability for
88 | damages, including direct, indirect, special, incidental and consequential
89 | damages, such as lost profits;
90 |
91 | iii) states that any provisions which differ from this Agreement are offered
92 | by that Contributor alone and not by any other party; and
93 |
94 | iv) states that source code for the Program is available from such
95 | Contributor, and informs licensees how to obtain it in a reasonable manner on
96 | or through a medium customarily used for software exchange.
97 |
98 | When the Program is made available in source code form:
99 |
100 | a) it must be made available under this Agreement; and
101 |
102 | b) a copy of this Agreement must be included with each copy of the Program.
103 |
104 | Contributors may not remove or alter any copyright notices contained within
105 | the Program.
106 |
107 | Each Contributor must identify itself as the originator of its Contribution,
108 | if any, in a manner that reasonably allows subsequent Recipients to identify
109 | the originator of the Contribution.
110 |
111 | 4. COMMERCIAL DISTRIBUTION
112 |
113 | Commercial distributors of software may accept certain responsibilities with
114 | respect to end users, business partners and the like. While this license is
115 | intended to facilitate the commercial use of the Program, the Contributor who
116 | includes the Program in a commercial product offering should do so in a
117 | manner which does not create potential liability for other Contributors.
118 | Therefore, if a Contributor includes the Program in a commercial product
119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend
120 | and indemnify every other Contributor ("Indemnified Contributor") against any
121 | losses, damages and costs (collectively "Losses") arising from claims,
122 | lawsuits and other legal actions brought by a third party against the
123 | Indemnified Contributor to the extent caused by the acts or omissions of such
124 | Commercial Contributor in connection with its distribution of the Program in
125 | a commercial product offering. The obligations in this section do not apply
126 | to any claims or Losses relating to any actual or alleged intellectual
127 | property infringement. In order to qualify, an Indemnified Contributor must:
128 | a) promptly notify the Commercial Contributor in writing of such claim, and
129 | b) allow the Commercial Contributor tocontrol, and cooperate with the
130 | Commercial Contributor in, the defense and any related settlement
131 | negotiations. The Indemnified Contributor may participate in any such claim
132 | at its own expense.
133 |
134 | For example, a Contributor might include the Program in a commercial product
135 | offering, Product X. That Contributor is then a Commercial Contributor. If
136 | that Commercial Contributor then makes performance claims, or offers
137 | warranties related to Product X, those performance claims and warranties are
138 | such Commercial Contributor's responsibility alone. Under this section, the
139 | Commercial Contributor would have to defend claims against the other
140 | Contributors related to those performance claims and warranties, and if a
141 | court requires any other Contributor to pay any damages as a result, the
142 | Commercial Contributor must pay those damages.
143 |
144 | 5. NO WARRANTY
145 |
146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
151 | appropriateness of using and distributing the Program and assumes all risks
152 | associated with its exercise of rights under this Agreement , including but
153 | not limited to the risks and costs of program errors, compliance with
154 | applicable laws, damage to or loss of data, programs or equipment, and
155 | unavailability or interruption of operations.
156 |
157 | 6. DISCLAIMER OF LIABILITY
158 |
159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
166 | OF SUCH DAMAGES.
167 |
168 | 7. GENERAL
169 |
170 | If any provision of this Agreement is invalid or unenforceable under
171 | applicable law, it shall not affect the validity or enforceability of the
172 | remainder of the terms of this Agreement, and without further action by the
173 | parties hereto, such provision shall be reformed to the minimum extent
174 | necessary to make such provision valid and enforceable.
175 |
176 | If Recipient institutes patent litigation against any entity (including a
177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
178 | (excluding combinations of the Program with other software or hardware)
179 | infringes such Recipient's patent(s), then such Recipient's rights granted
180 | under Section 2(b) shall terminate as of the date such litigation is filed.
181 |
182 | All Recipient's rights under this Agreement shall terminate if it fails to
183 | comply with any of the material terms or conditions of this Agreement and
184 | does not cure such failure in a reasonable period of time after becoming
185 | aware of such noncompliance. If all Recipient's rights under this Agreement
186 | terminate, Recipient agrees to cease use and distribution of the Program as
187 | soon as reasonably practicable. However, Recipient's obligations under this
188 | Agreement and any licenses granted by Recipient relating to the Program shall
189 | continue and survive.
190 |
191 | Everyone is permitted to copy and distribute copies of this Agreement, but in
192 | order to avoid inconsistency the Agreement is copyrighted and may only be
193 | modified in the following manner. The Agreement Steward reserves the right to
194 | publish new versions (including revisions) of this Agreement from time to
195 | time. No one other than the Agreement Steward has the right to modify this
196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
197 | Eclipse Foundation may assign the responsibility to serve as the Agreement
198 | Steward to a suitable separate entity. Each new version of the Agreement will
199 | be given a distinguishing version number. The Program (including
200 | Contributions) may always be distributed subject to the version of the
201 | Agreement under which it was received. In addition, after a new version of
202 | the Agreement is published, Contributor may elect to distribute the Program
203 | (including its Contributions) under the new version. Except as expressly
204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
205 | licenses to the intellectual property of any Contributor under this
206 | Agreement, whether expressly, by implication, estoppel or otherwise. All
207 | rights in the Program not expressly granted under this Agreement are
208 | reserved.
209 |
210 | This Agreement is governed by the laws of the State of New York and the
211 | intellectual property laws of the United States of America. No party to this
212 | Agreement will bring a legal action under this Agreement more than one year
213 | after the cause of action arose. Each party waives its rights to a jury trial
214 | in any resulting litigation.
215 |
--------------------------------------------------------------------------------
/11/playsync/LICENSE:
--------------------------------------------------------------------------------
1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
4 |
5 | 1. DEFINITIONS
6 |
7 | "Contribution" means:
8 |
9 | a) in the case of the initial Contributor, the initial code and
10 | documentation distributed under this Agreement, and
11 |
12 | b) in the case of each subsequent Contributor:
13 |
14 | i) changes to the Program, and
15 |
16 | ii) additions to the Program;
17 |
18 | where such changes and/or additions to the Program originate from and are
19 | distributed by that particular Contributor. A Contribution 'originates' from
20 | a Contributor if it was added to the Program by such Contributor itself or
21 | anyone acting on such Contributor's behalf. Contributions do not include
22 | additions to the Program which: (i) are separate modules of software
23 | distributed in conjunction with the Program under their own license
24 | agreement, and (ii) are not derivative works of the Program.
25 |
26 | "Contributor" means any person or entity that distributes the Program.
27 |
28 | "Licensed Patents" mean patent claims licensable by a Contributor which are
29 | necessarily infringed by the use or sale of its Contribution alone or when
30 | combined with the Program.
31 |
32 | "Program" means the Contributions distributed in accordance with this
33 | Agreement.
34 |
35 | "Recipient" means anyone who receives the Program under this Agreement,
36 | including all Contributors.
37 |
38 | 2. GRANT OF RIGHTS
39 |
40 | a) Subject to the terms of this Agreement, each Contributor hereby grants
41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
42 | reproduce, prepare derivative works of, publicly display, publicly perform,
43 | distribute and sublicense the Contribution of such Contributor, if any, and
44 | such derivative works, in source code and object code form.
45 |
46 | b) Subject to the terms of this Agreement, each Contributor hereby grants
47 | Recipient a non-exclusive, worldwide, royalty-free patent license under
48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
49 | transfer the Contribution of such Contributor, if any, in source code and
50 | object code form. This patent license shall apply to the combination of the
51 | Contribution and the Program if, at the time the Contribution is added by the
52 | Contributor, such addition of the Contribution causes such combination to be
53 | covered by the Licensed Patents. The patent license shall not apply to any
54 | other combinations which include the Contribution. No hardware per se is
55 | licensed hereunder.
56 |
57 | c) Recipient understands that although each Contributor grants the licenses
58 | to its Contributions set forth herein, no assurances are provided by any
59 | Contributor that the Program does not infringe the patent or other
60 | intellectual property rights of any other entity. Each Contributor disclaims
61 | any liability to Recipient for claims brought by any other entity based on
62 | infringement of intellectual property rights or otherwise. As a condition to
63 | exercising the rights and licenses granted hereunder, each Recipient hereby
64 | assumes sole responsibility to secure any other intellectual property rights
65 | needed, if any. For example, if a third party patent license is required to
66 | allow Recipient to distribute the Program, it is Recipient's responsibility
67 | to acquire that license before distributing the Program.
68 |
69 | d) Each Contributor represents that to its knowledge it has sufficient
70 | copyright rights in its Contribution, if any, to grant the copyright license
71 | set forth in this Agreement.
72 |
73 | 3. REQUIREMENTS
74 |
75 | A Contributor may choose to distribute the Program in object code form under
76 | its own license agreement, provided that:
77 |
78 | a) it complies with the terms and conditions of this Agreement; and
79 |
80 | b) its license agreement:
81 |
82 | i) effectively disclaims on behalf of all Contributors all warranties and
83 | conditions, express and implied, including warranties or conditions of title
84 | and non-infringement, and implied warranties or conditions of merchantability
85 | and fitness for a particular purpose;
86 |
87 | ii) effectively excludes on behalf of all Contributors all liability for
88 | damages, including direct, indirect, special, incidental and consequential
89 | damages, such as lost profits;
90 |
91 | iii) states that any provisions which differ from this Agreement are offered
92 | by that Contributor alone and not by any other party; and
93 |
94 | iv) states that source code for the Program is available from such
95 | Contributor, and informs licensees how to obtain it in a reasonable manner on
96 | or through a medium customarily used for software exchange.
97 |
98 | When the Program is made available in source code form:
99 |
100 | a) it must be made available under this Agreement; and
101 |
102 | b) a copy of this Agreement must be included with each copy of the Program.
103 |
104 | Contributors may not remove or alter any copyright notices contained within
105 | the Program.
106 |
107 | Each Contributor must identify itself as the originator of its Contribution,
108 | if any, in a manner that reasonably allows subsequent Recipients to identify
109 | the originator of the Contribution.
110 |
111 | 4. COMMERCIAL DISTRIBUTION
112 |
113 | Commercial distributors of software may accept certain responsibilities with
114 | respect to end users, business partners and the like. While this license is
115 | intended to facilitate the commercial use of the Program, the Contributor who
116 | includes the Program in a commercial product offering should do so in a
117 | manner which does not create potential liability for other Contributors.
118 | Therefore, if a Contributor includes the Program in a commercial product
119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend
120 | and indemnify every other Contributor ("Indemnified Contributor") against any
121 | losses, damages and costs (collectively "Losses") arising from claims,
122 | lawsuits and other legal actions brought by a third party against the
123 | Indemnified Contributor to the extent caused by the acts or omissions of such
124 | Commercial Contributor in connection with its distribution of the Program in
125 | a commercial product offering. The obligations in this section do not apply
126 | to any claims or Losses relating to any actual or alleged intellectual
127 | property infringement. In order to qualify, an Indemnified Contributor must:
128 | a) promptly notify the Commercial Contributor in writing of such claim, and
129 | b) allow the Commercial Contributor tocontrol, and cooperate with the
130 | Commercial Contributor in, the defense and any related settlement
131 | negotiations. The Indemnified Contributor may participate in any such claim
132 | at its own expense.
133 |
134 | For example, a Contributor might include the Program in a commercial product
135 | offering, Product X. That Contributor is then a Commercial Contributor. If
136 | that Commercial Contributor then makes performance claims, or offers
137 | warranties related to Product X, those performance claims and warranties are
138 | such Commercial Contributor's responsibility alone. Under this section, the
139 | Commercial Contributor would have to defend claims against the other
140 | Contributors related to those performance claims and warranties, and if a
141 | court requires any other Contributor to pay any damages as a result, the
142 | Commercial Contributor must pay those damages.
143 |
144 | 5. NO WARRANTY
145 |
146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
151 | appropriateness of using and distributing the Program and assumes all risks
152 | associated with its exercise of rights under this Agreement , including but
153 | not limited to the risks and costs of program errors, compliance with
154 | applicable laws, damage to or loss of data, programs or equipment, and
155 | unavailability or interruption of operations.
156 |
157 | 6. DISCLAIMER OF LIABILITY
158 |
159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
166 | OF SUCH DAMAGES.
167 |
168 | 7. GENERAL
169 |
170 | If any provision of this Agreement is invalid or unenforceable under
171 | applicable law, it shall not affect the validity or enforceability of the
172 | remainder of the terms of this Agreement, and without further action by the
173 | parties hereto, such provision shall be reformed to the minimum extent
174 | necessary to make such provision valid and enforceable.
175 |
176 | If Recipient institutes patent litigation against any entity (including a
177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
178 | (excluding combinations of the Program with other software or hardware)
179 | infringes such Recipient's patent(s), then such Recipient's rights granted
180 | under Section 2(b) shall terminate as of the date such litigation is filed.
181 |
182 | All Recipient's rights under this Agreement shall terminate if it fails to
183 | comply with any of the material terms or conditions of this Agreement and
184 | does not cure such failure in a reasonable period of time after becoming
185 | aware of such noncompliance. If all Recipient's rights under this Agreement
186 | terminate, Recipient agrees to cease use and distribution of the Program as
187 | soon as reasonably practicable. However, Recipient's obligations under this
188 | Agreement and any licenses granted by Recipient relating to the Program shall
189 | continue and survive.
190 |
191 | Everyone is permitted to copy and distribute copies of this Agreement, but in
192 | order to avoid inconsistency the Agreement is copyrighted and may only be
193 | modified in the following manner. The Agreement Steward reserves the right to
194 | publish new versions (including revisions) of this Agreement from time to
195 | time. No one other than the Agreement Steward has the right to modify this
196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
197 | Eclipse Foundation may assign the responsibility to serve as the Agreement
198 | Steward to a suitable separate entity. Each new version of the Agreement will
199 | be given a distinguishing version number. The Program (including
200 | Contributions) may always be distributed subject to the version of the
201 | Agreement under which it was received. In addition, after a new version of
202 | the Agreement is published, Contributor may elect to distribute the Program
203 | (including its Contributions) under the new version. Except as expressly
204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
205 | licenses to the intellectual property of any Contributor under this
206 | Agreement, whether expressly, by implication, estoppel or otherwise. All
207 | rights in the Program not expressly granted under this Agreement are
208 | reserved.
209 |
210 | This Agreement is governed by the laws of the State of New York and the
211 | intellectual property laws of the United States of America. No party to this
212 | Agreement will bring a legal action under this Agreement more than one year
213 | after the cause of action arose. Each party waives its rights to a jury trial
214 | in any resulting litigation.
215 |
--------------------------------------------------------------------------------
/01/clojure-noob/LICENSE:
--------------------------------------------------------------------------------
1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
4 |
5 | 1. DEFINITIONS
6 |
7 | "Contribution" means:
8 |
9 | a) in the case of the initial Contributor, the initial code and
10 | documentation distributed under this Agreement, and
11 |
12 | b) in the case of each subsequent Contributor:
13 |
14 | i) changes to the Program, and
15 |
16 | ii) additions to the Program;
17 |
18 | where such changes and/or additions to the Program originate from and are
19 | distributed by that particular Contributor. A Contribution 'originates' from
20 | a Contributor if it was added to the Program by such Contributor itself or
21 | anyone acting on such Contributor's behalf. Contributions do not include
22 | additions to the Program which: (i) are separate modules of software
23 | distributed in conjunction with the Program under their own license
24 | agreement, and (ii) are not derivative works of the Program.
25 |
26 | "Contributor" means any person or entity that distributes the Program.
27 |
28 | "Licensed Patents" mean patent claims licensable by a Contributor which are
29 | necessarily infringed by the use or sale of its Contribution alone or when
30 | combined with the Program.
31 |
32 | "Program" means the Contributions distributed in accordance with this
33 | Agreement.
34 |
35 | "Recipient" means anyone who receives the Program under this Agreement,
36 | including all Contributors.
37 |
38 | 2. GRANT OF RIGHTS
39 |
40 | a) Subject to the terms of this Agreement, each Contributor hereby grants
41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
42 | reproduce, prepare derivative works of, publicly display, publicly perform,
43 | distribute and sublicense the Contribution of such Contributor, if any, and
44 | such derivative works, in source code and object code form.
45 |
46 | b) Subject to the terms of this Agreement, each Contributor hereby grants
47 | Recipient a non-exclusive, worldwide, royalty-free patent license under
48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
49 | transfer the Contribution of such Contributor, if any, in source code and
50 | object code form. This patent license shall apply to the combination of the
51 | Contribution and the Program if, at the time the Contribution is added by the
52 | Contributor, such addition of the Contribution causes such combination to be
53 | covered by the Licensed Patents. The patent license shall not apply to any
54 | other combinations which include the Contribution. No hardware per se is
55 | licensed hereunder.
56 |
57 | c) Recipient understands that although each Contributor grants the licenses
58 | to its Contributions set forth herein, no assurances are provided by any
59 | Contributor that the Program does not infringe the patent or other
60 | intellectual property rights of any other entity. Each Contributor disclaims
61 | any liability to Recipient for claims brought by any other entity based on
62 | infringement of intellectual property rights or otherwise. As a condition to
63 | exercising the rights and licenses granted hereunder, each Recipient hereby
64 | assumes sole responsibility to secure any other intellectual property rights
65 | needed, if any. For example, if a third party patent license is required to
66 | allow Recipient to distribute the Program, it is Recipient's responsibility
67 | to acquire that license before distributing the Program.
68 |
69 | d) Each Contributor represents that to its knowledge it has sufficient
70 | copyright rights in its Contribution, if any, to grant the copyright license
71 | set forth in this Agreement.
72 |
73 | 3. REQUIREMENTS
74 |
75 | A Contributor may choose to distribute the Program in object code form under
76 | its own license agreement, provided that:
77 |
78 | a) it complies with the terms and conditions of this Agreement; and
79 |
80 | b) its license agreement:
81 |
82 | i) effectively disclaims on behalf of all Contributors all warranties and
83 | conditions, express and implied, including warranties or conditions of title
84 | and non-infringement, and implied warranties or conditions of merchantability
85 | and fitness for a particular purpose;
86 |
87 | ii) effectively excludes on behalf of all Contributors all liability for
88 | damages, including direct, indirect, special, incidental and consequential
89 | damages, such as lost profits;
90 |
91 | iii) states that any provisions which differ from this Agreement are offered
92 | by that Contributor alone and not by any other party; and
93 |
94 | iv) states that source code for the Program is available from such
95 | Contributor, and informs licensees how to obtain it in a reasonable manner on
96 | or through a medium customarily used for software exchange.
97 |
98 | When the Program is made available in source code form:
99 |
100 | a) it must be made available under this Agreement; and
101 |
102 | b) a copy of this Agreement must be included with each copy of the Program.
103 |
104 | Contributors may not remove or alter any copyright notices contained within
105 | the Program.
106 |
107 | Each Contributor must identify itself as the originator of its Contribution,
108 | if any, in a manner that reasonably allows subsequent Recipients to identify
109 | the originator of the Contribution.
110 |
111 | 4. COMMERCIAL DISTRIBUTION
112 |
113 | Commercial distributors of software may accept certain responsibilities with
114 | respect to end users, business partners and the like. While this license is
115 | intended to facilitate the commercial use of the Program, the Contributor who
116 | includes the Program in a commercial product offering should do so in a
117 | manner which does not create potential liability for other Contributors.
118 | Therefore, if a Contributor includes the Program in a commercial product
119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend
120 | and indemnify every other Contributor ("Indemnified Contributor") against any
121 | losses, damages and costs (collectively "Losses") arising from claims,
122 | lawsuits and other legal actions brought by a third party against the
123 | Indemnified Contributor to the extent caused by the acts or omissions of such
124 | Commercial Contributor in connection with its distribution of the Program in
125 | a commercial product offering. The obligations in this section do not apply
126 | to any claims or Losses relating to any actual or alleged intellectual
127 | property infringement. In order to qualify, an Indemnified Contributor must:
128 | a) promptly notify the Commercial Contributor in writing of such claim, and
129 | b) allow the Commercial Contributor tocontrol, and cooperate with the
130 | Commercial Contributor in, the defense and any related settlement
131 | negotiations. The Indemnified Contributor may participate in any such claim
132 | at its own expense.
133 |
134 | For example, a Contributor might include the Program in a commercial product
135 | offering, Product X. That Contributor is then a Commercial Contributor. If
136 | that Commercial Contributor then makes performance claims, or offers
137 | warranties related to Product X, those performance claims and warranties are
138 | such Commercial Contributor's responsibility alone. Under this section, the
139 | Commercial Contributor would have to defend claims against the other
140 | Contributors related to those performance claims and warranties, and if a
141 | court requires any other Contributor to pay any damages as a result, the
142 | Commercial Contributor must pay those damages.
143 |
144 | 5. NO WARRANTY
145 |
146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
151 | appropriateness of using and distributing the Program and assumes all risks
152 | associated with its exercise of rights under this Agreement , including but
153 | not limited to the risks and costs of program errors, compliance with
154 | applicable laws, damage to or loss of data, programs or equipment, and
155 | unavailability or interruption of operations.
156 |
157 | 6. DISCLAIMER OF LIABILITY
158 |
159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
166 | OF SUCH DAMAGES.
167 |
168 | 7. GENERAL
169 |
170 | If any provision of this Agreement is invalid or unenforceable under
171 | applicable law, it shall not affect the validity or enforceability of the
172 | remainder of the terms of this Agreement, and without further action by the
173 | parties hereto, such provision shall be reformed to the minimum extent
174 | necessary to make such provision valid and enforceable.
175 |
176 | If Recipient institutes patent litigation against any entity (including a
177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
178 | (excluding combinations of the Program with other software or hardware)
179 | infringes such Recipient's patent(s), then such Recipient's rights granted
180 | under Section 2(b) shall terminate as of the date such litigation is filed.
181 |
182 | All Recipient's rights under this Agreement shall terminate if it fails to
183 | comply with any of the material terms or conditions of this Agreement and
184 | does not cure such failure in a reasonable period of time after becoming
185 | aware of such noncompliance. If all Recipient's rights under this Agreement
186 | terminate, Recipient agrees to cease use and distribution of the Program as
187 | soon as reasonably practicable. However, Recipient's obligations under this
188 | Agreement and any licenses granted by Recipient relating to the Program shall
189 | continue and survive.
190 |
191 | Everyone is permitted to copy and distribute copies of this Agreement, but in
192 | order to avoid inconsistency the Agreement is copyrighted and may only be
193 | modified in the following manner. The Agreement Steward reserves the right to
194 | publish new versions (including revisions) of this Agreement from time to
195 | time. No one other than the Agreement Steward has the right to modify this
196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
197 | Eclipse Foundation may assign the responsibility to serve as the Agreement
198 | Steward to a suitable separate entity. Each new version of the Agreement will
199 | be given a distinguishing version number. The Program (including
200 | Contributions) may always be distributed subject to the version of the
201 | Agreement under which it was received. In addition, after a new version of
202 | the Agreement is published, Contributor may elect to distribute the Program
203 | (including its Contributions) under the new version. Except as expressly
204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
205 | licenses to the intellectual property of any Contributor under this
206 | Agreement, whether expressly, by implication, estoppel or otherwise. All
207 | rights in the Program not expressly granted under this Agreement are
208 | reserved.
209 |
210 | This Agreement is governed by the laws of the State of New York and the
211 | intellectual property laws of the United States of America. No party to this
212 | Agreement will bring a legal action under this Agreement more than one year
213 | after the cause of action arose. Each party waives its rights to a jury trial
214 | in any resulting litigation.
215 |
--------------------------------------------------------------------------------
/06/the-divine-cheese-code/LICENSE:
--------------------------------------------------------------------------------
1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
4 |
5 | 1. DEFINITIONS
6 |
7 | "Contribution" means:
8 |
9 | a) in the case of the initial Contributor, the initial code and
10 | documentation distributed under this Agreement, and
11 |
12 | b) in the case of each subsequent Contributor:
13 |
14 | i) changes to the Program, and
15 |
16 | ii) additions to the Program;
17 |
18 | where such changes and/or additions to the Program originate from and are
19 | distributed by that particular Contributor. A Contribution 'originates' from
20 | a Contributor if it was added to the Program by such Contributor itself or
21 | anyone acting on such Contributor's behalf. Contributions do not include
22 | additions to the Program which: (i) are separate modules of software
23 | distributed in conjunction with the Program under their own license
24 | agreement, and (ii) are not derivative works of the Program.
25 |
26 | "Contributor" means any person or entity that distributes the Program.
27 |
28 | "Licensed Patents" mean patent claims licensable by a Contributor which are
29 | necessarily infringed by the use or sale of its Contribution alone or when
30 | combined with the Program.
31 |
32 | "Program" means the Contributions distributed in accordance with this
33 | Agreement.
34 |
35 | "Recipient" means anyone who receives the Program under this Agreement,
36 | including all Contributors.
37 |
38 | 2. GRANT OF RIGHTS
39 |
40 | a) Subject to the terms of this Agreement, each Contributor hereby grants
41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
42 | reproduce, prepare derivative works of, publicly display, publicly perform,
43 | distribute and sublicense the Contribution of such Contributor, if any, and
44 | such derivative works, in source code and object code form.
45 |
46 | b) Subject to the terms of this Agreement, each Contributor hereby grants
47 | Recipient a non-exclusive, worldwide, royalty-free patent license under
48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
49 | transfer the Contribution of such Contributor, if any, in source code and
50 | object code form. This patent license shall apply to the combination of the
51 | Contribution and the Program if, at the time the Contribution is added by the
52 | Contributor, such addition of the Contribution causes such combination to be
53 | covered by the Licensed Patents. The patent license shall not apply to any
54 | other combinations which include the Contribution. No hardware per se is
55 | licensed hereunder.
56 |
57 | c) Recipient understands that although each Contributor grants the licenses
58 | to its Contributions set forth herein, no assurances are provided by any
59 | Contributor that the Program does not infringe the patent or other
60 | intellectual property rights of any other entity. Each Contributor disclaims
61 | any liability to Recipient for claims brought by any other entity based on
62 | infringement of intellectual property rights or otherwise. As a condition to
63 | exercising the rights and licenses granted hereunder, each Recipient hereby
64 | assumes sole responsibility to secure any other intellectual property rights
65 | needed, if any. For example, if a third party patent license is required to
66 | allow Recipient to distribute the Program, it is Recipient's responsibility
67 | to acquire that license before distributing the Program.
68 |
69 | d) Each Contributor represents that to its knowledge it has sufficient
70 | copyright rights in its Contribution, if any, to grant the copyright license
71 | set forth in this Agreement.
72 |
73 | 3. REQUIREMENTS
74 |
75 | A Contributor may choose to distribute the Program in object code form under
76 | its own license agreement, provided that:
77 |
78 | a) it complies with the terms and conditions of this Agreement; and
79 |
80 | b) its license agreement:
81 |
82 | i) effectively disclaims on behalf of all Contributors all warranties and
83 | conditions, express and implied, including warranties or conditions of title
84 | and non-infringement, and implied warranties or conditions of merchantability
85 | and fitness for a particular purpose;
86 |
87 | ii) effectively excludes on behalf of all Contributors all liability for
88 | damages, including direct, indirect, special, incidental and consequential
89 | damages, such as lost profits;
90 |
91 | iii) states that any provisions which differ from this Agreement are offered
92 | by that Contributor alone and not by any other party; and
93 |
94 | iv) states that source code for the Program is available from such
95 | Contributor, and informs licensees how to obtain it in a reasonable manner on
96 | or through a medium customarily used for software exchange.
97 |
98 | When the Program is made available in source code form:
99 |
100 | a) it must be made available under this Agreement; and
101 |
102 | b) a copy of this Agreement must be included with each copy of the Program.
103 |
104 | Contributors may not remove or alter any copyright notices contained within
105 | the Program.
106 |
107 | Each Contributor must identify itself as the originator of its Contribution,
108 | if any, in a manner that reasonably allows subsequent Recipients to identify
109 | the originator of the Contribution.
110 |
111 | 4. COMMERCIAL DISTRIBUTION
112 |
113 | Commercial distributors of software may accept certain responsibilities with
114 | respect to end users, business partners and the like. While this license is
115 | intended to facilitate the commercial use of the Program, the Contributor who
116 | includes the Program in a commercial product offering should do so in a
117 | manner which does not create potential liability for other Contributors.
118 | Therefore, if a Contributor includes the Program in a commercial product
119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend
120 | and indemnify every other Contributor ("Indemnified Contributor") against any
121 | losses, damages and costs (collectively "Losses") arising from claims,
122 | lawsuits and other legal actions brought by a third party against the
123 | Indemnified Contributor to the extent caused by the acts or omissions of such
124 | Commercial Contributor in connection with its distribution of the Program in
125 | a commercial product offering. The obligations in this section do not apply
126 | to any claims or Losses relating to any actual or alleged intellectual
127 | property infringement. In order to qualify, an Indemnified Contributor must:
128 | a) promptly notify the Commercial Contributor in writing of such claim, and
129 | b) allow the Commercial Contributor tocontrol, and cooperate with the
130 | Commercial Contributor in, the defense and any related settlement
131 | negotiations. The Indemnified Contributor may participate in any such claim
132 | at its own expense.
133 |
134 | For example, a Contributor might include the Program in a commercial product
135 | offering, Product X. That Contributor is then a Commercial Contributor. If
136 | that Commercial Contributor then makes performance claims, or offers
137 | warranties related to Product X, those performance claims and warranties are
138 | such Commercial Contributor's responsibility alone. Under this section, the
139 | Commercial Contributor would have to defend claims against the other
140 | Contributors related to those performance claims and warranties, and if a
141 | court requires any other Contributor to pay any damages as a result, the
142 | Commercial Contributor must pay those damages.
143 |
144 | 5. NO WARRANTY
145 |
146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
151 | appropriateness of using and distributing the Program and assumes all risks
152 | associated with its exercise of rights under this Agreement , including but
153 | not limited to the risks and costs of program errors, compliance with
154 | applicable laws, damage to or loss of data, programs or equipment, and
155 | unavailability or interruption of operations.
156 |
157 | 6. DISCLAIMER OF LIABILITY
158 |
159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
166 | OF SUCH DAMAGES.
167 |
168 | 7. GENERAL
169 |
170 | If any provision of this Agreement is invalid or unenforceable under
171 | applicable law, it shall not affect the validity or enforceability of the
172 | remainder of the terms of this Agreement, and without further action by the
173 | parties hereto, such provision shall be reformed to the minimum extent
174 | necessary to make such provision valid and enforceable.
175 |
176 | If Recipient institutes patent litigation against any entity (including a
177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
178 | (excluding combinations of the Program with other software or hardware)
179 | infringes such Recipient's patent(s), then such Recipient's rights granted
180 | under Section 2(b) shall terminate as of the date such litigation is filed.
181 |
182 | All Recipient's rights under this Agreement shall terminate if it fails to
183 | comply with any of the material terms or conditions of this Agreement and
184 | does not cure such failure in a reasonable period of time after becoming
185 | aware of such noncompliance. If all Recipient's rights under this Agreement
186 | terminate, Recipient agrees to cease use and distribution of the Program as
187 | soon as reasonably practicable. However, Recipient's obligations under this
188 | Agreement and any licenses granted by Recipient relating to the Program shall
189 | continue and survive.
190 |
191 | Everyone is permitted to copy and distribute copies of this Agreement, but in
192 | order to avoid inconsistency the Agreement is copyrighted and may only be
193 | modified in the following manner. The Agreement Steward reserves the right to
194 | publish new versions (including revisions) of this Agreement from time to
195 | time. No one other than the Agreement Steward has the right to modify this
196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
197 | Eclipse Foundation may assign the responsibility to serve as the Agreement
198 | Steward to a suitable separate entity. Each new version of the Agreement will
199 | be given a distinguishing version number. The Program (including
200 | Contributions) may always be distributed subject to the version of the
201 | Agreement under which it was received. In addition, after a new version of
202 | the Agreement is published, Contributor may elect to distribute the Program
203 | (including its Contributions) under the new version. Except as expressly
204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
205 | licenses to the intellectual property of any Contributor under this
206 | Agreement, whether expressly, by implication, estoppel or otherwise. All
207 | rights in the Program not expressly granted under this Agreement are
208 | reserved.
209 |
210 | This Agreement is governed by the laws of the State of New York and the
211 | intellectual property laws of the United States of America. No party to this
212 | Agreement will bring a legal action under this Agreement more than one year
213 | after the cause of action arose. Each party waives its rights to a jury trial
214 | in any resulting litigation.
215 |
--------------------------------------------------------------------------------
/10/code.clj:
--------------------------------------------------------------------------------
1 | (def fred (atom {:cuddle-hunger-level 0
2 | :percent-deteriorated 0}))
3 | @fred
4 | ; => {:cuddle-hunger-level 0, :percent-deteriorated 0}
5 |
6 | (let [zombie-state @fred]
7 | (if (>= (:percent-deteriorated zombie-state) 50)
8 | (future (println (:percent-deteriorated zombie-state)))))
9 |
10 | (swap! fred
11 | (fn [current-state]
12 | (merge-with + current-state {:cuddle-hunger-level 1})))
13 | ; => {:cuddle-hunger-level 1, :percent-deteriorated 0}
14 |
15 | @fred
16 | ; => {:cuddle-hunger-level 1, :percent-deteriorated 0}
17 |
18 | (swap! fred
19 | (fn [current-state]
20 | (merge-with + current-state {:cuddle-hunger-level 1
21 | :percent-deteriorated 1})))
22 | ; => {:cuddle-hunger-level 2, :percent-deteriorated 1}
23 |
24 | (defn increase-cuddle-hunger-level
25 | [zombie-state increase-by]
26 | (merge-with + zombie-state {:cuddle-hunger-level increase-by}))
27 |
28 | (increase-cuddle-hunger-level @fred 10)
29 | ; => {:cuddle-hunger-level 12, :percent-deteriorated 1}
30 |
31 | (swap! fred increase-cuddle-hunger-level 10)
32 | ; => {:cuddle-hunger-level 12, :percent-deteriorated 1}
33 |
34 | @fred
35 | ; => {:cuddle-hunger-level 12, :percent-deteriorated 1}
36 |
37 | (update-in {:a {:b 3}} [:a :b] inc)
38 | ; => {:a {:b 4}}
39 |
40 | (update-in {:a {:b 3}} [:a :b] + 10)
41 | ; => {:a {:b 13}}
42 |
43 | (swap! fred update-in [:cuddle-hunger-level] + 10)
44 | ; => {:cuddle-hunger-level 22, :percent-deteriorated 1}
45 |
46 | (let [num (atom 1)
47 | s1 @num]
48 | (swap! num inc)
49 | (println "State 1:" s1)
50 | (println "Current state:" @num))
51 | ; => State 1: 1
52 | ; => Current state: 2
53 |
54 | (reset! fred {:cuddle-hunger-level 0
55 | :percent-deteriorated 0})
56 |
57 | (defn shuffle-speed
58 | [zombie]
59 | (* (:cuddle-hunger-level zombie)
60 | (- 100 (:percent-deteriorated zombie))))
61 |
62 | (defn shuffle-alert
63 | [key watched old-state new-state]
64 | (let [sph (shuffle-speed new-state)]
65 | (if (> sph 5000)
66 | (do
67 | (println "Run, you fool!")
68 | (println "The zombie's SPH is now " sph)
69 | (println "This message brought to your courtesy of " key))
70 | (do
71 | (println "All's well with " key)
72 | (println "Cuddle hunger: " (:cuddle-hunger-level new-state))
73 | (println "Percent deteriorated: " (:percent-deteriorated new-state))
74 | (println "SPH: " sph)))))
75 |
76 | (reset! fred {:cuddle-hunger-level 22
77 | :percent-deteriorated 2})
78 | (add-watch fred :fred-shuffle-alert shuffle-alert)
79 | (swap! fred update-in [:percent-deteriorated] + 1)
80 | ; => All's well with :fred-shuffle-alert
81 | ; => Cuddle hunger: 22
82 | ; => Percent deteriorated: 3
83 | ; => SPH: 2134
84 |
85 | (swap! fred update-in [:cuddle-hunger-level] + 30)
86 | ; => Run, you fool!
87 | ; => The zombie's SPH is now 5044
88 | ; => This message brought to your courtesy of :fred-shuffle-alert
89 |
90 | (defn percent-deteriorated-validator
91 | [{:keys [percent-deteriorated]}]
92 | (and (>= percent-deteriorated 0)
93 | (<= percent-deteriorated 100)))
94 |
95 | (def bobby
96 | (atom
97 | {:cuddle-hunger-level 0 :percent-deteriorated 0}
98 | :validator percent-deteriorated-validator))
99 | (swap! bobby update-in [:percent-deteriorated] + 200)
100 | ; This throws "Invalid reference state"
101 |
102 | (defn percent-deteriorated-validator
103 | [{:keys [percent-deteriorated]}]
104 | (or (and (>= percent-deteriorated 0)
105 | (<= percent-deteriorated 100))
106 | (throw (IllegalStateException. "That's not mathy!"))))
107 | (def bobby
108 | (atom
109 | {:cuddle-hunger-level 0 :percent-deteriorated 0}
110 | :validator percent-deteriorated-validator))
111 | (swap! bobby update-in [:percent-deteriorated] + 200)
112 | ; This throws "IllegalStateException That's not mathy!"
113 |
114 | (def sock-varieties
115 | #{"darned" "argyle" "wool" "horsehair" "mulleted"
116 | "passive-aggressive" "striped" "polka-dotted"
117 | "athletic" "business" "power" "invisible" "gollumed"})
118 |
119 | (defn sock-count
120 | [sock-variety count]
121 | {:variety sock-variety
122 | :count count})
123 |
124 | (defn generate-sock-gnome
125 | "Create an initial sock gnome state with no socks"
126 | [name]
127 | {:name name
128 | :socks #{}})
129 |
130 | (def sock-gnome (ref (generate-sock-gnome "Barumpharumph")))
131 | (def dryer (ref {:name "LG 1337"
132 | :socks (set (map #(sock-count % 2) sock-varieties))}))
133 |
134 | (:socks @dryer)
135 | ; => #{{:variety "passive-aggressive", :count 2} {:variety "power", :count 2}
136 | ; => {:variety "athletic", :count 2} {:variety "business", :count 2}
137 | ; => {:variety "argyle", :count 2} {:variety "horsehair", :count 2}
138 | ; => {:variety "gollumed", :count 2} {:variety "darned", :count 2}
139 | ; => {:variety "polka-dotted", :count 2} {:variety "wool", :count 2}
140 | ; => {:variety "mulleted", :count 2} {:variety "striped", :count 2}
141 | ; => {:variety "invisible", :count 2}}
142 |
143 | (defn steal-sock
144 | [gnome dryer]
145 | (dosync
146 | (when-let [pair (some #(if (= (:count %) 2) %) (:socks @dryer))]
147 | (let [updated-count (sock-count (:variety pair) 1)]
148 | (alter gnome update-in [:socks] conj updated-count)
149 | (alter dryer update-in [:socks] disj pair)
150 | (alter dryer update-in [:socks] conj updated-count)))))
151 | (steal-sock sock-gnome dryer)
152 |
153 | (:socks @sock-gnome)
154 | ; => #{{:variety "passive-aggressive", :count 1}}
155 |
156 | (defn similar-socks
157 | [target-sock sock-set]
158 | (filter #(= (:variety %) (:variety target-sock)) sock-set))
159 |
160 | (similar-socks (first (:socks @sock-gnome)) (:socks @dryer))
161 | ; => ({:variety "passive-aggressive", :count 1})
162 |
163 |
164 | (def counter (ref 0))
165 | (future
166 | (dosync
167 | (alter counter inc)
168 | (println @counter)
169 | (Thread/sleep 500)
170 | (alter counter inc)
171 | (println @counter)))
172 | (Thread/sleep 250)
173 | (println @counter)
174 |
175 | (defn sleep-print-update
176 | [sleep-time thread-name update-fn]
177 | (fn [state]
178 | (Thread/sleep sleep-time)
179 | (println (str thread-name ": " state))
180 | (update-fn state)))
181 | (def counter (ref 0))
182 | (future (dosync (commute counter (sleep-print-update 100 "Thread A" inc))))
183 | (future (dosync (commute counter (sleep-print-update 150 "Thread B" inc))))
184 |
185 | (def receiver-a (ref #{}))
186 | (def receiver-b (ref #{}))
187 | (def giver (ref #{1}))
188 | (do (future (dosync (let [gift (first @giver)]
189 | (Thread/sleep 10)
190 | (commute receiver-a conj gift)
191 | (commute giver disj gift))))
192 | (future (dosync (let [gift (first @giver)]
193 | (Thread/sleep 50)
194 | (commute receiver-b conj gift)
195 | (commute giver disj gift)))))
196 |
197 | @receiver-a
198 | ; => #{1}
199 |
200 | @receiver-b
201 | ; => #{1}
202 |
203 | @giver
204 | ; => #{}
205 |
206 |
207 | (def ^:dynamic *notification-address* "dobby@elf.org")
208 |
209 | (binding [*notification-address* "test@elf.org"]
210 | *notification-address*)
211 | ; => "test@elf.org"
212 |
213 | (binding [*notification-address* "tester-1@elf.org"]
214 | (println *notification-address*)
215 | (binding [*notification-address* "tester-2@elf.org"]
216 | (println *notification-address*))
217 | (println *notification-address*))
218 | ; => tester-1@elf.org
219 | ; => tester-2@elf.org
220 | ; => tester-1@elf.org
221 |
222 | (defn notify
223 | [message]
224 | (str "TO: " *notification-address* "\n"
225 | "MESSAGE: " message))
226 | (notify "I fell.")
227 | ; => "TO: dobby@elf.org\nMESSAGE: I fell."
228 |
229 | (binding [*notification-address* "test@elf.org"]
230 | (notify "test!"))
231 | ; => "TO: test@elf.org\nMESSAGE: test!"
232 |
233 | (binding [*out* (clojure.java.io/writer "print-output")]
234 | (println "A man who carries a cat by the tail learns
235 | something he can learn in no other way.
236 | -- Mark Twain"))
237 | (slurp "print-output")
238 | ; => A man who carries a cat by the tail learns
239 | ; => something he can learn in no other way.
240 | ; => -- Mark Twain
241 |
242 | (println ["Print" "all" "the" "things!"])
243 | ; => [Print all the things!]
244 |
245 | (binding [*print-length* 1]
246 | (println ["Print" "just" "one!"]))
247 | ; => [Print ...]
248 |
249 | (def ^:dynamic *troll-thought* nil)
250 | (defn troll-riddle
251 | [your-answer]
252 | (let [number "man meat"]
253 | (when (thread-bound? #'*troll-thought*)
254 | (set! *troll-thought* number))
255 | (if (= number your-answer)
256 | "TROLL: You can cross the bridge!"
257 | "TROLL: Time to eat you, succulent human!")))
258 |
259 | (binding [*troll-thought* nil]
260 | (println (troll-riddle 2))
261 | (println "SUCCULENT HUMAN: Oooooh! The answer was" *troll-thought*))
262 |
263 | ; => TROLL: Time to eat you, succulent human!
264 | ; => SUCCULENT HUMAN: Oooooh! The answer was man meat
265 |
266 | *troll-thought*
267 | ; => nil
268 |
269 | (.write *out* "prints to repl")
270 | ; => prints to repl
271 |
272 | (.start (Thread. #(.write *out* "prints to standard out")))
273 |
274 | (let [out *out*]
275 | (.start
276 | (Thread. #(binding [*out* out]
277 | (.write *out* "prints to repl from thread")))))
278 |
279 | (.start (Thread. (bound-fn [] (.write *out* "prints to repl from thread"))))
280 |
281 | (def power-source "hair")
282 |
283 | (alter-var-root #'power-source (fn [_] "7-eleven parking lot"))
284 | power-source
285 | ; => "7-eleven parking lot"
286 |
287 | (with-redefs [*out* *out*]
288 | (doto (Thread. #(println "with redefs allows me to show up in the REPL"))
289 | .start
290 | .join))
291 |
292 | (defn always-1
293 | []
294 | 1)
295 | (take 5 (repeatedly always-1))
296 | ; => (1 1 1 1 1)
297 |
298 | (take 5 (repeatedly (partial rand-int 10)))
299 | ; => (1 5 0 3 4)
300 |
301 | (def alphabet-length 26)
302 |
303 | ;; Vector of chars, A-Z
304 | (def letters (mapv (comp str char (partial + 65)) (range alphabet-length)))
305 |
306 | (defn random-string
307 | "Returns a random string of specified length"
308 | [length]
309 | (apply str (take length (repeatedly #(rand-nth letters)))))
310 |
311 | (defn random-string-list
312 | [list-length string-length]
313 | (doall (take list-length (repeatedly (partial random-string string-length)))))
314 |
315 | (def orc-names (random-string-list 3000 7000))
316 |
317 | (time (dorun (map clojure.string/lower-case orc-names)))
318 | ; => "Elapsed time: 270.182 msecs"
319 |
320 | (time (dorun (pmap clojure.string/lower-case orc-names)))
321 | ; => "Elapsed time: 147.562 msecs"
322 |
323 |
324 | (def orc-name-abbrevs (random-string-list 20000 300))
325 | (time (dorun (map clojure.string/lower-case orc-name-abbrevs)))
326 | ; => "Elapsed time: 78.23 msecs"
327 | (time (dorun (pmap clojure.string/lower-case orc-name-abbrevs)))
328 | ; => "Elapsed time: 124.727 msecs"
329 |
330 | (def numbers [1 2 3 4 5 6 7 8 9 10])
331 | (partition-all 3 numbers)
332 | ; => ((1 2 3) (4 5 6) (7 8 9) (10))
333 |
334 | (pmap inc numbers)
335 |
336 | (pmap (fn [number-group] (doall (map inc number-group)))
337 | (partition-all 3 numbers))
338 | ; => ((2 3 4) (5 6 7) (8 9 10) (11))
339 |
340 | (apply concat
341 | (pmap (fn [number-group] (doall (map inc number-group)))
342 | (partition-all 3 numbers)))
343 |
344 | (time
345 | (dorun
346 | (apply concat
347 | (pmap (fn [name] (doall (map clojure.string/lower-case name)))
348 | (partition-all 1000 orc-name-abbrevs)))))
349 | ; => "Elapsed time: 44.677 msecs"
350 |
351 | (defn ppmap
352 | "Partitioned pmap, for grouping map ops together to make parallel
353 | overhead worthwhile"
354 | [grain-size f & colls]
355 | (apply concat
356 | (apply pmap
357 | (fn [& pgroups] (doall (apply map f pgroups)))
358 | (map (partial partition-all grain-size) colls))))
359 | (time (dorun (ppmap 1000 clojure.string/lower-case orc-name-abbrevs)))
360 | ; => "Elapsed time: 44.902 msecs"
361 |
362 | (quote-word-count 5)
363 | ; => {"ochre" 8, "smoothie" 2}
364 |
--------------------------------------------------------------------------------
/03/code.clj:
--------------------------------------------------------------------------------
1 | ;; valid forms
2 | 1
3 | "a string"
4 | ["a" "vector" "of" "strings"]
5 |
6 |
7 | ;; general form of operations. This won't actually run because
8 | ;; operator, operand1, etc aren't bound
9 | (operator operand1 operand2 ... operandn)
10 |
11 |
12 | ;; Example operations
13 | (+ 1 2 3)
14 | ; => 6
15 |
16 | (str "It was the panda " "in the library " "with a dust buster")
17 | ; => "It was the panda in the library with a dust buster"
18 |
19 |
20 | ;; This is an invalid form. I've commented it out so it doesn't mess
21 | ;; things up if you try to evaluate this file.
22 | ;; (+
23 |
24 |
25 | ;; General structure of `if`
26 | (if boolean-form
27 | then-form
28 | optional-else-form)
29 |
30 | ;; if examples
31 | (if true
32 | "By Zeus's hammer!"
33 | "By Aquaman's trident!")
34 | ; => "By Zeus's hammer!"
35 |
36 | (if false
37 | "By Zeus's hammer!"
38 | "By Aquaman's trident!")
39 | ; => "By Aquaman's trident!"
40 |
41 |
42 | (if false
43 | "By Odin's Elbow!")
44 | ; => nil
45 |
46 | (if true
47 | (do (println "Success!")
48 | "By Zeus's hammer!")
49 | (do (println "Failure!")
50 | "By Aquaman's trident!"))
51 | ; => Success!
52 | ; => "By Zeus's hammer!"
53 |
54 |
55 | ;; More boolean operators
56 | (when true
57 | (println "Success!")
58 | "abra cadabra")
59 | ; => Success!
60 | ; => "abra cadabra"
61 |
62 |
63 | (nil? 1)
64 | ; => false
65 |
66 | (nil? nil)
67 | ; => true
68 |
69 | (if "bears eat beets"
70 | "bears beets Battlestar Galactica")
71 | ; => "bears beets Battlestar Galactica"
72 |
73 | (if nil
74 | "This won't be the result because nil is falsey"
75 | "nil is falsey")
76 | ; => "nil is falsey"
77 |
78 | (= 1 1)
79 | ; => true
80 |
81 | (= nil nil)
82 | ; => true
83 |
84 | (= 1 2)
85 | ; => false
86 |
87 | (or false nil :large_I_mean_venti :why_cant_I_just_say_large)
88 | ; => :large_I_mean_venti
89 |
90 | (or (= 0 1) (= "yes" "no"))
91 | ; => false
92 |
93 | (or nil)
94 | ; => nil
95 |
96 | (and :free_wifi :hot_coffee)
97 | ; => :hot_coffee
98 |
99 | (and :feelin_super_cool nil false)
100 | ; => nil
101 |
102 |
103 | ;; Naming Values with def
104 | (def failed-protagonist-names
105 | ["Larry Potter" "Doreen the Explorer" "The Incredible Bulk"])
106 |
107 | failed-protagonist-names
108 | ; => ["Larry Potter" "Doreen the Explorer" "The Incredible Bulk"]
109 |
110 |
111 | ;; This is bad, don't do this
112 | (def severity :mild)
113 | (def error-message "OH GOD! IT'S A DISASTER! WE'RE ")
114 | (if (= severity :mild)
115 | (def error-message (str error-message "MILDLY INCONVENIENCED!"))
116 | (def error-message (str error-message "DOOOOOOOMED!")))
117 |
118 | ;; This is better
119 | (defn error-message
120 | [severity]
121 | (str "OH GOD! IT'S A DISASTER! WE'RE "
122 | (if (= severity :mild)
123 | "MILDLY INCONVENIENCED!"
124 | "DOOOOOOOMED!")))
125 |
126 | (error-message :mild)
127 | ; => "OH GOD! IT'S A DISASTER! WE'RE MILDLY INCONVENIENCED!"
128 |
129 |
130 | ;; Oh look, some numbers
131 | 93
132 | 1.2
133 | 1/5
134 |
135 | ;; Oooh and some strings
136 | "Lord Voldemort"
137 | "\"He who must not be named\""
138 | "\"Great cow of Moscow!\" - Hermes Conrad"
139 |
140 | (def name "Chewbacca")
141 | (str "\"Uggllglglglglglglglll\" - " name)
142 | ; => "Uggllglglglglglglglll" - Chewbacca
143 |
144 |
145 | ;; Maps now
146 | {}
147 |
148 | {:first-name "Charlie"
149 | :last-name "McFishwich"}
150 |
151 | {"string-key" +}
152 |
153 | {:name {:first "John" :middle "Jacob" :last "Jingleheimerschmidt"}}
154 |
155 | (hash-map :a 1 :b 2)
156 | ; => {:a 1 :b 2}
157 |
158 | (get {:a 0 :b 1} :b)
159 | ; => 1
160 |
161 | (get {:a 0 :b {:c "ho hum"}} :b)
162 | ; => {:c "ho hum"}
163 |
164 |
165 | (get {:a 0 :b 1} :c)
166 | ; => nil
167 |
168 | (get {:a 0 :b 1} :c "unicorns?")
169 | ; => "unicorns?"
170 |
171 |
172 | (get-in {:a 0 :b {:c "ho hum"}} [:b :c])
173 | ; => "ho hum"
174 |
175 |
176 | ({:name "The Human Coffeepot"} :name)
177 | ; => "The Human Coffeepot"
178 |
179 |
180 | ;; Here we're looking at keywords
181 | :a
182 | :rumplestiltsken
183 | :34
184 | :_?
185 |
186 | (:a {:a 1 :b 2 :c 3})
187 | ; => 1
188 |
189 | (get {:a 1 :b 2 :c 3} :a)
190 | ; => 1
191 |
192 | (:d {:a 1 :b 2 :c 3} "No gnome knows homes like Noah knows")
193 | ; => "No gnome knows homes like Noah knows"
194 |
195 |
196 | ;; Vector time!
197 | [3 2 1]
198 |
199 | (get [3 2 1] 0)
200 | ; => 3
201 |
202 | (get ["a" {:name "Pugsley Winterbottom"} "c"] 1)
203 | ; => {:name "Pugsley Winterbottom"}
204 |
205 | (vector "creepy" "full" "moon")
206 | ; => ["creepy" "full" "moon"]
207 |
208 | (conj [1 2 3] 4)
209 | ; => [1 2 3 4]
210 |
211 |
212 | ;; List time!
213 | '(1 2 3 4)
214 | ; => (1 2 3 4)
215 |
216 | (nth '(:a :b :c) 0)
217 | ; => :a
218 |
219 | (nth '(:a :b :c) 2)
220 | ; => :c
221 |
222 | (list 1 "two" {3 4})
223 | ; => (1 "two" {3 4})
224 |
225 | (conj '(1 2 3) 4)
226 | ; => (4 1 2 3)
227 |
228 |
229 | ;; Sets are super cool. Here's some set usage
230 | #{"kurt vonnegut" 20 :icicle}
231 |
232 | (hash-set 1 1 2 2)
233 | ; => #{1 2}
234 |
235 | (conj #{:a :b} :b)
236 | ; => #{:a :b}
237 |
238 | (set [3 3 3 4 4])
239 | ; => #{3 4}
240 |
241 | (contains? #{:a :b} :a)
242 | ; => true
243 |
244 | (contains? #{:a :b} 3)
245 | ; => false
246 |
247 | (contains? #{nil} nil)
248 | ; => true
249 |
250 | (:a #{:a :b})
251 | ; => :a
252 |
253 | (get #{:a :b} :a)
254 | ; => :a
255 |
256 | (get #{:a nil} nil)
257 | ; => nil
258 |
259 | (get #{:a :b} "kurt vonnegut")
260 | ; => nil
261 |
262 |
263 | ;; Just some more example function calls
264 | (+ 1 2 3 4)
265 | (* 1 2 3 4)
266 | (first [1 2 3 4])
267 |
268 | ;; You can return functions as values
269 | (or + -)
270 | ; => #
271 |
272 | ;; Some neat tricks
273 | ((or + -) 1 2 3)
274 | ; => 6
275 |
276 | ((and (= 1 1) +) 1 2 3)
277 | ; => 6
278 |
279 | ((first [+ 0]) 1 2 3)
280 | ; => 6
281 |
282 |
283 | ;; These won't work
284 | (1 2 3 4)
285 | ("test" 1 2 3)
286 |
287 |
288 | ;; Higher-order function examples
289 | (inc 1.1)
290 | ; => 2.1
291 |
292 | (map inc [0 1 2 3])
293 | ; => (1 2 3 4)
294 |
295 |
296 | ;; Demonstrating recursive evaluation
297 | (+ (inc 199) (/ 100 (- 7 2)))
298 | (+ 200 (/ 100 (- 7 2))) ; evaluated "(inc 199)"
299 | (+ 200 (/ 100 5)) ; evaluated (- 7 2)
300 | (+ 200 20) ; evaluated (/ 100 5)
301 | 220 ; final evaluation
302 |
303 |
304 | ;; Special forms
305 | (if boolean-form
306 | then-form
307 | optional-else-form)
308 |
309 |
310 | (if good-mood
311 | (tweet walking-on-sunshine-lyrics)
312 | (tweet mopey-country-song-lyrics))
313 |
314 |
315 | ;; Defining your own function
316 | (defn too-enthusiastic
317 | "Return a cheer that might be a bit too enthusiastic"
318 | [name]
319 | (str "OH. MY. GOD! " name " YOU ARE MOST DEFINITELY LIKE THE BEST "
320 | "MAN SLASH WOMAN EVER I LOVE YOU AND WE SHOULD RUN AWAY SOMEWHERE"))
321 |
322 | (too-enthusiastic "Zelda")
323 | ; => "OH. MY. GOD! Zelda YOU ARE MOST DEFINITELY LIKE THE BEST MAN SLASH WOMAN EVER I LOVE YOU AND WE SHOULD RUN AWAY SOMEWHERE"
324 |
325 |
326 | ;; Arity examples
327 | (defn no-params
328 | []
329 | "I take no parameters!")
330 | (defn one-param
331 | [x]
332 | (str "I take one parameter: " x))
333 | (defn two-params
334 | [x y]
335 | (str "Two parameters! That's nothing! Pah! I will smoosh them "
336 | "together to spite you! " x y))
337 |
338 | (defn multi-arity
339 | ;; 3-arity arguments and body
340 | ([first-arg second-arg third-arg]
341 | (do-things first-arg second-arg third-arg))
342 | ;; 2-arity arguments and body
343 | ([first-arg second-arg]
344 | (do-things first-arg second-arg))
345 | ;; 1-arity arguments and body
346 | ([first-arg]
347 | (do-things first-arg)))
348 |
349 |
350 | ;; Using arity to provide a default value for an argument
351 | (defn x-chop
352 | "Describe the kind of chop you're inflicting on someone"
353 | ([name chop-type]
354 | (str "I " chop-type " chop " name "! Take that!"))
355 | ([name]
356 | (x-chop name "karate")))
357 |
358 | (x-chop "Kanye West" "slap")
359 | ; => "I slap chop Kanye West! Take that!"
360 |
361 | (x-chop "Kanye East")
362 | ; => "I karate chop Kanye East! Take that!"
363 |
364 | (defn weird-arity
365 | ([]
366 | "Destiny dressed you this morning, my friend, and now Fear is
367 | trying to pull off your pants. If you give up, if you give in,
368 | you're gonna end up naked with Fear just standing there laughing
369 | at your dangling unmentionables! - the Tick")
370 | ([number]
371 | (inc number)))
372 |
373 |
374 | ;; Rest parameters
375 | (defn codger-communication
376 | [whippersnapper]
377 | (str "Get off my lawn, " whippersnapper "!!!"))
378 |
379 | (defn codger
380 | [& whippersnappers]
381 | (map codger-communication whippersnappers))
382 |
383 | (codger "Billy" "Anne-Marie" "The Incredible Bulk")
384 | ; => ("Get off my lawn, Billy!!!"
385 | ; => "Get off my lawn, Anne-Marie!!!"
386 | ; => "Get off my lawn, The Incredible Bulk!!!")
387 |
388 |
389 | (defn favorite-things
390 | [name & things]
391 | (str "Hi, " name ", here are my favorite things: "
392 | (clojure.string/join ", " things)))
393 |
394 | (favorite-things "Doreen" "gum" "shoes" "kara-te")
395 | ; => "Hi, Doreen, here are my favorite things: gum, shoes, kara-te"
396 |
397 |
398 | ;; Destructuring
399 | ;; Return the first element of a collection
400 | (defn my-first
401 | [[first-thing]] ; Notice that first-thing is within a vector
402 | first-thing)
403 |
404 | (my-first ["oven" "bike" "war-axe"])
405 | ; => "oven"
406 |
407 | (defn chooser
408 | [[first-choice second-choice & unimportant-choices]]
409 | (println (str "Your first choice is: " first-choice))
410 | (println (str "Your second choice is: " second-choice))
411 | (println (str "We're ignoring the rest of your choices. "
412 | "Here they are in case you need to cry over them: "
413 | (clojure.string/join ", " unimportant-choices))))
414 |
415 | (chooser ["Marmalade", "Handsome Jack", "Pigpen", "Aquaman"])
416 | ; => Your first choice is: Marmalade
417 | ; => Your second choice is: Handsome Jack
418 | ; => We're ignoring the rest of your choices. Here they are in case \
419 | ; => you need to cry over them: Pigpen, Aquaman
420 |
421 |
422 | ;; Destructuring maps
423 | (defn announce-treasure-location
424 | [{lat :lat lng :lng}]
425 | (println (str "Treasure lat: " lat))
426 | (println (str "Treasure lng: " lng)))
427 |
428 | (announce-treasure-location {:lat 28.22 :lng 81.33})
429 | ; => Treasure lat: 28.22
430 | ; => Treasure lng: 81.33
431 |
432 | (defn announce-treasure-location
433 | [{:keys [lat lng]}]
434 | (println (str "Treasure lat: " lat))
435 | (println (str "Treasure lng: " lng)))
436 |
437 | (defn receive-treasure-location
438 | [{:keys [lat lng] :as treasure-location}]
439 | (println (str "Treasure lat: " lat))
440 | (println (str "Treasure lng: " lng))
441 |
442 | ;; One would assume that this would put in new coordinates for your ship
443 | (steer-ship! treasure-location))
444 |
445 |
446 | ;; Function bodies return the last value
447 | (defn illustrative-function
448 | []
449 | (+ 1 304)
450 | 30
451 | "joe")
452 |
453 | (illustrative-function)
454 | ; => "joe"
455 |
456 | (defn number-comment
457 | [x]
458 | (if (> x 6)
459 | "Oh my gosh! What a big number!"
460 | "That number's OK, I guess"))
461 |
462 | (number-comment 5)
463 | ; => "That number's OK, I guess"
464 |
465 | (number-comment 7)
466 | ; => "Oh my gosh! What a big number!"
467 |
468 |
469 | ;; Anonymous functions
470 | (fn [param-list]
471 | function body)
472 |
473 | (map (fn [name] (str "Hi, " name))
474 | ["Darth Vader" "Mr. Magoo"])
475 | ; => ("Hi, Darth Vader" "Hi, Mr. Magoo")
476 |
477 | ((fn [x] (* x 3)) 8)
478 | ; => 24
479 |
480 |
481 | (def my-special-multiplier (fn [x] (* x 3)))
482 | (my-special-multiplier 12)
483 | ; => 36
484 |
485 |
486 | ;; Compact anonymous function
487 | #(* % 3)
488 |
489 | (#(* % 3) 8)
490 | ; => 24
491 |
492 | (map #(str "Hi, " %)
493 | ["Darth Vader" "Mr. Magoo"])
494 | ; => ("Hi, Darth Vader" "Hi, Mr. Magoo")
495 |
496 | ;; Function call
497 | (* 8 3)
498 |
499 | ;; Anonymous function
500 | #(* % 3)
501 |
502 |
503 | (#(str %1 " and " %2) "cornbread" "butter beans")
504 | ; => "cornbread and butter beans"
505 |
506 | (#(identity %&) 1 "blarg" :yip)
507 | ; => (1 "blarg" :yip)
508 |
509 |
510 | ;; Returning functions
511 | (defn inc-maker
512 | "Create a custom incrementor"
513 | [inc-by]
514 | #(+ % inc-by))
515 |
516 | (def inc3 (inc-maker 3))
517 |
518 | (inc3 7)
519 | ; => 10
520 |
521 |
522 | ;; Hobbit violence!
523 | (def asym-hobbit-body-parts [{:name "head" :size 3}
524 | {:name "left-eye" :size 1}
525 | {:name "left-ear" :size 1}
526 | {:name "mouth" :size 1}
527 | {:name "nose" :size 1}
528 | {:name "neck" :size 2}
529 | {:name "left-shoulder" :size 3}
530 | {:name "left-upper-arm" :size 3}
531 | {:name "chest" :size 10}
532 | {:name "back" :size 10}
533 | {:name "left-forearm" :size 3}
534 | {:name "abdomen" :size 6}
535 | {:name "left-kidney" :size 1}
536 | {:name "left-hand" :size 2}
537 | {:name "left-knee" :size 2}
538 | {:name "left-thigh" :size 4}
539 | {:name "left-lower-leg" :size 3}
540 | {:name "left-achilles" :size 1}
541 | {:name "left-foot" :size 2}])
542 |
543 |
544 | (defn matching-part
545 | [part]
546 | {:name (clojure.string/replace (:name part) #"^left-" "right-")
547 | :size (:size part)})
548 |
549 | (defn symmetrize-body-parts
550 | "Expects a seq of maps that have a :name and :size"
551 | [asym-body-parts]
552 | (loop [remaining-asym-parts asym-body-parts
553 | final-body-parts []]
554 | (if (empty? remaining-asym-parts)
555 | final-body-parts
556 | (let [[part & remaining] remaining-asym-parts]
557 | (recur remaining
558 | (into final-body-parts
559 | (set [part (matching-part part)])))))))
560 |
561 |
562 | (symmetrize-body-parts asym-hobbit-body-parts)
563 | ; => [{:name "head", :size 3}
564 | {:name "left-eye", :size 1}
565 | {:name "right-eye", :size 1}
566 | {:name "left-ear", :size 1}
567 | {:name "right-ear", :size 1}
568 | {:name "mouth", :size 1}
569 | {:name "nose", :size 1}
570 | {:name "neck", :size 2}
571 | {:name "left-shoulder", :size 3}
572 | {:name "right-shoulder", :size 3}
573 | {:name "left-upper-arm", :size 3}
574 | {:name "right-upper-arm", :size 3}
575 | {:name "chest", :size 10}
576 | {:name "back", :size 10}
577 | {:name "left-forearm", :size 3}
578 | {:name "right-forearm", :size 3}
579 | {:name "abdomen", :size 6}
580 | {:name "left-kidney", :size 1}
581 | {:name "right-kidney", :size 1}
582 | {:name "left-hand", :size 2}
583 | {:name "right-hand", :size 2}
584 | {:name "left-knee", :size 2}
585 | {:name "right-knee", :size 2}
586 | {:name "left-thigh", :size 4}
587 | {:name "right-thigh", :size 4}
588 | {:name "left-lower-leg", :size 3}
589 | {:name "right-lower-leg", :size 3}
590 | {:name "left-achilles", :size 1}
591 | {:name "right-achilles", :size 1}
592 | {:name "left-foot", :size 2}
593 | {:name "right-foot", :size 2}]
594 |
595 |
596 | ;; Let expressions
597 | (let [x 3]
598 | x)
599 | ; => 3
600 |
601 | (def dalmatian-list
602 | ["Pongo" "Perdita" "Puppy 1" "Puppy 2"])
603 | (let [dalmatians (take 2 dalmatian-list)]
604 | dalmatians)
605 | ; => ("Pongo" "Perdita")
606 |
607 |
608 | (def x 0)
609 | (let [x 1] x)
610 | ; => 1
611 |
612 |
613 | (def x 0)
614 | (let [x (inc x)] x)
615 | ; => 1
616 |
617 |
618 | (let [[pongo & dalmatians] dalmatian-list]
619 | [pongo dalmatians])
620 | ; => ["Pongo" ("Perdita" "Puppy 1" "Puppy 2")]
621 |
622 |
623 | (let [[part & remaining] remaining-asym-parts]
624 | (recur remaining
625 | (into final-body-parts
626 | (set [part (matching-part part)]))))
627 |
628 |
629 | ;; Into
630 | (into final-body-parts
631 | (set [part (matching-part part)]))
632 |
633 |
634 | (into [] (set [:a :a]))
635 | ; => [:a]
636 |
637 |
638 | ;; example ugly code
639 | (recur (rest remaining-asym-parts)
640 | (into final-body-parts
641 | (set [(first remaining-asym-parts) (matching-part (first remaining-asym-parts))])))
642 |
643 |
644 | ;; Loop
645 | (loop [iteration 0]
646 | (println (str "Iteration " iteration))
647 | (if (> iteration 3)
648 | (println "Goodbye!")
649 | (recur (inc iteration))))
650 | ; => Iteration 0
651 | ; => Iteration 1
652 | ; => Iteration 2
653 | ; => Iteration 3
654 | ; => Iteration 4
655 | ; => Goodbye!
656 |
657 |
658 | (defn recursive-printer
659 | ([]
660 | (recursive-printer 0))
661 | ([iteration]
662 | (println iteration)
663 | (if (> iteration 3)
664 | (println "Goodbye!")
665 | (recursive-printer (inc iteration)))))
666 | (recursive-printer)
667 | ; => Iteration 0
668 | ; => Iteration 1
669 | ; => Iteration 2
670 | ; => Iteration 3
671 | ; => Iteration 4
672 | ; => Goodbye!
673 |
674 |
675 | ;; Regular expressions
676 | #"regular-expression"
677 |
678 | (re-find #"^left-" "left-eye")
679 | ; => "left-"
680 |
681 | (re-find #"^left-" "cleft-chin")
682 | ; => nil
683 |
684 | (re-find #"^left-" "wongleblart")
685 | ; => nil
686 |
687 |
688 | ;; More hobbit violence
689 | (defn matching-part
690 | [part]
691 | {:name (clojure.string/replace (:name part) #"^left-" "right-")
692 | :size (:size part)})
693 | (matching-part {:name "left-eye" :size 1})
694 | ; => {:name "right-eye" :size 1}]
695 |
696 | (matching-part {:name "head" :size 3})
697 | ; => {:name "head" :size 3}]
698 |
699 |
700 | ;; sum with reduce
701 | (reduce + [1 2 3 4])
702 | ; => 10
703 |
704 | (+ (+ (+ 1 2) 3) 4)
705 |
706 | (reduce + 15 [1 2 3 4])
707 |
708 |
709 | ;; build your own reduce function
710 | (defn my-reduce
711 | ([f initial coll]
712 | (loop [result initial
713 | remaining coll]
714 | (if (empty? remaining)
715 | result
716 | (recur (f result (first remaining)) (rest remaining)))))
717 | ([f [head & tail]]
718 | (my-reduce f head tail)))
719 |
720 | (defn better-symmetrize-body-parts
721 | "Expects a seq of maps that have a :name and :size"
722 | [asym-body-parts]
723 | (reduce (fn [final-body-parts part]
724 | (into final-body-parts (set [part (matching-part part)])))
725 | []
726 | asym-body-parts))
727 |
728 | (defn hit
729 | [asym-body-parts]
730 | (let [sym-parts (better-symmetrize-body-parts asym-body-parts)
731 | body-part-size-sum (reduce + (map :size sym-parts))
732 | target (rand body-part-size-sum)]
733 | (loop [[part & remaining] sym-parts
734 | accumulated-size (:size part)]
735 | (if (> accumulated-size target)
736 | part
737 | (recur remaining (+ accumulated-size (:size (first remaining))))))))
738 |
739 |
740 | (hit asym-hobbit-body-parts)
741 | ; => {:name "right-upper-arm", :size 3}
742 |
743 | (hit asym-hobbit-body-parts)
744 | ; => {:name "chest", :size 10}
745 |
746 | (hit asym-hobbit-body-parts)
747 | ; => {:name "left-eye", :size 1}
748 |
749 |
750 | (def dec9 (dec-maker 9))
751 | (dec9 10)
752 | ; => 1
753 |
754 | (mapset inc [1 1 2 2])
755 | ; => #{2 3}
756 |
--------------------------------------------------------------------------------