函数式编程

函数式编程很难,这正是你要学的原因

廉价感情. 提交于 2019-11-29 13:25:54
很奇怪不是,很少有人每天都使用函数式 编程语言 。 如果你用Scala,Haskell,Erlang,F#或某个Lisp方言来编程,很可能没有公司会花钱聘你。这个行业里的绝大部分人都是使用像 Python,Ruby,Java或C#等面向对象的编程语言——它们用起来很顺手。不错,你也许会偶然用到一两个“函数式语言特征”,例如 “block”,但人们不会去做函数式编程。 然而,很多年来,我们一直被教导说函数式编程语言很好很棒。我仍然记得当我第一次阅读 ESR的著名的关于学习Lisp语言的论文 时的困惑。也许大多数的人对 Paul Graham 的《Beating The Averages》 这篇文章更加熟悉: 使用Lisp开发使我们的开发周期迭代的如此之快,以至于有时当竞争对手在新闻发布会上推出他们的新功能一两天后,我们就能复制出同样的功能。当报道产品发布的新闻记者打电话给我们时,我们的产品已经拥有了同样的功能特征。 那些皈依函数式编程的人中,一直常见的考虑是:学习这种新的、函数式的语言“对你有好处”;就像是某些人建议说每天30分钟的健身房活动会“让你的 身体健康”一样。但这也同时暗示了这样做的难度和需要的付出。Lisp语言跟Haskell、Ocaml和Scala语言不同,被认为是出了名的难学,可 以说是臭名昭著。文雅的人说这是Lisp语言的“深度&广度”的体现。不文雅的人说这是“意淫

JDK 8 函数式编程入门(转载)

蓝咒 提交于 2019-11-29 12:17:56
本人博客园链接 https://www.cnblogs.com/zongmin/articles/11345157.html 1. 概述 1.1 函数式编程简介 我们最常用的面向对象编程(Java)属于 命令式编程 (Imperative Programming)这种编程范式。常见的编程范式还有 逻辑式编程 (Logic Programming), 函数式编程 (Functional Programming)。 函数式编程作为一种编程范式,在科学领域,是一种编写计算机程序数据结构和元素的方式,它把计算过程当做是数学函数的求值,而避免更改状态和可变数据。 函数式编程并非近几年的新技术或新思维,距离它诞生已有大概50多年的时间了。它一直不是主流的编程思维,但在众多的所谓顶级编程高手的科学工作者间,函数式编程是十分盛行的。 什么是函数式编程?简单的回答:一切都是数学函数。函数式编程语言里也可以有对象,但通常这些对象都是恒定不变的 —— 要么是函数参数,要什么是函数返回值。函数式编程语言里没有 for/next 循环,因为这些逻辑意味着有状态的改变。相替代的是,这种循环逻辑在函数式编程语言里是通过递归、把函数当成参数传递的方式实现的。 举个例子: a = a + 1 ; 这段代码在普通成员看来并没有什么问题,但在数学家看来确实不成立的,因为它意味着变量值得改变。 1.2 Lambda

MapReduce分布编程模型之函数式编程范式

拟墨画扇 提交于 2019-11-29 09:27:56
导读: 计算机科学是算法与算法变换的科学,算法是计算机科学的基石。 任何一个计算问题的分析与建模,几乎都可以归为算法问题。 MapReduce算法模型是由Google公司针对大规模群组中的海量数据处理而提出的分布编程模型,主要应用于大规模数据集{大于1TB}的分布并行运算。 在MapReduce模型中的Map{映射}和Reduce{化简}创意来自函数型编程语言,同是也继承了向量型编程语言的特性。 MapReduce模型能够使程序员在不了解分布式并行编程的情况下,将自己书写的程序在分布式系统上运行。MapReduce模型主要实现了映射与化简两个核心功能,分别由Map和Reduce完成,这两个函数也是函数型语言中常用的函数,由用户负责实现。 Map函数应用于集合中的所有成员,然后返回一个基于这个处理的结果集。而Reduce函数是从两个或更多个Map结果中,通过多个线程、进程或者独立系统并行执行处理的结果进行分类和归纳。 一个Map函数用来把对映象成一组新的键值对,Reduce函数用来对同一个键的值进行合并。 下面给大家着重介绍一下函数式编程范式,函数式编程是一种编程范式,在这种编程范式中,更多地使用了函数运算。 函数型语言与函数式编程 函数型语言是一种典型的程序设计语言。函数型语言的特点是把问题求解过程表示成块结构,对调用块的调用者来说,每个块都有输入数据和经过加工处理后的输出数据

