函数式思维:为什么函数式编程越来越受关注

到目前为止,在本系列的每期文章中,我都说明了为什么理解函数式编程非常重要。但是,有些原因是在 多期文章中进行说明的,只有在综合思路的更大背景中,才可以完全了解这些原因。在本期文章中,我会探讨 函数式编程方兴未艾的所有原因,并综合前几期文章中的一些个人经验教训。

在计算机科学短短的发 展历史中,技术的主流有时会产生分支,包括实用分支和学术分支。20 世纪 90 年代的 4GL(第四代语言) 是一个实用分支,而函数式编程是来自学术界的一个示例。每隔一段时间,都会有一些分支加入主流,函数式 编程目前也是这种情况。函数式语言不仅在 JVM 上刚刚崭露头脚(其中两个最有趣的新语言是 Scala 和 Clojure),在 .NET 平台上也是才开始得到应用,在 .NET 平台上,F# 是头等公民。为什么所有平台都如此 欢迎函数式编程?答案是,随着时间的推移,随着运行时都要能够处理更多的繁忙工作,开发人员已经能够将 日常任务的更多控制权割让给它们。

割让控制权

在 20 世纪 80 年代初,在我上大学的时候, 我们使用一个被称为 Pecan Pascal 的开发环境。其独特的特性是,相同的 Pascal 代码可以在 Apple II 或 IBM PC 上运行。Pecan 工程师使用某个称为 “字节码” 的神秘东西实现了这一壮举。开发人员将 Pascal 代码编译为 “字节码”,它可以在每个平台本地编写的 “虚拟机” 上运行。这是一个可怕的体验!所生成 的代码慢得让人痛苦,甚至简单的类赋值也非常缓慢。当时的硬件还没有准备好迎接这个挑战。

在发 布 Pecan Pascal 之后的十年,Sun 发布了 Java,Java 使用了相同的架构,对于 20 世纪 90 年代中期的硬 件环境,运行该代码显得有些紧张,但最终取得了成功。Java 还增加了其他开发人员友好的特性,如自动垃 圾收集。使用过像 C++ 这样的语言之后,我再也不想在没有垃圾收集的语言中编写代码。我宁愿花将时间花 在更高层次上的抽象上,思考解决复杂业务问题的方法,也不愿意在内存管理等复杂的管道问题上浪费时间。

Java 缓解了我们与内存管理的交互;函数式编程语言使我们能够用高层次的抽象取代其他核心构建块 ,并更注重结果而不是步骤。

结果比步骤更重要

函数式编程的特点之一是存在强大的抽象,它 隐藏了许多日常操作的细节(比如迭代)。我在本系列文章中一直使用的一个示例是数字分类:确定某个数字 是 perfect、abundant 还是 deficient(完整的定义参见 第一期文章)。清单 1 中显示的 Java 实现可以 解决这个问题:

清单 1. 自带缓存总数的 Java 数字分类器

import static 

java.lang.Math.sqrt;

public class ImpNumberClassifier {
    private Set<Integer> _factors;
    private int _number;
    private int _sum;

    public ImpNumberClassifier(int number) {
        _number = number;
        _factors = new HashSet<Integer>();
        _factors.add(1);
        _factors.add(_number);
        _sum = 0;
    }

    private boolean isFactor(int factor) {
        return _number % factor == 0;
    }

    private void calculateFactors() {
        for (int i = 1; i <= sqrt(_number) + 1; i++)
            if (isFactor(i))
                addFactor(i);
    }

    private void addFactor(int factor) {
        _factors.add(factor);
        _factors.add(_number / factor);
    }

    private void sumFactors() {
        calculateFactors();
        for (int i : _factors)
            _sum += i;
    }

    private int getSum() {
        if (_sum == 0)
            sumFactors();
        return _sum;
    }

    public boolean isPerfect() {
        return getSum() - _number == _number;
    }

    public boolean isAbundant() {
        return getSum() - _number > _number;
    }

    public boolean isDeficient() {
        return getSum() - _number < _number;
    }
}

清单 1 中的代码是典型的 Java 代码,它使用迭代来确定和汇总系数。在使用函数式编程语言时 ,开发人员很少关心细节(比如迭代,由 calculateFactors() 使用)和转换(比如汇总一个列表,该列表由 sumFactors() 使用),宁愿将这些细节留给高阶函数和粗粒度抽象。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索编程
, 函数
, 代码
, java 分支嵌套
, 迭代
, number
, 函数式编程
, pascal编程
, pascal 编程
, 函数式
分支
,以便于您获取更多的相关知识。

时间: 2024-08-24 05:10:42

函数式思维:为什么函数式编程越来越受关注的相关文章

函数式思维和函数式编程

