1.看法
1.1.抽象化暗藏了繁复的技术细节,只是有时会与及重要的考虑因素一起暗藏掉
1.2.认知掌控的算例总有一天要比日常生活使用的算例更进一步
2.表达式式观念的益处
2.1.将低阶技术细节(如废弃物搜集)的控股权转交给运转时,从而消解了一批或许会发生的流程严重错误
2.2.表达式式词汇的简约句法和灵巧相互配合,才使递回成为单纯可取的标识符宠信快捷键之一
2.3.运转时有能力在牵涉工作效率的问题Jaunpur他们做决定
2.4.从频密出现的情景中铲除掉恼人的实现技术细节
3.旋量群(closure)
3.1.一类特定的表达式,在聚合的时候,会把提及的表达式全部库金标识符块的作用域里,半封闭、包围住(故称旋量群)
3.1.1.旋量群作为一类对犯罪行为的可视化方式,让他们把标识符和语句同时PCB在单个结构,也就是旋量群这类里头,像现代计算机流程一样可以传达到其他边线,然后在正确的时间和处所完成继续执行
3.2.旋量群的每一示例都能保持自己的这份表达式值域,包括专有表达式也是如此
3.2.1.标识符块示例从它被建立的一刹那,就所持其返回值内一切表达方式的半封闭复本
3.3.在缺少旋量群优点的旧版本Java网络平台上,Functional Java利用非官方外部Canillac仿效“真正的”旋量群的这类犯罪行为,但词汇的发展缓慢导致这种仿效是不全盘的
3.4.当作一类异地继续执行的机制,用来传达待继续执行的变换标识符
3.5.是推迟继续执行原则的绝佳样板
3.6.抓住语句,而非状态
3.6.1.“让运转时去管理状态”
4.柯里化(currying)和表达式的部分施用(partial application)
4.1.向一部分参数代入一个或多个默认值的办法来实现的
4.1.1.这部分参数被称为“固定参数”
4.2.柯里化
4.2.1.从一个多参数表达式变成一连串单参数表达式的变换4.2.2.结果是返回链条中的下一个表达式
4.3.部分施用
4.3.1.通过提前代入一部分参数值,使一个多参数表达式得以省略部分参数,从而转化为一个参数数目较少的表达式4.3.2.把参数的值域绑定到用户在操作中提供的具体值上,因而产生一个“元数”(参数的数目)较少的表达式
4.4. Groovy
4.4.1. curry()表达式实现柯里化
4.5. Clojure
4.5.1.(partial f a1 a2…)表达式4.5.2.没有将柯里化实现成一类词汇优点,相关的情景交由部分施用去处理
4.6. Scala
4.6.1.柯里化4.6.2.部分施用表达式4.6.3.偏表达式4.6.3.1. PartialFunction trait是为了密切相互配合词汇中的模式匹配优点4.6.3.2. trait并不聚合部分施用函数。它的真正用途是描述只对定义域中一部分值域或类型有意义的表达式4.6.3.3. Case语句是偏表达式的一类用法4.6.3.4.偏表达式的参数被限定了值域范围4.6.3.5.可以把偏表达式用在任何类型上,包括Any
4.7.大多数表达式式词汇都具备柯里化和部分施用这两种优点,但实现上各有各的做法
4.8.用途
4.8.1.表达式工厂4.8.1.1.工厂方法的场合,正适合柯里化(以及部分施用)表现它的才干4.8.2. Template Method(模板方法)模式4.8.2.1.在固定的算法框架外部安排一些抽象化方法,为后续的具体实现保留一部分灵巧性4.8.3.隐含参数
5.递回
5.1.以一类自相似的方式来重复表达方式的过程
5.2.对一个不断变短的列表反复地做同一件事,把递回用在这样的场合,写出来的标识符就容易认知
5.3.递回操作往往受制网络平台而存在一些固有的技术限制,因此这种技法绝非万灵药
5.4.但对于长度不大的列表来说,递回操作是安全的
5.5.词汇在管理返回值,它从递回栈里搜集每次方法调用的返回结果,构造出最终的返回值
5.6.利用递回,把状态的管理责任推给运转时
6.记忆(memoization)
6.1.用更多的内存(他们一般不缺内存)去换取长期来说更高的工作效率
6.1.1.缓存可以提高性能,但缓存有代价:它提高了标识符的非本质复杂性和维护负担6.1.2.负责编写缓存标识符的开发者不仅要顾及标识符的正确性,连它的继续执行环境也要考虑在内6.1.3.标识符中的状态,开发者不仅要费心照应它,还要条分缕析它的一切明暗牵连
6.2.记忆的内容应该是值不可变的
6.3.保证所有被记忆的表达式
6.3.1.没有副作用6.3.2.不依赖任何外部信息
6.4.只有纯(pure)表达式才可以适用缓存技术
6.4.1.纯表达式是没有副作用的表达式6.4.1.1.它不提及其他值可变的类字段6.4.1.2.除返回值之外不设置其他的表达式6.4.1.3.其结果完全由输入参数决定6.4.2.只有在表达式对同样一组参数总是返回相同结果的前提下,他们才可以放心地使用缓存起来的结果
6.5.缓存是很常见的一类需求,同时也是制造隐晦严重错误的源头
6.6.两种情况
6.6.1.类外部缓存6.6.1.1.类中的缓存就代表类有了状态,所有与缓存打交道的方法都不可以是静态的,于是产生了更多的连锁效应6.6.2.外部调用
6.7.两种实现方式
6.7.1.手工进行状态管理6.7.2.采用记忆机制
6.8.在命令式的思路下,开发者是标识符的主人(以及一切责任的承担者)
6.9.他们写出来的缓存绝不可能比词汇设计者产生的更高效,因为词汇设计者可以无视他们给词汇定的规矩:开发者无法触碰的底层设施,不过是词汇设计者手中的玩物,他们拥有的优化方式和空间是“凡人”无法企及的
6.9.1.上帝视角
6.10. Groovy
6.10.1.先将要记忆的表达式定义成旋量群,然后对该旋量群继续执行memoize()方法来获得一个新表达式,以后他们调用这个新表达式的时候,其结果就会被缓存起来6.10.2. memoizeAtMost(1000)
6.11. Clojure
6.11.1.(memoize )
6.12. Scala
6.12.1.没有直接提供记忆机制,但它为集合提供的getOrElseUpdate()方法已经替他们承担了大部分的实现工作
6.13. Java 8
6.13.1.没有直接提供记忆优点,但只要借助它新增的lambda优点,就可以轻松地实现记忆功能
7.缓求值(lazy evaluation)
7.1.尽可能地推迟求解表达式
7.1.1.昂贵的运算只有到了绝对必要的时候才继续执行7.1.2.可以建立无限大的集合,只要一直接到请求,就一直送出元素7.1.3.按缓求值的方式来使用映射、筛选等表达式式概念,可以产生更高效的标识符7.1.4.减少占用的存储空间。假如能够用推导的方法得到后续的值,那就不必预先存储完整的列表了——这是牺牲速度来换取存储空间的做法
7.2.非严格求值(non-strict)的(也叫缓求值,lazy)
7.2.1.常用的非严格求值词汇有Haskell
7.3. Totally Lazy框架(Java)
7.4. Groovy
7.4.1.缓求值列表是表达式式词汇普遍具备的优点7.4.1.1. LazyList7.4.2.暂缓初始化昂贵的资源,除非到了绝对必要的时候7.4.3.可以用来构建无限序列,也就是没有上边界的列表7.4.4.缓求值列表特别适用于资源的生产成本较高的情况
7.5. Clojure
7.5.1.计算机流程都是默认缓求值的
7.6. Scala
7.6.1.没有把一切都默认安排成缓求值的,而是在集合之上另外提供了一层缓求值的视图
7.7.缓求值的字段初始化
7.7.1. Scala7.7.1.1. val声明前面加上“lazy”字样7.7.1.1.1.令字段从严格求值变成按需要求值7.7.2. Groovy7.7.2.1.抽象化句法树(Abstract Syntax Tree,AST)7.7.2.1.1.@Lazy标注
8.元表达式技法
8.1.操纵的对象是表达式这类,而非表达式的结果
8.2.柯里化