廖雪峰Java16函数式编程-2Stream-7其他操作

随声附和 提交于 2019-11-29 07:56:30
1. 排序 Stream<T> sorted(); //按元素默认大小排序(必须实现Comparable接口) Stream<T> sorted(Comparator<? super T> cp); //按指定Comparator比较的结果排序 public static void main(String[] args){ Stream<String> s = Stream.of("hello","JAVA","python","RUBY","PHP"); s.sorted().forEach(str-> System.out.print(str+"\t")); System.out.println(); Stream<Integer> s1 = Stream.of(1,9,5,3,7); s1.sorted(Comparator.reverseOrder()).forEach(str-> System.out.print(str+"\t")); } 2.去除重复元素 Stream<T> distinct(); //返回去除重复元素的Stream Stream<String> s = Stream.of("hello","JAVA","hello","RUBY","JAVA"); s.distinct().forEach(str-> System.out.print(str+"\t

初识函数式编程的一点漫谈

亡梦爱人 提交于 2019-11-29 03:38:49
昨天看一些函数式编程、Haskell、Scala的书和文章,到半夜还莫名其妙: 「好像除了函数是一等公民外,没发现什么好处呀……很多人说学函数式能改变思维方式,又不肯说这改变具体是什么。」 「javascript里函数也是一等公民,用着也很爽,函数式比之,还有什么好处?」 很不满意地躺下,用手机继续google之,突然发现 一篇文章 ,醍醐灌顶,立刻爬起来仔细阅读,摸黑记录(兴奋得没工夫开灯),发微博致谢。 「函数式编程的关键是不定义变量」,这至为重要的一点,之前看的书和文章竟然都没强调——说是说过了,却没指出这是重点。 就连忙现想个功能,尝试不定义变量地实现它,发现当有了这个勒定,函数语言自然会被「倒逼」着具备lambda等特性,因为我发现只用老java,不用java8语法,很难在「不定义变量」的约束下实现之,不知道是不是不可能实现,我的数学能力不足以证明之。 今天早上起来,赶快翻开《写给大忙人看的java8》,使用java8语法完成程序。完成后重构一下,发现果然不出所料,最终代码的结构,是函数复函数,函数套函数,主函数是超级大函数,而这些函数的分隔和关联,着眼点就在其参数和返回值上。 数学里,函数的意义是定义域到值域的映射,代码里写的函数,其意义是参数集合到返回值集合的映射,为了达成这从集合到集合的映射,在不许定义变量的情况下

利用java8新特性实现类似javascript callback特性

断了今生、忘了曾经 提交于 2019-11-29 03:38:39
Java8的新特性之一,就是首次引入了函数式编程Lambda表达式,按oracle的说法,是为了引导java向函数式编程的方向发展。 在JDK1.8中,多了一个包,java.util.function,这里主要用到了这个包下面的两个接口: Consumer<T> //Represents an operation that accepts a single input argument and returns no result. Function<T,R> //Represents a function that accepts one argument and produces a result. 要解释清楚这个问题,首先得从lambda表达式说起 (x,y)->doSomethingWith(x,y); 这句话就是一个lambda表达式的例子;"->"是Java8新定义的一个操作符,操作符左边代表lambda表达式接收的参数,这里它接收了两个参数,x和y;表达式右边是函数操作,也就是对这两个变量执行某种操作。如x+y,x*y等。 简单的解释了一下java8的lambda表达式,接下来进入正题: 在java8中,function包下面的所有接口都描述了一种预定义的lambda表达式类型,换句话说,就是可以通过声名接口类型的变量为lambda赋值,从而达到函数参数化的目的

函数式响应式编程 - Functional Reactive Programming

