草庐IT

读函数式编程思维笔记04_语言与范式_模式与重用

躺柒 2023-03-28 原文

1. 语言的分类

1.1. 静态类型

1.1.1. 要求我们事先指定变量和函数的类型

1.2. 动态类型

1.2.1. 允许推迟指定类型

1.3. 强类型

1.3.1. 变量“知道”自己的类型

1.3.1.1. 允许反射和对实例作类型测试,且一直保有自身的类型信息

1.4. 弱类型

1.4.1. 语言相对不了解变量所指向的内容

2. 多范式

2.1. 面向对象

2.2. 元编程

2.2.1. 可用于在语言及其核心库上添加额外的特性

2.3. 函数式

2.3.1. 函数式编程不喜欢把结构耦合在一起,它依靠零件之间的复合来组织抽象,以达到减少不确定因素的目的

2.3.2. 通过复合(composition)而不是耦合(coupling)来达到代码重用的目的

2.4. 命令式

3. 多范式语言的后顾之忧

3.1. 要求开发者更注重纪律,才能驾驭好大型的项目

3.1.1. 依靠工程纪律来保证所有的开发者都朝着同一个方向努力,是解决协调问题的一种途径

3.2. 单元测试为开发者精确地理解经元编程实现的复杂扩展提供了方便

3.3. 消费者驱动的契约(consumer-driven contract)

3.3.1. 由一项集成工作的实施方与各组件供应方共同商定的一组测试

4. 正交(orthogonality)

4.1. 数学上把两个互相垂直的向量称作正交的,也就是说这两个量不相关

4.2. 在计算机科学里,两个组件如果互相没有任何影响(或副作用),就可以称作是正交的

5. Groovy语言

5.1. 函数式编程和元编程是正交的

5.2. 使用元编程并不妨碍我们使用函数式编程的语言构造

5.2.1. 可以获得更充分地实践函数式的代码风格

5.2.2. 可以用来增强第三方的函数式库

5.2.2.1. 拥有了无缝添加新方法的能力

5.3. 利用元编程在数据类型之间建立映射

5.3.1. 开发者们一般只会考虑使用元编程来编写自己的代码,很少会想到用它来改造别人的代码

6. 复合型(composable)抽象

6.1. Unix shell

6.1.1. 在shell命令行里,各种互相独立、五花八门的行为可以串联在一起创造出新的事物

6.2. Rake构建语言,可以用在各种公私项目上(几乎不受项目本身技术选型的限制)

6.3. Gradle

6.3.1. Groovy语言的一种内部DSL,复合能力好于插件式设计的Maven

6.4. 不约而同地选择了DSL的形式

6.5. 倾向于使用一些细粒度的部件来组成整体,且这些部件都已准备好以特定方式相连接

6.6. 较少隐性的行为,较容易上手,但倾向于提供细粒度的构造单元,需经过一定过程才能发挥真正的实力

6.6.1. 设计得当的复合型系统应当在封装的模块内提供窄范围的、局部的上下文

7. 上下文型(contextual)抽象

7.1. Maven是典型的上下文型工具

7.2. 基于插件的架构可以作为上下文型抽象的代表

7.2.1. 提供了更多扶持性的“脚手架”设施,更完善的预设行为,以及“脚手架”上承载的上下文智能

7.3. Dietzler的Access定律

7.3.1. 所有Access项目最后都会失败,原因是,在用户想要的功能里,有80%实现起来既迅速又简单,还有10%能实现但较困难,而最后的10%是办不到的,因为不可能足够深地突破内建抽象去访问底层。可是,用户总想100%地满足需求。

7.3.1.1. 4GL语言最终丢掉了市场

8. 在函数式编程中传统设计模式的三种归宿

8.1. 模式已被吸收成为语言的一部分

8.2. 模式中描述的解决办法在函数式范式下依然成立,但实现细节有所变化

8.3. 由于在新的语言或范式下获得了原本没有的能力,产生了新的解决方案

8.3.1. 很多问题都可以用元编程干净利落地解决,但Java没有元编程能力可用

8.4. 设计模式的存在意义就是弥补语言功能上的弱点

9. 函数级别的重用

9.1. 复合(composition)

9.1.1. 通过参数来传递作为第一等语言成分的函数

9.2. 函数式语言的重用发生于较粗的粒度级别上,着眼于提取一些共通的运作机制,并参数化地调整其行为

9.2.1. 定义各类型“物件”之间“态射”(morphism)关系的数学分支——范畴论为基础,希望从代码中抽取另一种粗粒度的脉络而加以重用

9.2.2. 不追求复现结构之间经典的(耦合)关系

9.2.3. 建立在列表的概念,以及可以连同执行上下文一起传递的代码块的概念之上

9.3. 以模式为载体的重用是细粒度的:一种解答方案(如Flyweight模式)与另一种解答方案(如Memento模式)之间,是井水不犯河水的“正交”关系

9.3.1. 模式和问题之间这种狭窄的对应关系又限制了它的适用面

10. Command模式

10.1. 当语言拥有了闭包特性,就不需要了

11. Factory模式

11.1. 柯里化相当于产出函数的工厂

11.2. 柯里化可以把通用的函数改造成专用的函数

12. Strategy模式

12.1. 定义一个算法族,并将每一种算法都在相同的接口下封装起来,令同一族的算法能够互换使用

12.2. 好处是算法的变化不影响使用方,也不受使用方的影响

13. Singleton模式

13.1. 模式被运行时吸收掉的典型案例

14. Template Method模式

14.1. 一个方法里面定义好算法的骨架,但留下一部分未实现的步骤,强迫子类按照规定好的算法结构来补全缺失的步骤定义

14.2. 抽象方法的定义相当于一种特殊形式的文档,提醒子类将指定的方法纳入考虑

15. 被语言或运行时吸收掉的模式

16. Flyweight模式

16.1. 种在大量的细粒度对象引用之间共享数据的优化技巧。我们维护一个对象池,然后引用池中的对象来构成需要的视图

16.2. 非常简单的函数式实现

16.3. 记忆

16.4. 模式保留了原来的语义,但实现发生了变化

有关读函数式编程思维笔记04_语言与范式_模式与重用的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  5. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  6. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  7. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  8. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  9. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  10. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

随机推荐