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

python函数式编程 大家好,这里还还还是长弓 今天我们来讲讲python中的函数式编程 函数式编程 有些同学疑惑了,我们已经学了函数,为什么还要学这个函数式编程呢? 两者的区别是什么呢? 函数是一个语法,函数式编程是一种编程的思路 是将本是CPU加减乘除的过程封装成一个个函数,调用函数的过程,更整体,更人性 函数式编程允许传入一个函数作为函数... 阅读详情

很奇怪不是,很少有人每天都使用函数式编程语言。如果你用Scala,Haskell,Erlang,F#或某个Lisp方言来编程,很可能没有公司会花钱聘你。这个行业里的绝大部分人都是使用像Python,Ruby,Java或C#等面向对象的编程语言——它们用起来很顺手。不错,你也许会偶然用到一两个“函数式语言特征”,例如“block”,但人们不会去做函数式编程。

然而,很多年来,我们一直被教导说函数式编程语言很好很棒。我仍然记得当我第一次阅读ESR的著名的关于学习Lisp语言的论文时的困惑。也许大多数的人对Paul Graham 的《Beating The Averages》这篇文章更加熟悉:

使用Lisp开发使我们的开发周期迭代的如此之快,以至于有时当竞争对手在新闻发布会上推出他们的新功能一两天后,我们就能复制出同样的功能。当报道产品发布的新闻记者打电话给我们时,我们的产品已经拥有了同样的功能特征。

那些皈依函数式编程的人中,一直常见的考虑是:学习这种新的、函数式的语言“对你有好处”;就像是某些人建议说每天30分钟的健身房活动会“让你的身体健康”一样。但这也同时暗示了这样做的难度和需要的付出。Lisp语言跟Haskell、Ocaml和Scala语言不同,被认为是出了名的难学,可以说是臭名昭著。文雅的人说这是Lisp语言的“深度&广度”的体现。不文雅的人说这是“意淫”或“玩弄学术”或简单的“没必要”。我认为,它的难度跟你对它熟不熟悉有关,而且,这种难度是一种重要指标显示:学习这样的一种语言会让你编程更有效率、能力更强。

它给你的初次印象不友善

我7岁时就开始编程,在漫长无聊的郊区夏季里,在我祖父的计算机上瞎搞一气。我学了BASIC,用它在屏幕上画一个蹦跳的球。我学了Pascal,用它写了一个能通过PC喇叭放音乐的程序。大概10岁时我学了C语言,但遇到了一堵越不过去的墙,直到我上了高中。那就是:指针。即使不算这些该死的指针,我写、读、学习、练习中,同样遭遇无数的失败。我把祖父的硬盘给毁掉了两次(一次属意外),最后弄得不少次要自己重装操作系统。我失败,一遍遍的失败。

也许你也有跟我相似的故事,也许是完全不同的一个。但我想,差不多所有学过编程的人都有过遇到困难的经历。我们在学了一些基本知识后,必然会遇到一些公认的概念上的关口,比如“指针”。很多计算机科学教授会把指针描述为他们课程上的过滤网。如果你想成为一名优秀的程序员,你必须要能理解指针。很少人能轻松的掌握它们。大多数人,包括我,则需要不断的练习和参考例子来理解什么是指针、为什么它们很重要。

这种艰难的努力过程不是偶然的,是一种几乎普遍的现象。指针是一种非常强大和基础功能的概念。学会它能让你成为一名更好的程序员,能让你的思考更加形象化。即使你使用的语言并不提供指针这样的特征,但跟指针类似的数据结构和概念却随处可见。

新奇事物

一旦你学会了几种语言后,所有的语言都开始看起来都很相似。知道Python的人学习Ruby可能不会遇到太多的问题,知道Java的人学习C#会感到很熟悉。不错,也有意外的地方。Ruby爱好者在学习Python时会对它的comprehension感到吃惊,Java用户会对C#里的委派摸不着头脑。还是那句话,如果你只瞟一眼,它们都很相似。我可以打保票的说,如果你还不曾有过这样的认识,一旦你学了一种Lisp语言,你会发现所有的Lisp变种都很相似。

有人说,大部分人第一次使用Haskell或Ocaml时都完全的不知所措。见鬼了,在Haskell里,连分号都跟别人不一样。这并不是语法的问题;Haskell和ML语言完全基于一种不同的概念、一种新的语言范式。你需要用不同的方式开发应用,不同的方式组织应用,不同的方式扩展应用。