拈花ヽ惹草 提交于 2019-11-29 00:59:03
我们略过概念,直接看函数式响应式编程解决了什么问题。 故事从下面这个例子展开: 两个密码输入框,一个提交按钮。 密码、确认密码都填写并一致,允许提交;不一致提示错误。 HTML 如下: <input id="pwd" placeholder="输入密码" type="password" /><br /> <input id="confirmPwd" placeholder="再次确认" type="password" /> <label id="errorLabel"></label><br /> <button id="submitBtn" disabled>提交</button> 常规做法 初始版 const validate = () => { const match = pwd.value === confirmPwd.value; const canSubmit = pwd.value && match; errorLabel.innerText = match ? "" : "密码不一致"; if (canSubmit) { submitBtn.removeAttribute("disabled"); } else { submitBtn.setAttribute("disabled", true); } }; pwd.addEventListener("input",

Scala 函数式编程

随声附和 提交于 2019-11-28 23:04:39
将函数赋值给变量 // Scala 中的函数是一等公民,可以独立定义,独立存在,而且可以直接将函数作为值赋值给变量 // Scala 的语法规定,将函数赋值给变量时,必须在函数后面加上空格和下划线 def sayHello(name: String) { println("Hello, " + name) } val sayHelloFunc = sayHello _ sayHelloFunc("leo") 匿名函数 // Scala 中,函数也可以不需要命名,此时函数被称为匿名函数。 // 可以直接定义函数之后,将函数赋值给某个变量;也可以将直接定义的匿名函数传入其他函数之中 // Scala 定义匿名函数的语法规则就是, ( 参数名 : 参数类型 ) => 函数体 // 这种匿名函数的语法必须深刻理解和掌握,在 spark 的中有大量这样的语法,如果没有掌握,是看不懂 spark 源码的 val sayHelloFunc = (name: String) => println("Hello, " + name) 高阶函数 // Scala 中,由于函数是一等公民,因此可以直接将某个函数传入其他函数,作为参数。这个功能是极其强大的,也是 Java 这种面向对象的编程语言所不具备的。 // 接收其他函数作为参数的函数,也被称作高阶函数( higher-order function

Scala 函数式编程

自古美人都是妖i 提交于 2019-11-28 23:04:19
将函数赋值给变量 // Scala 中的函数是一等公民,可以独立定义,独立存在,而且可以直接将函数作为值赋值给变量 // Scala 的语法规定,将函数赋值给变量时,必须在函数后面加上空格和下划线 def sayHello(name: String) { println("Hello, " + name) } val sayHelloFunc = sayHello _ sayHelloFunc("leo") 匿名函数 // Scala 中,函数也可以不需要命名,此时函数被称为匿名函数。 // 可以直接定义函数之后,将函数赋值给某个变量;也可以将直接定义的匿名函数传入其他函数之中 // Scala 定义匿名函数的语法规则就是, ( 参数名 : 参数类型 ) => 函数体 // 这种匿名函数的语法必须深刻理解和掌握,在 spark 的中有大量这样的语法,如果没有掌握,是看不懂 spark 源码的 val sayHelloFunc = (name: String) => println("Hello, " + name) 高阶函数 // Scala 中,由于函数是一等公民,因此可以直接将某个函数传入其他函数,作为参数。这个功能是极其强大的,也是 Java 这种面向对象的编程语言所不具备的。 // 接收其他函数作为参数的函数,也被称作高阶函数( higher-order function

DSL与函数式编程

一个人想着一个人 提交于 2019-11-28 19:33:49
一直看到这个英文缩写,但是不知道它具体是啥东西,google几次都讲的非程序层面的意思,找到一篇还不错的介绍文章,转载过来... 出自: http://mzhou.me/?p=95219 什么是DSL? DSL即领域编程语言,它是用于解决特定领域问题的语言。与GPPL(通用目的编程语言)相比,DSL针对的目标是特定的领域。其实DSL并不是什么高深的东西,SQL、正则表达式、CSS等等都是一种DSL。对于前端工程师来说jQuery就是一种DSL。 DSL可以分为两种:内部DSL、外部DSL。外部DSL是自我包含的语言,它们有自己特定语法、解析器和词法分析器等等,它往往是一种小型的编程语言,甚至不会像GPPL那样需要源文件。与之相对的则是内部DSL。内部DSL其实更像是种别称,它代表一类特别API及使用模式[1]。jQuery就是一种内部DSL,而CSS则是一种外部DSL。 $(".selector").text("display text") .append("<div>children</div>") .show(); 使用DSL的好处就是:我们可以更关注做什么(What)而不是怎么做(How)! jQuery是一门用于解决多种浏览器上javascript 执行兼容性的DSL,它提供了一组API用于Web前端开发的通用功能:DOM、AJAX、Event等等。众所周知