写点什么

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

  • 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:376049
用户头像

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

关注

评论

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

Go语言入门16—锁

良猿

Go golang 后端 11月月更

js作用域、作用域链和它的一些优化

hellocoder2029

JavaScript

技术指南 | 如何集成Perforce版本控制系统Helix Core (P4V) 与软件生命周期管理工具Helix ALM

龙智—DevSecOps解决方案

版本控制 软件开发生命周期 版本管理 ALM

成为web前端工程师培训和自学选择

小谷哥

升级到React-Router-v6

xiaofeng

React

webpack配置优化,让你的构建速度飞起

Geek_02d948

webpack

用Vue.js开发企业管理后台,我做到了

博文视点Broadview

linux(centos)中部署docker(步骤超全,含带一些发展史和一些概念)

A-刘晨阳

Docker Linux 运维 11月月更

Vue虚拟dom是如何被创建的

yyds2026

Vue

Nodejs相关ORM框架分析

coder2028

node.js

JavaScript刷LeetCode拿offer-js版字典

Geek_07a724

JavaScript LeetCode

webpack热更新原理(面试大概率会问)

Geek_02d948

webpack

webpack模块化的原理

Geek_02d948

webpack

云栖盘点 | 一文 get 云原生峰会的最全发布

云布道师

云原生 云栖大会

HarmonyOS 3开启新一轮升级,3年前的nova 6也能更新!

Geek_2d6073

vue中的几个高级概念

yyds2026

Vue

javascript尾递归优化

hellocoder2029

JavaScript

开源代码安全 | 西门子为保护代码安全采取了什么措施?

龙智—DevSecOps解决方案

SCA SCA工具 开源代码安全

几个你必须知道的React错误实践

xiaofeng

React

​GOPS演讲 | 如何构建现代运营与支持体系,实现团队的高效协同

龙智—DevSecOps解决方案

gops ITSM ITSM解决方案 GOPS全球运维大会

干货|分析PostgreSql单表60w数据却占用55g空间

查拉图斯特拉说

数据库 postgresql db 11月月更

安装户外LED显示屏安装注意事项

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

docker如何在容器外执行容器内命令

A-刘晨阳

Docker Linux 运维 11月月更

Nodejs+Redis实现简易消息队列

coder2028

node.js

javascript 高级编程 之 Array 用法总结

hellocoder2029

JavaScript

在线研讨会报名 | 如何通过自动化测试实现降本、增效与提质

龙智—DevSecOps解决方案

自动化测试 研讨会

AR Engine光照估计能力,让虚拟物体在现实世界更具真实感

HarmonyOS SDK

AR HMS Core

让数据流动起来,RocketMQ Connect 技术架构解析

阿里巴巴云原生

阿里云 RocketMQ 云原生

vue3实战-完全掌握ref、reactive

yyds2026

Vue

Nodejs:ESModule和commonjs,傻傻分不清

coder2028

node.js

云栖盘点:2022 云网络产业干货分享

云布道师

云网络 云栖大会

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