作为一个对Hashell语言[1]彻头彻尾的新手,当第一次看到一个用这种语言编写的快速排序算法的优雅例子时,我立即对这种语言发生了浓厚的兴趣.下面就是这个例子: quicksort :: Ord a => [a] -> [a] quicksort [] = [] quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater) where lesser = filter (< p) xs greater = filte

函数式思维:大量转换:同义词掩盖了相似性

函数式编程语言实现代码重用的方法与面向对象的语言不同,这个主题我在 "第 2 部分" 中进行了分析.面向对象的 语言往往拥有众多可进行多种操作的数据结构,而函数式语言却只有极少数可进行多种操作的数据结构.面向对象的语言鼓 励您创建特定于类的方法,而您可以捕获一些重复出现的模式,以便以后重用.函数式语言鼓励您将常见转换应用于数据结 构,使用更高级的函数来定制特定实例的操作,从而帮助您实现重用. 相同的数据结构和操作出现在所有函数式语 言中(也出现在支持 Java 中的函数式编程的众多框架

Java函数式思维: 函数设计模式

尽管 Java 不支持这些技术,下一代 JVM 语言均支持这些技术,但其具体实现细则有所不同.在本文中,Neal Ford 将探讨 Groovy.http://www.aliyun.com/zixun/aggregation/16945.html">Scala 和 Clojure 如何通过以 Java 无法支持的方式来实现函数式扩展,从而实现解释器设计模式的目的. 在本期 函数式思维 的文章中,我将继续研究 Gang of Four (GoF) 设计模式(参阅 参考资料)的函数式替代解决方

最近4K电视越来越受关注

摘要: 最近4K电视越来越受关注,就像当初1080p和3D刚出来时一样,厂商在不遗余力的推广,自然也会有人唱衰.唱衰的理由无外乎4K 片源匮乏.4K电视买来只能当 普通电视 看之类.如果基于旧 最近4K电视越来越受关注,就像当初1080p和3D刚出来时一样,厂商在不遗余力的推广,自然也会有人唱衰.唱衰的理由无外乎"4K 片源匮乏"."4K电视买来只能当 普通电视 看"之类.如果基于旧的产品和旧的技术,用旧的眼光来看,这种说法是有一定道理的:但时代是在前进的,随着新技

函数式思维: 转换和优化各种语言的更多功能比较

函数式编程起源于数学和计算机科学,这两种科学对术语都各执一词.语言和框架设计师们开发了他们最喜欢的命名法 ,结果发现基础范式已经有名称了.由于术语存在不一致性而使得了解函数式编程范式变得不容易. 在 "大量转换 " 中,我提出了对质数进行分类的问题,并且跨各种函数式语言就 JVM 和两种函数式 Java 框架实现了一种解决方案.本 期文章继续探讨上一期的主题,通过两种方式优化了上一期的算法,展示了各种语言中的后续更改.本期文章和上一期文章 同样阐述了各种工具和语言中术语与特性可用性之间

大数据安全分析越来越受关注

近日,在计世资讯进行的一次关于大数据的调查中,结果显示,越来越多的用户对基于大数据的安全分析解决方案的需求逐渐迫切.

[译]函数式响应编程入门指南

本文讲的是[译]函数式响应编程入门指南, 原文地址:An Introduction to Functional Reactive Programming 原文作者:Daniel Lew 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:龙骑将杨影枫 校对者:jasonxia23.Tobias Lee 函数式响应编程入门指南 今年,我做了一场有关函数式响应编程(functional reactive programming,简称 FRP)的演讲,演讲的内容

JavaScript的函数式编程,你了解吗?

探索函数式编程,通过它让你的程序更具有可读性和易于调试 当 Brendan Eich 在 1995 年创造 JavaScript 时,他原本打算将 Scheme 移植到浏览器里 .Scheme 作为 Lisp 的方言,是一种函数式编程语言.而当 Eich 被告知新的语言应该是一种可以与 Java 相比的脚本语言后,他最终确立了一种拥有 C 风格语法的语言(也和 Java 一样),但将函数视作一等公民.而 Java 直到版本 8 才从技术上将函数视为一等公民,虽然你可以用匿名类来模拟它.这个特性允

函数式接口、默认方法、纯函数、函数的副作用、高阶函数、可变的和不可变的、函数式编程和 Lambda 表达式 - 响应式编程 [Android RxJava2](这到底是什么)第三部分

本文讲的是函数式接口.默认方法.纯函数.函数的副作用.高阶函数.可变的和不可变的.函数式编程和 Lambda 表达式 - 响应式编程 [Android RxJava2](这到底是什么)第三部分, 太棒了,我们又来到新的一天.这一次,我们要学一些新的东西让今天变得有意思起来. 大家好,希望你们都过得不错.这是我们的 RxJava2 Android 系列的第三篇文章. 第一部分 第二部分 在这篇文章中,我们将讨论函数式的接口,函数式编程,Lambda 表达式以及与 Java 8 的相关的其它内容.这