很多这样的新概念都具有不可思议的强大力量。Haskell里的Monads 是跟指针一样基础且强大的概念(你很可能在不知道它叫什么的情况下就已经使用过它们了)。所以,跟学了Java后再学C#不一样,有志向学习函数式语言的人需要往回走的更远,去学习更加基础的概念后才能接下去学习。就像是完全再学习一次指针。并且,就像是当年我们刚开始学习编程一样,一些很大的概念看起来会让人迷惑茫然,让人沮丧,直到你去攻克(以及失败)它们。

吃下你的药丸,找到你的药剂师

尽管不好学,但我坚信,学习这些函数式编程语言会在职业上对你有好处。我相信有些人读到这点时会眼睛翻起来向天看,很难想象出这些monoids 或 monad 会对他们在使用Java或C#时有用处。对我而言,我已经不惊奇于由于这样的思维而阻止他们学习函数式语言的现象;他们需要学习一种跟指针和递归一样基础的新概念。他们需要有一种只有专业人员在完成清晰的商业目标时才具有的耐心和斗志。很少人能在过了可塑的年龄后还受得了挫折——一次又一次的挫折——否则我们现在都早成专家了,不是吗?

还有更复杂的东西,有大量的语言和算法研究都是用函数式语言实施的(尤其是Haskell)。你很容易会被这些不熟悉的概念——例如分类学理论, half-finished abstractions,一些失败的研究——弄的迷失方向。没有一个清晰的指导(比如由一个实用主义的作者写的一本好书),本来已经很困难的学习任务变的更加可怕。
这些叠加起来的复杂因素导致了不出意外的结果:很多人不情愿在函数式编程学习中投入时间。很容易理解这种不情愿,“我干嘛不把花在学习这些东西的时间用在实现什么东西上呢?”但这种思路也表明了你永远不愿意在任何新技术上浪费时间(只用自己熟悉的)。在一个像软件技术这样日新月异的产业里,我不认为这是正确的判断。

眼见为实

学习一种函数式编程语言最显而易见的好处是,你能学会这种类型语言中的函数式概念。它能帮助你的大脑,让它具有能非常清晰的思考和处理一些惊人的重大概念的能力。这并不是函数式编程具有魔法;各种语言和范式的出现都是为了应对某一特定类别的问题。函数式编程的杀手锏正是应对了当今世界上日益增长的并行性编程和元数据编程趋势。

例如,我们研究一个简化的、本地版本化的Google著名的MapReduce范例。用函数式方式描述这种范例是不可思议的清晰简洁:

mapReducer data partitioner mapper reducer =                let partitions = partitioner data                in reduce reducer (map mapper partitions)

让这样的代码支持并行计算或分布式并行计算是轻而易举的(对于本地并行计算,很多的功能包都支持“pmap”和“preduce“——只需要利用函数式语言的一些简单特性)。像maps, partitions, generators, streams, reductions, folds, 已以及 function chaining等概念在各种的函数式编程语言中都大同小异,所以,任何对Lisp,Haskell,OCaml,甚至带点函数式语言特征的语言——Python和Ruby熟悉的人,都会很容易的理解这里面的思想精华。

让我们花点时间考虑一下,如何用一种面向对象的语言,以一种常见的面向对象的模式来清楚的描述这种架构。至少你需要做的事情是定义用来描述mapper和reducer的声明。如果你有好奇心,请试着用你喜欢的面向对象语言描述一个最小化的“面向对象”的MapReduce。我发现那是非常罗嗦的。如果使用Java风格的语言,它会像这样:

