写点什么

函数式编程为何越来越受到重视

  • 2013-07-19
  • 本文字数:1659 字

    阅读完需:约 5 分钟

函数式编程受到越来越多的关注,软件架构师 Neal Ford分析了其中的原因。

Neal Ford 首先强调,函数式编程的特点之一是存在强大的抽象,它隐藏了许多日常操作的细节(比如迭代)。用抽象来处理迭代等任务,使得需要维护的代码变得更少,因此可能出现错误的地方也就更少。

Java 开发人员习惯于框架 级别的重用;在面向对象的语言中进行重用所需的必要构件需要非常大的工作量,他们通常会将精力留给更大的问题。函数式语言在更细化的级别提供重用,在列表和映射等基本数据结构之上通过高阶函数提供定制,从而实现重用。

在面向对象的命令式编程语言中,重用的单元是类以及与这些类进行通信的消息,这些信息是在类图中捕获的。在 OOP 的世界中,鼓励开发人员创建独特的数据结构,以方法的形式附加特定的操作。

函数式编程语言尝试采用不同的方式来实现重用。它们更喜欢一些关键的数据结构(如列表、集和映射),并且在这些数据结构上采用高度优化的操作。传递数据结构和高阶函数,以便 “插入” 这种机制,针对某一特定用途对其进行定制。

函数级的封装支持在比构建自定义类结构更细的基础级别上进行重用。此方法的优势之一已经体现在 Clojure 中。最近,库中的一些巧妙创新重写了 map 函数,使它可以自动并行化,这意味着所有映射操作都可以受益于没有开发人员干预的性能提升。

Neal Ford 举了一个解析 XML 的例子。大量的框架可用于在 Java 中完成这个任务,每个框架都有自定义的数据结构和方法语义(例如,SAX 与 DOM)。

Clojure 将 XML 解析为一个标准的 Map 结构,而不是强迫您使用自定义的数据结构。因为 Clojure 中包含大量与映射配合使用的工具,如果使用内置的列表理解函数 for,那么执行 XPath 样式的查询就会很简单。

最初,Clojure 中令人生畏的细节之一是:与映射和其他核心数据结构进行交互的方法似乎有无限多种。然而,它反映了这样一个事实:在 Clojure 中,大多数内容都尝试解决这些核心的、优化的数据结构。它没有将解析的 XML 困在一个独特的框架中,相反,它试图将其转换为一个已存在相关工具的现有结构。

其次,函数式编程提供了新的工具类型,以优雅的方式解决棘手的问题。例如,Java 开发人员不习惯尽能延迟生成其值的惰性 数据结构。而未来的函数式语言将对这种高级特性提供支持,一些框架将此功能加装到 Java 中。

第三点是让语言迁就问题,大多数开发人员都将他们的工作误解为接受一个复杂的业务问题,将它转换成 Java 等语言。

他们的这种误解是因为 Java 并不是一种特别灵活的语言,它迫使您让自己的想法适应于已经存在的刚性结构。但是,当开发人员使用可塑语言时,他们看到了让语言迁就问题,而不是让问题迁就语言的机会。像 Ruby(它为领域特定语言 (DSL) 提供了比主流更友好的支持)等语言证明了这种潜在可能。现代函数式语言甚至走得更远。Scala 旨在协调内部 DSL 的托管,并且所有 Lisp(包括 Clojure)都可以提供无与伦比的灵活性,使开发人员能够让语言适应问题。

最后一点是与语言的趋势相一致,函数式编程的目标之一是最大程度地减少可变状态。像垃圾收集一样,现在缓存也可以降级用于语言。

由于运行时获得了更多的能力并且有多余的开销,开发人员可以将繁忙的工作割让给语言,将我们解放出来,去思考更重要的问题。Groovy 中的备忘功能就是众多示例中的一个;因为基础运行时允许这样做,所有现代语言都添加了函数式构造,包括 Totally Lazy 等框架。

微软的函数式编程语言 F#最近随 Visual Studio 2013 预览版发布了 3.1 版本。3.1 版的主要新增语言特性:

  • 命名的联合类型字段——现在可以为每个联合类型中的联合字段命名
  • 数组切片扩展——之前的数组切片只能用于同等维度的数组,现在这不是必须的了
  • 为 LINQ 风格的方法增强了类型推断——改进了 F#中使用函数作为参数的重载方法的类型推断
  • 支持第一个参数为类型参数的 C#风格的扩展方法——3.1 支持使用扩展方法(this 关键字),比如:static member M(this T input, T other)
  • 在特性和字面量表达式中对常量进行组合——比如,可以使用“+”来连接字符串,或对枚举标记进行按位 OR 操作(|||)
2013-07-19 10:376530
用户头像

发布了 501 篇内容, 共 283.9 次阅读, 收获喜欢 64 次。

关注

评论

发布
暂无评论
发现更多内容

滴滴夜莺社区文章有奖征集

滴滴云

最佳实践 奖品 案例分享 滴滴夜莺

如何基于Spring Aware和InitializingBean接口实现策略模式

技术进阶之路

Java spring 5 Java设计模式

中国为什么加快推进数字人民币

CECBC

数字货币

看完字节大佬的算法刷题宝典,我直接手撕了500道算法算法题

程序员 面试 算法

最简单的map,filter,forEach,every,some的使用教学

coolFish(呔呆)

方法 Vue 大前端 数组 js

架构训练营大作业(一)

一期一会

2021最新「阿里」Java高级工程师面试高频题:JVM+Redis+并发+算法+框架

比伯

Java 编程 架构 面试 计算机

用最少人力玩转万亿级数据,我用的就是MongoDB

dbaplus社群

科技,亲吻这个特别的春节

脑极体

PanoVideoCall 的 Electron Demo 开源了

拍乐云Pano

html Mac windows Electron js

webpack | 进阶用法2:代码分割和动态引入的实现方式

梁龙先森

大前端 webpack 28天写作 2月春节不断更

欢迎来到,2021摄像机竞技场

脑极体

如何基于Spring 事件驱动模型实现业务解耦

技术进阶之路

Java spring 架构

夕四今晚加班到2点30,而王二还不打算走《打工人的那些事》

谙忆

硬核!八张图搞懂 Flink 端到端精准一次处理语义 Exactly-once(深入原理,建议收藏)

五分钟学大数据

大数据 flink

Varchar竟然会自动存储成lob类型?

dbaplus社群

产品经理训练营课后作业-第三周-产品思维和产品意识

.nil?

产品经理训练营

「抖音同款播放器」上市:有效解决卡顿、黑屏和模糊

字节跳动技术团队

Java并发包源码学习系列:阻塞队列实现之SynchronousQueue源码解析

Java 编程

区块链在数字版权领域的应用发展报告(2020)

CECBC

版权保护

静默安装Oracle也没那么恐怖

MySQL从删库到跑路

oracle

分页方式,看这一篇就够了。

大伟

分页

京东支付SDK重构设计与实现

京东数科风险算法与技术

【LeetCode】子集问题debug模式查看数据变化

Albert

算法 LeetCode 2月春节不断更

驱动力读后感之一

张老蔫

28天写作

作业3

瑾瑾呀

Gradle Docker插件将SpringBoot应用程序打包为Docker镜像

wjchenge

Docker SpringBoot 2 Gradle

产品训练营第三次作业

Geek_79e983

区块链--另一场改变社会组织方式的工业革命

CECBC

区块链

精美的淘客项目完全开源啦,确定不来围观吗

Silently9527

Vue mybatis springboot uniapp

架构训练营大作业(二)

一期一会

函数式编程为何越来越受到重视_Java_崔康_InfoQ精选文章