关于函数式编程,读研或读博,去国外读研的条件哪所大学强

京 东 价:
[定价:¥]
PLUS会员专享价
支  持:
重  量:
搭配赠品:
服务支持:
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
Scala函数式编程
商品介绍加载中...
扫一扫,精彩好书免费看
  这本书绝不轻易放过每个知识点,全书包含有大量习题,要求你自己实现&Scala&标准库或者&Scalaz&中的既有功能。所以,当你读完本书,做完习题后,虽然你的应用开发能力并不会直接提升,但你会体会到构建函数式语言和框架时的难点和取舍,从而增进你的框架开发和语言设计的能力。  ——ThoughtWorks&Lead&Consultant&杨博  这本书所讲授的,正是基于&Scala&的函数式编程基础。基于&Scheme、Haskell&等老牌函数式语言的传统教材的问题在于,相关语言的语法和思维方式与读者现有的知识体系迥异,容易造成较为陡峭的入门门槛。此外,由于这些语言本身的实际应用机会不多,初学者也难以在实战中获得宝贵的直觉和经验。而在&Scala&的帮助下,这本书并不要求你抛开现有的思维方式另起炉灶,它所做的更像是为你现有的思维方式添砖加瓦,从而令你如虎添翼。  ——Spark&committer&from&Databricks&连城  尽管函数式编程在近十多年用得越来越多,但市面上介绍其高阶特性的书却并不多。这本书在这方面是个重要的补充,它不仅仅面向&Scala&程序员,同样面向用任何编程语言开发的程序员,只要你充满好奇心。  ——挖财网首席架构师&王宏江  “让你洞察计算的本质。”  ——Martin&Odersky,&Scala的作者  “Scala和Java8开发者的函数式编程指南!”  ——William&E.&Wheeler,&TekSystems  “本书向你展示了提升Scala技能的方法和理念,它已超过‘更好的Java’。”  ——Fernando&Dobladez,&Code54  “里面的练习有些挑战,很有趣,对你在真实世界中使用它很有益。”  ——Chris&Nauroth,&Hortonworks  “边干边学,而非只是阅读。”  ——Douglas&Alan、Eli和Edythe&L.&Broad,哈佛和麻省理工学院