interface Mapper {   B map(A input); }

 interface Reducer {   Y reduce(X a, X b); }

 abstract class MapReduce {   private Mapper mapper;   private Reducer reducer;

   public MapReduce(Mapper map, Reducer reduce) {     // ...   }

   public run(SeqenceType data) {     // ...   } }

即使是没有加入循环逻辑,这种缺乏函数式模式中常见的名词和动词的使用,使得MapReduce这种技术很难被定义。这种定义方式几乎是滑稽可笑的,但它能让你想到函数式概念。另外一个好例子是Scala语言如何利用完备的Java Fork/Join 类库,把它轻松的集成的自己的自有语法中。

各有所求

所以,我鼓励任何想进步的程序员:请考虑学习一种函数式语言。Haskell和OCaml都是极好的选择,F#和Erlang也相当的不错。它们都不好学,但也许这是个好事。努力弄清楚你遇到的复杂的概念,看看是否有其他人正在利用这些概念;经常的,你会在寻找这些不熟悉的概念的真正用意的时候实现思想上的突破。

当你开始学的时候,请注意,不要过于在意。就像其他任何需要你花时间和精力的事情一样,过度的在函数式编程上进行精力上的投资是很危险的。掉进了认知能力的陷阱后你的投资会血本无归。你很容易会忘掉世界上还有无数种计算模型,你更容易忘掉有多少种优秀的软件根本没有使用任何的函数式概念。
学习的道路会越来越难走,但从另一方面说,在你日常的编程中,你会发现有越来越多的可以使用的重要概念和模型。对于这样紧凑的编程风格你会越来越适应,必然,你也会对如何成为一名更好的软件工程师有了新的认识。

补充

有不少校对这篇文章的人在看完文章后都问了我一个同样的问题:“听起来不错,大卫,可是我应该学习那种语言呢?”当然,这是他们给我出的难题。

我想,如果你是一个很有经验的程序员,这最能“应付”这个问题的答案是:“选一种符合你的需求的”。如果你需要在JVM上工作,选择Scala或Clojure。如果你想能快速的开发大型分布式软件系统,选择Erlang。如果你想要一种具有超强编译器的超能干活的语言,请选择Haskell或RCaml。如果你想要一种比Ruby或Python更有能力的原型工具,选择Scheme。

请记住,我们在这里要做的这些目的是为了实际的技能和自我进步。如果你能腾出时间学这些,就走出你的安逸环境,挑战自己。

因为我已经学习了Lisp和Erlang,而且使用OCaml做专业工作,我决定研究一下Haskell,这完全是另外一个世界。我发现唯一能帮助我参透这种语言的途径是依赖Learn You A Haskell 和 Real World Haskell 这两本有用的指导材料。这些书写的非常好,很有价值,而且可以免费在网上找到。如果你想试一下Haskell,这些书可以当作你的寻宝图。


函数式编程,真香 最开始接触函数式编程的时候是在小米工作的时候,那个时候看老大以前写的代码各种 compose,然后一些 ramda 的一些工具函数,看着很吃力,然后极力吐槽函数式编程,现在回想起来,那个时候的自己真的是见识短浅,只想说,'真香'。 最近在研究函数式编程,真的是在学习的过程中感觉自己的思维提升了很多,抽象能力大大的提高了,让我深深的感受到了函数式编程的魅力。所以我打算后面用 5 到 8 篇的篇... 阅读详情

相关推荐

1. 滚雪球学Python第四季开启,一需三吃,Python 函数式编程初识,面向过程,面向对象,函数式

启动,学Python就从这里开始吧

梦想橡皮擦,专栏100例写作模式先行者,现象级专栏 《Python 爬虫 100 例》作者、《滚雪球学 Python 专栏》原创者 1万+

函数式编程很难,这正是你要学习它的原因(转)

本文是从 Functional Programming Is Hard,That's Why It's Good 这篇文章翻译而来。翻译原文来自这里。   很奇怪不是,很少有人每天都使用函数式编程语言。如果你用Scala,Haskell,Erlang,F#或某个Lisp方言来编程,很可能没有公司会花钱聘你。这个行业里的绝大部分人都是使用像Python,Ruby,Java或C#等面向对象的编...

风吹鸡蛋壳 284

CPRI原理及应用--帧结构

对于CPRI 控制字,协议将1个超帧(256基本帧)的控制数据划分为一个“子通道”,将子通道内超帧内的控制字进行行列划分,分为4列X64行,每64个基本帧组成1列。如下图所示。每个Xs子通道内Ns的定义基本相同,在做控制字设计时,主要已Xs和Ns和X.Y.Z开展控制字映射。

u014035968的博客 2325

不会函数能学c语言吗,不会函数能学C语言吗

该楼层疑似违规已被系统折叠隐藏此楼查看此楼反正中学数学这方面基本浪费时间,花几分钟给你们点补课方向。0.关于数学中函数的定义的演变,没搞过数学史的基本都没什么有效的认识,找英文喂鸡百科 History of the function concept 这个条目。基本理解过了就知道学校里学的(包括数学专业本科程度的)都是些什么叒鸡货色了。1.中学数学姑且当作空气,不过就是带专水平的也得先补课集合论(...

weixin_32101177的博客 199

AGV避坑指南:海康控制系统与Modbus设备对接的那些‘坑’

本文深入解析海康AGV控制系统与Modbus设备对接中的常见问题及解决方案,涵盖通信协议对接、信号干扰、硬件层问题和软件优化策略。通过真实案例和实用技巧,帮助工程师规避典型陷阱,提升系统稳定性和效率。

l3m4n的博客 741

森林冰火人html源码,森林冰火人单人版(源码)

【实例简介】java小游戏——森林冰火人,单人游戏, 实现人物行走,跳跃,吃水晶,具有计时功能,积分功能,倒计时结束游戏失败。【实例截图】【核心代码】森林冰火人单人版├── bin│ ├── game│ │ ├── Help.class│ │ ├── Logon.class│ │ ├── Main.class│ │ ├── Mykey.class│ │ ...

weixin_42507981的博客 6201

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

函数式编程很难,这正是你要学习它的原因 作者: Dave Fayram  来源: 外刊IT评论  发布时间: 2012-07-31 12:13  阅读: 16440 次  推荐: 14   原文链接   [收藏]     英文原文:Functional Programming Is Hard,That's Why It's Good   很奇怪不是,很少有

gdapenny的专栏 548

自己动手写CPU(1)五级流水线及CPU第一条指令ori

自己动手写CPU(1)五级流水线及CPU第一条指令ori 动机 不知为何研一的自由时间突然多起来,可能人一闲下来就容易焦虑吧,hhhhhh。正好之前看到一本《自己动手写CPU》,就按照此书从头实做一遍MIPS指令集的CPU,也当做对大学课程的总结。之前看龙芯杯比赛的代码震惊到我了,想想那堆大佬本科在搞这东西而我本科在瓜瓜地刷分,感叹人之间的差距真的好大。痛定思痛,还是先动手做起来这才能假意安慰自己,我好像也不错。闲言少叙,让我们开始吧! 由于作者提供了各章实现的具体代码,所以该系列博客主要记录我过程中有哪些

谦豫 7080

为什么函数式编程在Java中很危险?

摘要:函数式编程这个不温不火的语言由来已久。有人说,这一年它会很火,尽管它很难,这也正是你需要学习的理由。那么,为什么函数式编程在Java中很危险呢?也许这个疑问普遍存在于很多程序员的脑中,作者Elliotte对此发表了一些见解,我们一起来看看他是怎么说的。 在我的日常工作中,我身边的开发者大多是毕业于CS编程顶级院校比如MIT、CMU以及Chicago,他们初次涉及的语言是Haskell、...

weixin_33737774的博客 335

4×V100部署Qwen3.8-Flash-Next:vLLM/GGUF实战

大模型本地部署的核心,是把参数量、量化精度、显存容量和推理框架放在同一张账本里算清楚。MoE 模型总参数量大但激活参数少,解码阶段更受显存带宽与 KV Cache 限制;通过 INT4/AWQ 或 GGUF 等 4-bit 量化可显著压缩权重占用,再结合 vLLM 张量并行、llama.cpp 分层切分提升多卡利用率。其技术价值在于让 V100 这类老架构 GPU 也能承载百亿级参数模型的私有化推理,并服务于 RAG 知识库、工作流 API、批量生成等场景。这次围绕 4×V100 32G 部署 Qwen3.

weixin_29061425的博客 349

EtherCAT ROS2 入门教程(一)

本文介绍了EtherCAT驱动与ROS2的集成方案,主要包括三部分内容:1)在Ubuntu 22.04上安装IgH EtherCAT主站的详细步骤,包括内核配置、源码编译和网络适配器设置;2)构建ethercat_driver_ros2,通过ros2_control描述文件配置硬件接口和EtherCAT从站模块插件;3)使用方法,包括启动EtherCAT主站和运行配置包。该方案支持通过参数文件定义硬件接口,并提供通用和专用两种EtherCAT模块插件,便于开发基于EtherCAT的工业应用。

机器人控制与仿真应用 1530

函数式编程很难,这正是你要学习它的原因 | 外刊IT评论网

函数式编程很难,这正是你要学习它的原因 | 外刊IT评论网 函数式编程很难,这正是你要学习它的原因 | 外刊IT评论网函数式编程很难,这正是你要学习它的原因156次分享新浪微博腾讯微博Tweet人人网QQ空间很奇怪不是,很少有人每天都使用函数式编程语言。如果你用S...

180

伺服系统控制原理深度解析

摘要:本文系统阐述了伺服系统的控制原理与应用。首先介绍了伺服系统的定义、组成及其在工业自动化中的重要性;然后详细分析了反馈控制机制、稳定性判据和性能指标;重点推导了传递函数和状态空间两种数学模型,并通过LaTeX公式展示了二阶系统建模过程;进而对比了PID控制、状态反馈及自适应控制等方法的优缺点;最后结合数控机床等案例,验证了理论方法的有效性,并展望了伺服系统智能化发展趋势。全文兼顾理论深度与实践指导性,为控制工程领域提供了系统的技术参考。

技术工作者 1267

函数式编程

看懂公司代码大数量下处理集合效率高代码可读性高消灭嵌套地狱定义:Lambda表达式是Java 8及以后版本中引入的一个重要特性,它提供了一种简洁的表示匿名方法的方式。Lambda表达式允许开发者以更简洁的方式传递代码块作为参数给方法。用途:Lambda表达式主要用于实现只有一个抽象方法的接口(即函数式接口)。它可以显著简化代码,提高代码的可读性和可维护性。语法:Lambda表达式的语法通常包括一个参数列表和一个方法体,参数列表和方法体之间用箭头(->)分隔。例如,

lanssssss的博客 1031

文献综述三大痛点用AI轻松解决!借助Gemini 3 Pro搞定检索难、阅读慢、框架乱问题(附 AI 提示词)

4)“漏斗式”结构:先介绍宏观领域的研究现状,再缩小范围,聚焦于与你课题直接先关的子领域,深入探讨与你研究变量直接相关的文献, 指出前人没做过、没做全或结论有矛盾的地方,再顺势提出你的研究课题,这种结构逻辑最清晰,能直接引导读者发现你研究的必要性。想要有针对性的搜到相关文献,必须先把模糊的研究题目拆解成精准的检索语言,这个时候就需要建立一个关键词矩阵,如核心词、同义词、学术术语、上下位词,以及对应的英文表达。请围绕【我的研究主题/关键词】,检索近5年发表的高被引的中英文文献,优先选择顶刊综述/论文。

