第1章 保持初学者的心态 1
1.1函数式思维 2
1.1.1以值为导向 2
1.1.2从递归的角度考虑问题 4
1.1.3高阶函数 7
1.1.4拥抱惰性 11
1.1.5当变动成为必需时 12
1.1.6 Nil双关 15
1.1.7函数式Web 16
1.2改进面向对象编程 17
1.2.1利用defmulti实现多态调度 18
1.2.2使用deftype和defrecord定义类型 20
1.2.3协议 21
1.2.4 reify 22
1.3可持久化数据结构 23
1.4塑造语言 27
1.5小结 29
第2章Clojure的快速反馈循环 31
2.1 REPL驱动开发 31
2.1.1 REPL在Leiningen中的基本操作 32
2.1.2通过nREPL实现远程REPL 34
2.1.3 REPL在实际程序中的应用 36
2.1.4 REPL与编辑器的连接 40
2.2代码重载 41
2.2.1从REPL重载代码 41
2.2.2自动重载代码 45
2.2.3编写可重载的代码 52
2.3小结 54
第3章Web服务 55
3.1项目总览 55
3.2构成Web服务的元素 57
3.2.1库,而非框架 57
3.2.2 HTTP 57
3.2.3路由 66
3.2.4 JSON端点 73
3.3示例服务 78
3.3.1创建项目 78
3.3.2其他命名空间 78
3.3.3默认中间件 81
3.3.4存储协议 82
3.3.5处理函数 87
3.3.6中间件 92
3.3.7路由 94
3.4部署 99
3.4.1使用Leiningen 99
3.4.2编译Uberj ar或Uberwar 100
3.4.3托管 101
3.5小结 102
第4章 测试 105
4.1 clojure.test测试基础 106
4.1.1 with-test宏 106
4.1.2 deftest库 107
4.1.3 are 108
4.1.4使用基境 109
4.2测试策略 110
4.2.1数据库测试 110
4.2.2 Ring处理函数测试 112
4.2.3采用with-redefs实现模拟/存根 115
4.2.4重新定义动态var 117
4.2.5采用vcr-clj实现录制和重放 118
4.3度量代码质量 119
4.3.1采用cloverage度量代码覆盖率 120
4.3.2采用kibit和bikeshed进行静态分析 122
4.3.3将依赖置于掌控之中 124
4.4其他测试框架 127
4.4.1 expectations 127
4.4.2 speclj 128
4.4.3 Cucumber 129
4.4.4 kerodon 136
4.5小结 137
第5章 采用ClojureScript开发反应式网页 139
5.1 ClojureScript与众不同 140
5.2 ClojureScript初探 142
5.2.1创建新的ClojureScript项目 142
5.2.2采用Figwheel实现快速反馈 143
5.2.3创建组件 144
5.2.4数据建模 145
5.2.5响应事件并处理状态变更 147
5.2.6理解错误和警告信息 148
5.2.7命名空间布局 151
5.2.8样式 152
5.2.9表单输入与表单处理 153
5.2.10导航和路由 156
5.2.11 HTTP调用:与服务器进行通信 157
5.2.12拖放 160
5.2.13发布 160
5.3 Reagent进阶 162
5.3.1形式1:返回向量的函数 162
5.3.2形式2:返回组件的函数 163
5.3.3形式3:返回类的函数 164
5.3.4序列与键 165
5.3.5自定义标记 167
5.3.6反应 168
5.3.7对样式的注释 170
5.4 Devcards的测试组件 170
5.5与JavaScript的互操作性 174
5.6一种语言,一种惯用法,多个平台 176
5.7 Closure编译器和Closure库浅析 176
5.8采用DataScript处理建模状态 177
5.9在浏览器中使用core.async 178
5.10小结 179
第6章Datomic数据库 181
6.1 Datomic基础 182
6.1.1为何选择Datomic? 182
6.1.2 Datomic数据模型 184
6.1.3查询 187
6.1.4事务 192
6.1.5索引:将数据切实绑定在一起 195
6.1.6 Datomic的独特架构 198
6.2对应用数据建模 200
6.2.1任务跟踪器应用的示例模式 200
6.2.2实体id和分区 209
6.3 Datomic的Clojure API 209
6.3.1基本设置 209
6.3.2在REPL中小试牛刀 213
6.4采用Datomic构建应用 219
6.4.1用户函数 219
6.4.2账户函数 222
6.4.3任务函数 223
6.4.4部署 227
6.4.5局限性 227
6.5小结 228
第7章 性能 231
7.1何为性能? 233
7.2性能优化的前提:选择正确的数据结构 233
7.3基准测试 235
7.3.1测定低速模块的时间 235
7.3.2采用Criterium测定高速模块的时间 237
7.3.3采用测试选择器进行性能测试 239
7.4并行 239
7.5记忆化 240
7.6内联 241
7.7利用瞬态机制安全地处理变动 243
7.8性能分析 243
7.9利用类型提示避免反射 244
7.10 Java标志 246
7.11数值计算 246
7.12小结 247