京东商城向您保证所售商品均为正品行货,京东自营商品开具机打发票或电子发票。
凭质保证书及京东商城发票,可享受全国联保服务(奢侈品、钟表除外;奢侈品、钟表由京东联系保修,享受法定三包售后服务),与您亲临商场选购的商品享受相同的质量保证。京东商城还为您提供具有竞争力的商品价格和,请您放心购买!
注:因厂家会在没有任何提前通知的情况下更改产品包装、产地或者一些附件,本司不能确保客户收到的货物与商城图片、产地、附件说明完全一致。只能确保为原厂正货!并且保证与当时市场上同样主流新品一致。若本商城没有及时更新,请大家谅解!
权利声明:京东上的所有商品信息、客户评价、商品咨询、网友讨论等内容,是京东重要的经营资源,未经许可,禁止非法转载使用。
注:本站商品信息均来自于合作方,其真实性、准确性和合法性由信息拥有者(合作方)负责。本站不提供任何保证,并不承担任何法律责任。
印刷版次不同,印刷时间和版次以实物为准。
价格说明:
京东价:京东价为商品的销售价,是您最终决定是否购买商品的依据。
划线价:商品展示的划横线价格为参考价,该价格可能是品牌专柜标价、商品吊牌价或由品牌供应商提供的正品零售价(如厂商指导价、建议零售价等)或该商品在京东平台上曾经展示过的销售价;由于地区、时间的差异性和市场行情波动,品牌专柜标价、商品吊牌价等可能会与您购物时展示的不一致,该价格仅供您参考。
折扣:如无特殊说明,折扣指销售商在原价、或划线价(如品牌专柜标价、商品吊牌价、厂商指导价、厂商建议零售价)等某一价格基础上计算出的优惠比例或优惠金额;如有疑问,您可在购买前联系销售商进行咨询。
异常问题:商品促销信息以商品详情页“促销”栏中的信息为准;商品的具体售价以订单结算页价格为准;如您发现活动商品售价或促销信息有异常,建议购买前先联系销售商咨询。
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
浏览了该商品的用户还浏览了
加载中,请稍候...
联系供应商
七日畅销榜
新书热卖榜
iframe(src='///ns.html?id=GTM-T947SH', height='0', width='0', style='display: visibility:')函数式思维和函数式编程
作为一个对Hashell语言[1]彻头彻尾的新手,当第一次看到一个用这种语言编写的快速排序算法的优雅例子时,我立即对这种语言发生了浓厚的兴趣。下面就是这个例子:
quicksort&::&Ord&a&=&&[a]&-&&[a]&&
quicksort&[]&=&[]&&
quicksort&(p:xs)&=&&
&&&&(quicksort&lesser)&++&[p]&++&(quicksort&greater)
&&&&&&&&lesser&=&filter&(&&p)&xs
&&&&&&&&greater&=&filter&(&=&p)&xs
我很困惑。如此的简单和漂亮,能是正确的吗?的确,这种写法并不是“完全正确”的最优快速排序实现。但是,我在这里并不想深入探讨性能上的问题 [2]。我想重点强调的是,纯函数式编程是一种思维上的改变,是一种完全不同的编程思维模式和方法,就相当于你要重新开始学习另外一种编程方式。
首先,让我先定义一个问题,然后用函数式的方式解决它。我们要做的基本上就是按升序排序一个数组。为了完成这个任务,我使用曾经改变了我们这个世界的快速排序算法[3],下面是它几个基本的排序规则:
如果数组只有一个元素,返回这个数组
多于一个元素时,随机选择一个基点元素P,把数组分成两组。使得第一组中的元素全部 &p,第二组中的全部元素 &p。然后对这两组数据递归的使用这种算法。
那么,如何用函数式的方式思考、函数式的方式编程实现?在这里,我将模拟同一个程序员的两个内心的对话,这两个内心的想法很不一样,一个使用命令式 的编程思维模式,这是这个程序员从最初学习编码就形成的思维模式。而第二个内心做了一些思想上的改造,清洗掉了所有以前形成的偏见:用函数式的方式思考。事实上,这程序员就是我,现在正在写这篇文章的我。你将会看到两个完全不同的我。没有半点假话。
让我们在这个简单例子上跟Java进行比较:
public&class&Quicksort&&{&&
&&private&int[]&
&&private&int&
&&public&void&sort(int[]&values)&{
&&&&if&(values&==&null&||&values.length&==&0){
&&&&this.numbers&=&
&&&&number&=&values.
&&&&quicksort(0,&number&-&1);
&&private&void&quicksort(int&low,&int&high)&{
&&&&int&i&=&low,&j&=&
&&&&int&pivot&=&numbers[low&+&(high-low)/2];
&&&&while&(i&&=&j)&{
&&&&&&while&(numbers[i]&&&pivot)&{
&&&&&&&&i++;
&&&&&&while&(numbers[j]&&&pivot)&{
&&&&&&&&j--;
&&&&&&if&(i&&=&j)&{
&&&&&&&&swap(i,&j);
&&&&&&&&i++;
&&&&&&&&j--;
&&&&if&(low&&&j)
&&&&&&quicksort(low,&j);
&&&&if&(i&&&high)
&&&&&&quicksort(i,&high);
&&private&void&swap(int&i,&int&j)&{
&&&&int&temp&=&numbers[i];
&&&&numbers[i]&=&numbers[j];
&&&&numbers[j]&=&
哇塞。到处都是i和j,这是干嘛呢?为什么Java代码跟Haskell代码比较起来如此的长?这就好像是30年前拿C语言和汇编语言进行比较!从某种角度看,这是同量级的差异。[4]
让我们俩继续两个”我”之间的对话。
好 ,我先开始定义Java程序需要的数据结构。一个类,里面含有一些属性来保存状态。我觉得应该使用一个整数数组作为主要数据对象,针对这个数组进行排序。还有一个方法叫做sort,它有一个参数,是用来传入两个整数做成的数组,sort方法就是用来对这两个数进行排序。
public&class&Quicksort&{&&
&&&&private&int[]&
&&&&public&void&sort(int[]&values)&{
好,这里不需要状态,不需要属性。我需要定义一个函数,用它来把一个list转变成另一个list。这两个list有相同 之处,它们都包含一样的元素,并有各自的顺序。我如何用统一的形式描述这两个list?啊哈!typeclass….我需要一个typeclass来实现 这个…对,Ord.
quicksort&::&Ord&a&=&&[a]&-&&[a]
我要从简单的开始,如果是空数组,如果数组是空的,我应该返回这个数组。但是…该死的,当这个数组是null时,程序会崩溃。让我来在sort方法开始的地方加一个if语句,预防这种事情。
if&(values.length&==&0&||&values&==&null)&{&&
先简单的,一个空list。对于这种情况,需要使用模式匹配。我看看如何使用,好的,非常棒!
quicksort&[]&=&[]
好的,现在让我用递归来处理正常的情况。正常的情况下,需要记录sort方法参数状态。需要它的长度,所以,我还需要在Quicksort类里添加一个新属性。
public&void&sort(int[]&values)&{&&
&&&&if&(values.length&==&0&||&values&==&null)&{
&&&&this.numbers&=&
&&&&this.length&=&values.
&&&&quicksort(0,&length&-&1);
这已经是递归了。不需要在再做任何事情。
No&code.&Nothing.&Nada.&That's&good.
现在,我需要根据上面说明的规则实现快速排序的过程。我选择第一个元素作为基点元素,这不需要使用其它奇异方法。比较,递归。每次比较从两头同时遍历,一个从头至尾(i, 生成&p的list),一个从尾至头(j, 生成&p的list)。每次在i方向遍历中发现有比j方向遍历的当前值大时,交互它们的位置。当i的位置超过j时,停止比较,对形成的两个新队列继续递归调用。
private&void&quicksort(int&low,&int&high)&{&&
&&&&int&i&=&low,&j&=&
&&&&int&pivot&=&numbers[low];
&&&&while&(i&&=&j)&{
&&&&&&&&while&(numbers[i]&&&pivot)&{
&&&&&&&&&&&i++;
&&&&&&&&while&(numbers[j]&&&pivot)&{
&&&&&&&&&&&&j--;
&&&&&&&&if&(i&&=&j)&{
&&&&&&&&&&&&swap(i,&j);
&&&&&&&&&&&&i++;
&&&&&&&&&&&&j--;
&&&&if&(low&&&j)
&&&&&&&&quicksort(low,&j);
&&&&if&(i&&&high)
&&&&&&&&quicksort(i,&high);
交换位置的方法:
private&void&swap(int&i,&int&j)&{&&
&&&&int&temp&=&numbers[i];
&&&&numbers[i]&=&numbers[j];
&&&&numbers[j]&=&
使用Haskell
我先定义一个lesser和一个greater作为每次迭代的两个队列。等一下!我们可以使用标准的head和tail函数来获取第一个值作为基点数据。这样我们可以它的两个部分进行递归调用!
quicksort&(p:xs)&=&(quicksort&lesser)&++&[p]&++&(quicksort&greater)
非常好,这里我声明了lesser和greater两个list,现在我将要用where——Haskell语言里一个十分强大的用来描述函数内部值(not 变量)的关键字——描述它们。我需要使用filter函数,因为我们已经得到除首元素之外的其它元素,我们可以调用(xs),就是这样:
&&&&&&&&lesser&=&filter&(&&p)&xs
&&&&&&&&greater&=&filter&(&=&p)&xs
我试图用最详细的语言解释Java里用迭代+递归实现快速排序。但是,如果在java代码里,我们少写了一个i++,我们弄错了一个while循环条件,会怎样?好吧,这是一个相对简单的算法。但我们可以想象一下,如果我们整天写这样的代码,整天面对这样的程序,或者这个排序只是一个非常复杂的算法的第一步,将会出现什么情况。当然,它是可以用的,但难免会产生潜在的、内部的bug。
现在我们看一下关于状态的这些语句。如果出于某些原因,这个数组是空的,变成了null,当我们调用这个Java版的快速排序方法时会出现什么情况?还有性能上的同步执行问题,如果16个线程想同时访问Quicksort方法会怎样?我们就要需要监控它们,或者让每个线程拥有一个实例。越来越乱。
最终归结到编译器的问题。编译器应该足够聪明,能够“猜”出应该怎样做,怎样去优化[5]。程序员不应该去思考如何索引,如何处理数组。程序员应该 思考数据本身,如何按要求变换数据。也许你会认为函数式编程给思考算法和处理数据增添的复杂,但事实上不是这样。是编程界普遍流行的命令式编程的思维阻碍 了我们。
事实上,你完全没必要放弃使用你喜爱的命令式编程语言而改用Haskell编程。Haskell语言有其自身的缺陷[6]。只要你能够接受函数式编程思维,你就能写出更好的Java代码。你通过学习函数式编程能变成一个更优秀的程序员。
看看下面的这种Java代码?
public&List&Comparable&&sort(List&Comparable&&elements)&{&&
&&&&if&(elements.size()&==&0)&return&
&&&&Stream&Comparable&&lesser&=&elements.stream()
&&&&.filter(x&-&&pareTo(pivot)&&&0)
&&&&.collect(Collectors.toList());
&&&&Stream&Comparable&&greater&=&elements.stream()
&&&&.filter(x&-&&pareTo(pivot)&&=&0)
&&&&.collect(Collectors.toList());
&&&&List&Comparable&&sorted&=&new&ArrayList&Comparable&();
&&&&sorted.addAll(quicksort(lesser));
&&&&sorted.add(pivot);
&&&&sorted.addAll(quicksort(greater));
&&&&return&
是不是跟Haskell代码很相似?没错,也许你现在使用的Java版本无法正确的运行它,这里使用了lambda函数,Java8中引入的一种非常酷的语法[7]。看到没有,函数式语法不仅能让一个程序员变得更优秀,也会让一种编程语言更优秀。
函数式编程是一种编程语言向更高抽象阶段发展的自然进化结果。就跟我们认为用C语言开发Web应用十分低效一样,这些年来,我们也认为命令式编程语言也是如此。使用这些语言是程序员在开发时间上的折中选择。为什么很多初创公司会选择Ruby开发他们的应用,而不是使用C++?因为它们能使开发周期更短。不要误会。我们可以把一个程序员跟一个云计算单元对比。一个程序员一小时的时间比一个高性能AWS集群服务器一小时的时间昂贵的多。通过让犯错误更难,让出现bug的几率更少,使用更高的抽象设计,我们能使程序员变得更高效、更具创造性和更有价值。
[1] Haskell from scratch courtesy of
[2] This quicksort in Haskell that I am showing here is not in-place quicksort so it loses one of its properties, which is memory efficiency. The in-place version in Haskell would be more like:
import&qualified&Data.Vector.Generic&as&V&&
import&qualified&Data.Vector.Generic.Mutable&as&M&
qsort&::&(V.Vector&v&a,&Ord&a)&=&&v&a&-&&v&a&&
qsort&=&V.modify&go&where&&
&&&&go&xs&|&M.length&xs&&&2&=&return&()
&&&&&&&&&&|&otherwise&=&do
&&&&&&&&&&&&p&&-&M.read&xs&(M.length&xs&`div`&2)
&&&&&&&&&&&&j&&-&M.unstablePartition&(&&p)&xs
&&&&&&&&&&&&let&(l,&pr)&=&M.splitAt&j&xs&
&&&&&&&&&&&&k&&-&M.unstablePartition&(==&p)&pr
&&&&&&&&&&&&go&l;&go&$&M.drop&k&pr
Discussion .
[3] This version of quicksort is simplified for illustration purposes. It’s always good looking at the source. Boldly go and read this piece of History (with a capital H) by C.A.R. Hoare, .
[4] Taken from
[4] Will we consider uncontrolled state harmful the same way GOTO
consolidated structured programming?
[5] This wiki has LOTS of architectural information about the amazing Glasgow Haskell Compiler, ghc.
[6] A big question mark over time on functional programming languages has been the ability (or lack thereof) to effectively code User Interfaces. Don’t despair though! There’s this cool new thing called Functional Reactive Programming (FRP). Still performing babysteps, but there are already implementations out there. One that’s gaining lots of momentum is ReactJS/Om/ClojureScript web app stack. Guess that might be a good follow-up post
[英文原文: ]
转载请注明:文章转载自 开源中国社区
本文标题:函数式思维和函数式编程
本文地址:
我觉得文章不是在比较语言本身吧。虽然内容不甚明了。有时间得看一下。为什么大家都对for 的i和j这么排斥呢?看着多明白啊。关于函数式编程,读研或读博,国外哪所大学强?-学网-中国IT综合门户网站
关于函数式编程,读研或读博,国外哪所大学强?
来源:互联网 发表时间: 3:02:53 责任编辑:鲁晓倩字体:
供参考答案5:
学Scheme,来东北
供参考答案6:
供参考答案7:
推荐Chalmers,一般挺少有人知道,等dependent types再流行一点估计会再出名一些。感觉不少论文都是从那儿来的。
相关信息 [
相关文章:
最新添加资讯
24小时热门资讯
Copyright © 2004- All Rights Reserved. 学网 版权所有
京ICP备号-1 京公网安备02号}

我要回帖

更多关于 国内读研国外读博 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信