智能AI让学术科研更容易 277

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【函数式编程】什么是函数式编程? C语言为何不是函数式语言?

什么是函数式编程? C语言为何不是函数式语言? 函数式语言有两个个主要的特点:1. 函数是“头等公民”。2. 数据的“immutability”. 操作的“无副作用”, 这规避了‘锁’。 函数式编程的函数是指数学上的函数:给定输入固定的输出,没有副作用。任何语言都可以用函数式的风格, 只是难易不同罢了。 比如函数 y = f(x). 和 函数 t = g(z); 在数学上,当 t在f(x)的定义域内时,可以组成复合函数 y=f(g(z)); 对于第二个问题,C为何不是函数式语言? 因为这种效果在C里面

我的笔记本 5460

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

70、Python之函数式编程:一文搞懂函数式编程的核心概念

本文首先简单介绍了编程范式的概念,然后梳理了编程语言与编程范式的关系。在此基础上,引入了函数式编程这一范式,着重介绍了为什么要学习函数式编程。最后,系统梳理了函数式编程的核心概念,从而对后续学习函数式编程有一个纲领性的了解。

南宫理的日知录 1486

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

JavaScript函数式编程指南

本文内容来自于《JavaScript函数式编程指南》,可以看作是对原书内容进行提炼和总结,若您有需要或感觉有出入请参原书。函数式编程是指为创建不可变的程序,通过消除外部可见的副作用,来对纯函数的声明式的求值过程。简单来说,函数式编程是一种强调以函数使用为主的软件开发风格。这与日常基本工作中使用函数不同,使用函数来获取结果并不重要,函数式编程的目标是使用函数来抽象作用在数据中之上的控制流与操作,从而在系统中消除副作用并减少对状态的改变。这个程序很简单,但所有代码是写死的,不能动态显示消息。

qq_66118130的博客 1378

《别看了,你学不会的》——函数式编程

函数式编程是一种声明式的编程范式,起源于学术界,从lambda演算演变而来,最初的函数式语言是Lisp

穷人家阳公子的博客 578
上一篇: 爱因斯坦有关佛教与科学的论述
下一篇: 外程序员推荐的免费编程书籍资源
hi
hi
博客等级 码龄20年 3粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值