Perl的衰落是文化层面的,不是技术
据Discourse论坛所言,有人终结了Perl
关于Perl衰落原因的讨论在Hacker News和其他技术论坛上掀起热潮。我在90年代中期写过大量Perl代码,2000年代初还用mod_perl维护过互联网流量最大的网站之一,因此有些见解。我的观点是:这主要源于文化因素。Perl在保守价值观主导的反动社区中发展,阻碍了它演变为成熟的通用语言生态系统。其他语言填补了这一空白。
我记得Perl
需要说明的是,尽管这只是我的个人见解,但我是亲历者。我离开亚马逊后便不再系统使用Perl,大约是2005年左右。这些观点源于一位曾深度参与Perl鼎盛时期、后来又抽身而出的实践者的第一手印象。我既是圈内人,也是局外人,拥有丰富的双重视角。
Perl的根源在于系统管理
何谓文化?Perl始终承载着大量可称为“BOFH”的文化基因,其根源可追溯至古老的UNIX系统管理时代。那些被动攻击式的行话和内部梗——比如“RTFM”(读手册)、“lusers”(菜鸟)、‘wizards’(高手)、“asking for help the wrong way”(错误求助方式)等等。这些表述本身并非严肃指责,却暗含着本质上部落化、内向型的社交规范。其中隐含着特权群体,加入需付出代价,必须缴纳会费。文化保守主义是首要原则。
这种文化根源于旧式封闭数据中心的命令文化。当计算机资源昂贵、集中化、脆弱且依赖人工操作时,守门人便以严苛手段维护体系,防范不当使用。我职业生涯始于这个时代的尾声(80年代末),那时网络尚未兴起,微型计算机也未普及,这种堡垒内部的思维确实盛行。(筑堡固守的弊端在于:一旦身处堡垒,便极易滋生围城心态)。计算机是特殊的存在,用户是麻烦的干扰,破坏性才是首要敌人。
此类“危境”环境中存在着恶性循环:骄傲情绪极易滋生。在此环境中茁壮成长实属不易,若能生存且表现优异,便被视为技艺精湛;你完成了壮举,理应标记你的成长仪式。这种文化陷阱极具危险性——稍不留神,你便会将那些险阻与困境,那些“自掘坟墓”的陷阱,视为 必需 的特征:它们教会你那些标志着独特价值的生存技能。更残酷的是,它们筛除了愚钝之辈,助长了那些熬过漫长适应期者的高位。哎呀,你这就创造了阶级政治。
这种思维的症结在于自我强化。努力掌握系统复杂性确实令人满足——你确实完成了艰巨任务且表现出色。这其实与后来被称为“精英统治”[1]的机制如出一辙,但核心逻辑更简单——当困难本身成为荣誉徽章,你就设下了陷阱:任何降低系统门槛的举措都会被视作贬低你的成就。你开始执着于维护自己曾跨越的壁垒。
(顺带一提,LeetCode面试管道正是这种心态的产物,但暂且不作赘述)
因此UNIX操作员文化本质上是部落式精英主义(区别于UNIX 实现者 文化——后者源于截然不同的文化规范,本身就是个耐人寻味的分支[2]), 这群文化祭司略带自恋,崇尚机巧与知识囤积,热衷炫技,满腹典故,秉持守护圣火的防御心态——既要安抚平民的温饱需求,又要抵御蛮族的侵扰。进入90年代时,这种文化已悄然式微——集中式计算正让位于微型计算机的崛起。但万维网的爆发式增长,却让互联网/Unix文化借着巨大的公共机遇真空,骤然重返主流舞台。所有人突然迫切需要编写程序,将文本从UNIX文件系统(及数据库)推送至网页——而Perl在这片新生的关键生态中占据独特先发优势。但其文化基因与价值理念,仍深深植根于那个旧时代。
由此衍生出一种文化基调:Perl对“难缠的天才”类型充其量只是勉强容忍。不幸的是,这类有毒人格往往在我描述的文化环境中如鱼得水,并确实助长了这种氛围。我无意点名道姓,因为我想阐明观点而非煽动文化战争或挖掘八卦,但确实存在若干典型案例,若感兴趣你大可查证相关传闻。要温和地描述这种累积效应,我只能说当时存在一种根深蒂固的文化准则:“只要出于正义目的,粗鲁无礼也无妨”。
城中之城
这种紧张感始终如影随形。Perl的IRC频道和邮件列表充满小团体色彩,充斥着备受尊崇的专家和内部笑话,对天真无知者苛刻,热衷于激烈冗长的辩论,对新人略带戒备。更近乎教派氛围。“TIMTOWTDI”原则表面宽容,实则强调“在Perl中实现方式不止一种”——由此不难推知,使用其他语言几乎毫无必要。这种对极致灵活性的推崇,却悖论般地成为保守主义的引擎。既然Perl已能以多种方式灵活实现任何功能,语言本身便无需变革——“我们已有现成方案,无需创新”。这种态度决定了Perl的进化路径:核心语言保持稳定(如同堡垒中的堡垒,仅供高级巫师进入),创新则被推向CPAN外部。开发者可通过编写和使用第三方库在核心之外添加功能,借助pragma指令改变语言行为而不修改Perl本体。理论上最优秀的CPAN模块可被纳入核心,使语言能从经过验证、广泛使用的特性中保守进化。
纸面上这听起来合理。但实践中,我认为这种设计从早期就将根本性利益冲突编码进社区,为后来诸多增长问题埋下伏笔。我无意声称Perl“发明”了依赖地狱,但它终究是另一项因文化哲学误判而被奉为美德的重大缺陷。
关于原始博客文章讨论Perl 6是否显著影响Perl发展的背景,有个常被忽略的有趣现象:Perl 6本身就是持续争论的产物。Perl 6是分裂的产物。以下是Larry Wall本人在YAPCOSCON 2000大会上关于Perl 6起源事件的经典记录:
我们花了整整一小时讨论各种枯燥乏味的政治与组织问题。中途乔恩·奥旺特走进来,站着听了片刻,随后他非常平静地走向角落的咖啡服务台——当时房间里约有20人——他拿起一只咖啡杯砸向对面的墙壁,接着不断将咖啡杯砸向墙壁,并说道: “除非我们能提出让社区兴奋的新方案,否则我们完蛋了——因为大家正因厌倦而纷纷离去,转投其他项目。”
(请稍作停顿,思考这种既容许公开场合出现此类行为,又将其奉为文化精髓的社会文化)
Perl 6 的冲击
Perl 6 实为一场 分裂 。Perl 本已承受巨大压力——既要适应后互联网时代主流网络应用建设的现代化浪潮,又要应对核心维护者的固守保守主义, 加之第三方库数年间呈指数级增长的维护负担,导致实现基础功能的多种方案逐渐演变成分形般的混乱——这些看似微小差异却相互兼容的实现方式,在部署环境悄然转向更现代、更普及的万维网[3]之际,已然成为语言的底层特性。
因此,虽然我认同“Perl 6 杀死了 Perl”这种概括是错误的,但我认为 Perl 6 恰恰是导致 Perl 衰亡的内部矛盾的症结所在。尽管如此,我仍要强调 Perl 并未消亡,没有任何力量真正“杀死”过它。“Perl 已死”这种论调实属愚蠢的讨论框架,但现实就是如此。
所以…Perl 6的诞生就像一个安全阀,用来释放这种压力,某种程度上确实有效。但遗憾的是,我认为其副作用在于:当文化分叉时,两个分支反而强化了各自固化的规范。Perl 5.x则稳稳占据着实用主义阵地,它提供了一套已成熟的解决方案,无需太多改变就能完成相同任务。那么更广泛的网络开发环境中涌现的 现代 应用模式需求呢?比如Unicode支持、REST客户端、严格数据结构、异步I/O等等?这些需求要么等待Perl 6实现,要么现在就能通过CPAN整合现有方案。Perl 6则走向另一极端——他们无需立即交付,现有Perl 5已能满足需求,Perl 6将对 所有 领域进行创新,并投入大量时间进行前期设计。[4]他们耗费至少两年撰写高级需求规格说明书,甚至分拆出一个试图构建通用虚拟机以运行所有动态编程语言的子项目,该项目最终未能交付。[5]
正是在这样的背景下,Perl在“后端”网络编程领域的核心统治地位持续下滑。遗憾的是,伴随着如今根深蒂固的文化保守主义倾向,Perl 5对此竟有明确的辩解:未来在彼方,充满魅力;而此刻我们正高效工作、获得报酬、完成任务。在堡垒内部看来尚可接受。终有一日我们会迁往新堡垒,但眼下 这里还行 。不过对新人确实缺乏吸引力。这倒也无妨,毕竟Perl本就不需要这类新人对吧?那些出现在IRC或论坛上询问Perl 6基础知识的新手,往往惨遭公然轻蔑对待。
与此同时,那边的情况
Ruby催生了“Ruby on Rails”,在动态网页构建领域掀起了一场风暴。Rails作为第二代Web框架,自诩为“有主见的Web框架”。当时Web应用架构正趋于三层体系:客户端是浏览器,中间层是单体应用服务器,持久层是关系型数据库,并采用分流架构分别处理静态与动态内容。Rails提供了一种实现方案:其极具开发者友好的工具链将80%核心功能转化为标准化模板,同时通过插件与客户端装饰机制实现必要的站点定制化。
Ruby同样引人注目。它本质上堪称Perl6的雏形。更准确地说,它属于平行宇宙的Perl5。Ruby源自日本,最初试图复刻Perl特性,但由编程语言爱好者在更晚时期开发,最初十年间主要在日本本土使用。在我看来这点至关重要。Ruby并非源于数十年的系统管理员文化,而是专为程序员打造的语言。它如今已成为构建Rails这类框架的理想选择——如同动态编程的空白画布,既保留了Perl的诸多特性,又摒弃了陈旧冗余,更融入了集成对象系统、异常处理、简洁数据结构等现代精妙设计。Ruby还将“友好性”奉为核心价值,其文化体系秉持原则性立场:积极接纳新人、倡导易用性,并将程序员的幸福感与便利性视为首要原则。
Rails取得了巨大成功。大约在我停止大量使用Perl的时期(2004-2005年)(因离职所致,并非出于对Perl的厌恶——事实上当年我曾是Perl的忠实拥趸),Rails已成为网页程序员入门的最佳选择。其采用率高、社区活跃、开发节奏稳健,更提供了一条清晰明亮的入门通道。甚至无需精通Ruby语言——通过一键安装工具,仅需模板即可生成基本可用的网站,堪称不折不扣的入门首选。
Perl 秉承其一贯风格,衍生出多个与 Rails 功能相似的框架。这些框架彼此兼容又相互排斥,各自依赖关系错综复杂,且都极力追求最大程度的可定制性和用户配置灵活性[6]
PHP
还有其他显而易见的竞争者。PHP始终存在,且几乎完全源自与Perl截然相反的文化背景。PHP是 面向用户的语言 。它设计初衷就是通过将脚本文件复制到用户主目录来部署,几乎不影响服务器端运行且无需权限。它几乎未经精心设计,却在整个第一代(乃至第二代)网络时代迎来爆发式增长,几乎完全归功于其近乎零门槛的入门体验。PHP还获得了额外的助力:
- 其架构极易适配共享服务器托管,因而成为博客热潮的主要实现语言。整整一代网络开发者诞生于租用CPanel主机账户时,直接将WordPress、text-pattern等系统安装至用户主目录的实践。对于“我并非专业程序员,但如何建立个人网站”的疑问,它始终是首选答案 [7]这种零门槛策略使PHP技术栈在整个网络发展史中始终稳居“基础”程序员的首选之列,直至今日。
- 由于最初面向轻量级部署场景,PHP展现出无与伦比的可扩展性——这主要得益于其执行模型高度倾向于幂等操作,每次网络请求都会彻底重建整个运行环境。某种程度上,这种模式虽不如保留热状态高效,却极适合实现无共享的水平扩展——随着2000年代网络用户基数呈爆炸式增长,这成为最简便的横向扩展路径。Facebook在当时正是以PHP构建而闻名。
Python
当然,这个时代还有另一匹重要的赛驹,它在许多方面都格外引人注目,尤其当与Perl对比时。这便是Python。Python与Perl几乎同时诞生,但其根源却截然不同。Python同样不源自UNIX文化,而是诞生于学术界和编程语言文化。这段历史常被遗忘:Python最初是为[Amoeba操作系统](https://en.wikipedia.org/wiki/Amoeba_(operating_system)开发的脚本语言,旨在成为简洁易用的脚本工具[8]。其设计理念是打造一种能成为程序员“第二编程语言”的工具。考虑到这是20世纪80年代至90年代初,当时程序员主要使用C/C++,或许还有Pascal。Python旨在为轻量级程序或脚本任务提供更快的开发速度。其核心理念是:将原本需要用shell脚本实现的功能,通过提供足够的高级结构化支持,使开发者能干净利落地构建那些在shell脚本中容易引发问题的复杂系统。因此它强调数据结构、作用域变量和模块化设计,并优先支持通过模块扩展语言功能——这些正是资深程序员所需的核心特性。该语言还致力于实现跨平台移植性,既能在当时的桌面系统运行,也能部署于服务器环境。因此它拥有庞大的标准库,围绕文件系统、并发、时间、FFI等系统特性封装了大量通用且可移植的抽象层。很长一段时间里,Python的标准口号便是“电池已装好”。
Python从未在某个特定时刻引发轰动,但始终坚持清晰渐进的演进路线和严谨的工程原则。我认为关键在于其文化基调。Python略显平淡,不追求成为最佳语言或万能语言。它始终带着几分挑剔——或许有些傲慢——略微抽离现实世界。它几乎与Perl同龄,却始终循序渐进地演化:积累用户、完善特性、逐步扩充标准库。我初次见证Python确立主流优势的时刻,同样发生在2000年代初——谷歌公开将其列为企业标准语言之一。它从不激进,只在自身生态中沉稳进化。
自然厌恶真空
勾勒这幅图景时,我始终坚信Perl持续增长的阻力主要源于文化因素。Perl在90年代的辉煌时刻,源于它成功融合了两种截然不同的用户文化:传统UNIX/数据库/数据中心运维管理用户,以及充满热情的早期网络建设者与扩展者。但极快的增长带来了文化冲击,核心体系难以维系,最终导致体系逐渐瓦解。
不过话说回来,是时候正视那个显而易见的问题了。Perl显然并未消亡。它此刻就在这里。在我拥有和操作的几乎每台计算机上,它似乎都默认安装着——而我根本没做过任何安装操作。每天仍有数百万用户在数百万系统上使用它(即便并非刻意为之)。许多人仍在 完全主动 地用它构建软件——无论是因为熟悉喜爱且行之有效,还是因需对接或维护大量遗留Perl系统,抑或是将其用于最初设计的核心场景: – 一种强大的原生POSIX脚本语言,其性能远超任何shell或awk,功能集也更为丰富。我自己偶尔仍会启用它,用于需要重复使用的小型脚本,或作为命令行管道的组成部分。
如今我不再优先选择Perl开发新项目。对我而言,这纯粹是因为当前多数任务都有更合适的替代方案——具体取决于目标需求。当我接触Perl时(约1998年),职业生涯已进入第三阶段:拥有扎实的UNIX背景,并用Lisp、Java、Pascal、Visual Basic和C++完成过实际项目。那时我选择语言的准则就是“工具适配任务”。那几年我确实痴迷Perl——它与早期网络时代的契合度堪称完美。虽然Perl文化确实存在我反复指出的负面特质,但对我个人而言并非问题——我早已在数据中心里与那些“BOFH”们打过交道,融入其中并不困难,核心理念也很快就能掌握。虽然偶尔会与社区里几个尖锐人物产生摩擦,但这反而让我保持着松散的联系。我享受这门语言快速解决问题的效率,享受它的灵活性,更享受用它以创意方式攻克难题、设计绕过漏洞的方案时,那种让我感觉自己正朝着巫师袍与魔法帽进发的聪明感。长达三四年间,它始终是我首选的编程语言。
正如我所说,我并非带着怨怼放弃它,而是自然而然地转向了其他领域,选择了更契合需求的工具。离开亚马逊后,我大量投入OS X系统和音频编程领域,这涉及大量Objective-C和C++。该领域的脚本工具常采用Ruby,偶尔也用Python。个人开发时,我重新拾起了Lisp(学生时代就钟爱这门语言)[9]。偶尔接些合同项目时会接触Perl,但我的重心始终倾向大型数据库领域——那里通常是C、Java和Python的天地。后来转向Web开发时,Rails和Ruby成为首选;进入Web服务/REST/云计算时代后,Go语言自然成为最佳选择,当然Node.js与JavaScript或TypeScript也是必然之选。我始终是个多语言程序员,在不同编程语言间切换游刃有余。事实上,绝大多数编程工作本质相通,只要符合场景需求,具体语言的实现细节并不重要。
在我有生之年,Perl绝不会彻底消失。我见过许多编程环境和语言的消亡,其衰亡程度远超Perl可能面临的境地。
- Pascal曾在教学领域和8/16位时代的桌面开发中占据 绝对主导地位
- Objective C——仅在苹果生态系统内真正有用,而苹果正全力推动其淘汰
- 在接触互联网前,我曾为庞大的16位Windows(3.11)市场开发应用软件,当时主要使用数据库四代语言(如PowerBuilder、Gupta/Centura SQLWindows)和Win16 C API。这个领域如今已彻底消亡,完全过时。类似案例必然不胜枚举。
- 现实中除了遗留系统或爱好者市场,还有谁在用Common Lisp?用户数量肯定比Perl还少。
Perl若非开创先河,也绝对是早期主导新市场范式的代表。多数技术都未能实现这一点。从这个角度看,Perl堪称巨大成功。它以真正具有深远影响的方式创新并影响了后续语言的发展。
- 深度集成正则表达式并实现其扩展(其他工具中最常用的正则表达式方言正是Perl)
- CPAN——通过互联网分发软件包/库的系统,具备依赖关系解析功能,并包含供应链验证等关键概念,采用强效的软件包签名机制
- 极度重视测试、自动化测试框架和持续集成。Perl测试格式(TAP)在其他CI/测试框架系统中也广泛存在
- 通过单一工具消弭了 shell/脚本编程与系统编程之间的鸿沟。这点或许存在争议,但 Perl 将 POSIX/libc 核心功能以原生内置形式整合进来,既保留了基本语义,又实现了内存管理与 shell 惯例的融合,堪称革命性突破。在此之前,我所见的大多数语言往往局限于单一领域;此后,多数语言则开始跨越多个领域。
- 卓越的集成文档体系:在线文档、工具内置文档及手册页。POD或许是文书式编程理念最成功的实践(尽管实际文档中很少真正交织文档内容,据我所记)。
仅凭这些亮点——当然还有诸多未尽之言——已足以构成值得骄傲的遗产。
反事实推演既愚蠢又充满趣味。若我眯眼想象,或许能看到这样一种 Perl:它拥有更开放的文化,更健康地接纳新理念与环境变革,从而能在网络范式转变中与其他工具共同进化,至今仍占据开发生态的核心地位。但现实中的 Perl 并非如此,这种情景也未曾发生。我深信,若没有我们所经历的 Perl,整个现代软件实践的形态都将截然不同。我确实认为Perl如今已退居历史舞台,影响力日渐式微,但这绝非值得羞愧或懊悔之事。只要POSIX标准存在,就没人能强行剥夺Perl的地位——就我所见,这意味着永恒。即便到了2025年,我仍能预见那只无形之手正悄然侵蚀我提及的其他系统。Rust正逐步吸收C和C++。Ruby(以及Rails框架)显然已呈衰落之势,很可能步其后尘沦为历史遗留产物。从某种角度看,TypeScript正缓慢取代Python的地位。若真如此我倒不会太惊讶,不过以我这把年纪,恐怕活不到那一天了。
脚注
- “精英主义”是个有趣的词。它最初作为贬义词,用来描述现代(即西方/英国)社会通过某种反乌托邦机制来巩固和合理化特权的不公平分配。 ↩︎
- UNIX的 实现者 文化源于科学/学术领域,脱胎于贝尔实验室。我认为这种思想流派可延伸为一种文化浪潮,推动构建抽象化的云端操作体系,如Plan 9/Inferno/Go等项目。 ↩︎
- Web 2.0概念最早由 达西·迪努奇在印刷文章中首次提出,该术语直至被蒂姆·奥莱利(当时perl.com所有者/运营者,冷知识爱好者)采纳推广后才成为主流——这位敏锐的内部观察者洞悉了推动网络发展的核心力量 ↩︎
- 此处又遇不幸巧合。正当“敏捷”作为更自然的软件开发方式开始获得认可——即在不断变化的环境和需求中进行小步迭代——之际,Perl 6却决定采用开源领域前所未有的瀑布式开发流程。直到十五年后,Perl 6才推出接近可用编程语言形态的产品。 ↩︎
- Parrot虚拟机,这个美好而理想主义的构想,在Perl 6放弃将其作为目标平台后,最终遗憾地销声匿迹。有趣的是,Python和Ruby都曾高调移植到JVM平台,其实现效果足够出色,甚至在特定领域获得了生产环境部署的应用。 ↩︎
- 这种高度抽象化的副作用在于:不仅入门门槛极高,更容易陷入性能开销的陷阱。 ↩︎
- 这种无处不在的轻量级WordPress定制安装生态系统催生了商业网站建设/小型电商网站的网络代理模式,该模式如今蓬勃发展且出人意料地健康。近期略显乐观的调查将WordPress的市占率推高至全球网站的40%以上。这个数字显然被夸大了,但即便实际数字只有一半,其市场表现依然相当强劲。 ↩︎
- 虽常有人宣称Python是为教学设计的语言,但据我所知事实并非如此。Python的设计者Guido Van Rossum此前参与的项目https://www.artima.com/articles/the-making-of-python才是真正的教学语言——名为ABC的项目,其语法和结构特性对Python产生了深远影响。 ↩︎
- 个人认为,Common Lisp比Perl更适合作为无限灵活的“万能”链锯式语言。 ↩︎
本文文字及图片出自 Perl's decline was cultural

我从未接触过文中描述的“Perl社区”。过去工作中使用Perl时,正值“直接谷歌搜索解决方案”的时代。
相比Ruby或Python,Perl语法中充斥的@和%符号显得迂回复杂,迫使开发者思考更多细节,却未带来明显优势(这与Java或C系语言需要更关注类型系统的情况不同)。
在我最初掌握的三门语言(Pascal、C/C++、Java)中,既没有Ruby,也没有Python或Perl。Ruby、Python、Matlab、R和Perl都是后来才接触的,且相隔不过数年。对于有Pascal/C/Java背景的我而言,Perl完全不具备Ruby和Python那样的易上手性。
(个人认为Python如今正逐渐失去这种优势,尤其在我最近参与的某个专业级Python项目中,可选类型提示功能虽被采用却 时常失准 ,简直是种特殊的折磨。)
编辑:文章在描述Ruby时也提及了这点:“Ruby是面向程序员的语言,现已成为构建Rails这类框架的理想选择——它如同动态编程的空白画布,兼具Perl的诸多特性,却摒弃了陈旧冗余,融入了集成对象系统、异常处理、简洁数据结构等现代特性。” Ruby作为新生语言,并非从系统管理工具演变而来,而是始终以完整的面向对象应用程序语言为定位。因此我不同意文章观点:当时的文化背景无关紧要,因为Perl文化即使发生变革,也无法将其重塑为像Ruby这样更优雅的新型语言——毕竟那时的Perl早已丧失原有本质。
> 我职业生涯中最后一个使用Python的项目采用了可选类型提示,但提示往往不准确,简直是种特殊的折磨。
但这恰恰是可选类型提示的 全部意义 。若要求提示必须准确,那根本就不该是可选提示,而是强制类型声明。
不,可选类型提示意味着有时根本不存在提示。存在提示却传入错误类型才是真正的错误和地狱。
你说的误导性类型提示与可选提示无关。可选意味着不必强制添加。错误的类型提示远比缺失提示更糟糕。
我认为 可选 类型提示的意义在于 不必一次性全局添加 ,而非允许其不准确。或许可以吹毛求疵地说“提示”不要求绝对准确,但…添加一个 可能撒谎 的语言特性,其弊端远大于优势;而 可选 特性至少有明显的迁移优势。
可选类型提示仍可让运行时发出警告——甚至仅凭可选标记——当函数本应返回整数却返回字符串时。
因为现状是:当大型代码库中存在声明返回整数却实际返回字符串的函数时,编辑器工具会彻底混乱,这种情况比完全没有提示更难处理。
(Python确实存在可用于检查验证准确性的工具。但这些工具同样是…可选的…若将它们应用于从未使用过这些工具的代码库,修复所有问题将极其耗时…)
> Python确实存在可用于检查和验证准确性的工具。但这些工具同样…属于可选项…若将它们应用于从未使用过类型提示的代码库,修复所有问题将极其耗时…
这种“糟糕”方案与“优秀”方案有何区别?
> 你本可以采用可选类型提示机制——即使仅通过可选标记,运行时仍会对你发出警告——比如当函数本应返回整数却返回字符串时。
我始终觉得Perl“社区”充满僧侣和巫师之类的荒诞设定,令人极度反感。更别提那些追求炫技和晦涩的一行式代码了。对一个非戏剧圈的年轻极客而言,Python的一切都显得更严肃、更 正常 。
现在不得不学点Perl,虽然没接触过社区,但它确实给人一种“由巫师编写、为巫师服务”的感觉。晦涩难懂的单行命令、刻意复杂化的语法,还有那些不查文档就无法理解的特性。(免得大家跳出来指正——没错,作为开发者我本该阅读文档。我也确实读了。但在查阅前,代码的逻辑对我而言完全是黑箱。这简直是糟糕的语言设计。)
其中部分内容我能理解是时代的产物,毕竟那时简洁性确实至关重要。但在2025年依然令人反感。
整件事让我想起《龙与地下城》,那些职业与法术充斥其中,却只因某个偶然坐在盖克斯桌边的家伙——他执意要扮演电影里看到的武侠人物,或是为某次即兴游戏硬塞进个法术——如今竟成了游戏的硬编码。
> 我最近不得不学习Perl,虽然没参与社区交流,但它确实_感觉_像是巫师为巫师编写的语言。晦涩难懂的单行命令、刻意复杂的语法,还有些不查文档根本无法理解的特性。
对我而言,Perl 5是经典脚本语言(而非真正的编程语言),其优劣皆在此定位。我始终以这种视角看待Perl脚本,认为它们完全合格。反观Python,它只是平庸的脚本语言,语法层面勉强算合格的编程语言,而在其他几乎所有方面都属于倒数五名的编程语言。
大脑的运作方式着实耐人寻味。
Perl始终能自然流淌于我的思维,其逻辑大多直观易懂。而其他需要硬着头皮折腾的语言,总让我费劲地将其塞进僵化的思维框架里。
我明白自己是个异类,但天啊,我多么怀念Perl曾作为介于“bash脚本”和“专业开发语言”之间的理想选择,能让我快速敲出临时程序的日子。
我认为若你是系统管理员,习惯使用shell脚本、sed、awk、grep和xargs,那么Perl对你而言可能比传统语言出身的程序员更容易理解。
>我认为若你是习惯使用shell脚本、sed、awk、grep和xargs的系统管理员,Perl会比传统语言背景的程序员更容易上手。
确实如此,它极具Unix风格,感觉像是shell脚本的自然延伸。这大概就是早期Linux用户如此着迷的原因。
作为在开发与运维(即21世纪的系统管理员)双重角色间切换的人,虽然运维工作面临更多基础设施压力,但摆脱Scrum、Jira、里程碑等繁琐事务,回归纯粹的shell脚本、sed、awk、grep、xargs操作,以及虚拟机起停的日常,反而能获得某种心灵平静。
或者干脆把一堆脚本放进仓库,省去无休止的争论——某个模块如何契合洋葱架构或六边形架构,如何践行干净代码,抑或今年架构大会上又流行什么新花样。
作为另一位“DevOps范式”从业者(本质是系统管理员,但乐于接受当下流行的任何头衔),我完全认同上述观点。能从旁观者角度见证开发者每日承受的种种繁文缛节,却知晓自己几乎不受其影响,着实令人欣慰。
况且…诸多复杂性本质上是自找的。
但必须指出:“运维开发”与传统系统管理完全不同。
这观点很有道理。编程三十余载,我至今仍需搜索资料(或借助大型语言模型)才能熟练运用sed、xargs等工具,Perl语言也始终与我无缘。
反观之下,我却能轻松掌握几乎所有尝试过的“传统”语言——从80年代的Basic和C,到近年来的Dart和Go皆是如此。
若我精通sed、awk、grep和xargs,是否意味着我曾是系统管理员?
若你精通上述工具却 不懂 C或Java等“传统”语言,那确实会被人认定为系统管理员。这正是GP所指的背景——那些只懂shell脚本却不懂其他语言,初次接触Perl的人。
若你正在寻找介于“bash脚本”与“专业开发工具”之间的趣味可定制工具,强烈推荐尝试babashka。
它让你用clojure编写shell脚本。babashka本身是单一可执行文件,无需JVM占用资源或启动时间。内置库包含各类精巧工具:解析器、服务器、 卓越 的异步功能(不过我认为Clojure在异步领域堪称语言之最,此处难免有偏),以及HTTP相关功能。所有功能均支持宏编写和REPL交互。堪称脚本开发者的梦想,当需要正式部署时,还能直接部署到JVM环境!
我赞同。Perl作为从*sh和awk进阶的语言确实合理。
而且当时的社区氛围对新手很友好。我读过的Perl书籍鼓励避免编写过于简洁晦涩的代码,邮件列表也总能获得有用的解答。
如果我的命令行管道变得过于复杂,我偶尔还会用到Perl。
Perl该不会是你最早接触的语言之一吧?我坦白承认自己只摸索了几个月;或许明年此时,我会对当初留下的评论感到困惑,仿佛那是另一个人写的。
> 介于“bash脚本”和“真正的开发者”之间。
有位同事给了我绝妙的见解:“至少不是用Bash写的!”
没错,这是我学的第一门语言。由于我较早接触互联网,14岁时就发现了IRC,并从许多Perl书籍作者或社区知名人士那里学到了很多。
这无疑是我建立技术认知体系的关键因素!
直到此刻才真正意识到,当Larry Wall和Randal Schwartz告诉你“RTFM”时,这种态度确实以某种方式塑造了你早期的成长轨迹。
不过我从未自诩为开发者或程序员。我能掌握足够的语法快速搞定临时方案或搭建MVP演示创意,但那些“硬核”开发工作还是交给专业人士吧——他们比我强太多了。
虽然不是你回复的对象,但我也有同感。Perl同样是我的入门语言,它深刻塑造了我的编程思维模式——让Python显得过于僵化,却让Ruby倍感亲切。在学习掌握某个领域时,环境的限制性确实能塑造未来的思维方式,这点值得探讨。
当然有人会从某种语言起步,后来发现更契合自己的语言。我只是在分享自身经历中的感悟。
大学时教授编程语言课程的学者坚信萨皮尔-沃尔夫假说同样适用于编程语言,即语言会影响思维方式。
这似乎与艾弗森1979年图灵奖演讲《符号作为思维工具》有所关联(https://www.eecg.utoronto.ca/~jzhu/csc326/readings/iverson.p…)(https://news.ycombinator.com/item?id=25249563)
我最近才了解到这件事,大概一个月前。这对我来说很有道理。
> 某位同事给了我一个绝妙的视角:“至少它不是用Bash写的!”
真希望消亡的是Bash。作为行业,我们需要做出更明智的选择。
确实。要我下载安装Bash……我才不干!
我写Bash脚本纯粹是因为它无处不在。
没有任何东西能取代Bash的功能。几十年来人们都在尝试。接受bash能与任何工具和谐共存的事实你会更快乐——这正是它永不消亡的根源。
命令行操作以文本为核心,而bash是其上层的元框架。借助curl、jq和awk,几乎能为任何API快速搭建MVP客户端。若用Python或Go实现相同功能则复杂得多。
加上nc和while循环,你就能搞定服务器端!
>它永远不会消失
切特·拉米自1990年代初成为Bash主要维护者,此后所有Bash更新(及Readline)均由他独立完成。这对于百人团队已是艰巨任务,更遑论单枪匹马。
我已然成为它的拥趸(尽管曾为应对其数不胜数的怪癖而苦战良久)。
至少你们有Bash脚本。我多数同事写的是tcsh脚本 😐
(没错,我一直在力推Bash或posix sh)。
> 其中部分特性我认出是时代的产物,当时简洁性至关重要
这恰恰是突破束缚却仍秉承其精髓的产物。Perl作为“功能更强大、限制更少”的sed/awk替代品,其根源决定了它 必须 支持
perl -pi.bak -e oneliner file这类命令——正如sed所做的那样。由此核心需求延伸,它所做的一切至今仍遵循此道。即便在Perl5鼎盛时期,简洁性已非必要,但sed兼容的基因始终是语言设计者的关注焦点。需要学习才能使用语言并非糟糕的设计。我看到Haskell程序时觉得神秘莫测,只因未曾钻研,但绝不会因此断言这是糟糕的设计。
是的,有人会编写晦涩难懂的Perl代码,也有人热衷于Perl高尔夫编程。正如存在以不可读代码为乐的IOCCC竞赛,这并不意味着C语言就该被扔进垃圾堆。关键在于编写可读性强的代码,无论使用何种语言。
90年代末选择学习Python还是Perl时,Perl表达式的上下文敏感性曾让我深感不安。在我看来,这是Perl最致命的语言设计缺陷。虽然Python也能实现上下文敏感表达式(例如通过运算符重载),但必须刻意为之。而在Perl中,这类表达很容易被误用,导致严重错误。在我看来简直是自虐行为。
但大多数Python代码我都能一目了然地理解其功能。Perl代码则需要查阅大量资料。
– 为什么文件中间会出现单行代码
1;?–
$_是什么?– 这个并行执行管理器似乎并未明确定义需并行执行的代码,它究竟如何运作?
– Perl文件开头的BEGIN代码块有何作用?为何必须存在?
– qx、qw、qq 究竟在做什么?
– 当 chomp 单独出现在一行且未带参数时,它会执行什么操作?
重申:Python 语法更接近你熟悉的模式,因此使用起来更顺手。
$_对未接触过Perl的人而言难以理解,但初次见到Python装饰器的人也会有同样困惑。Python中“else: do after a while”循环的作用?只有懂Python的人才知道(我怀疑多数人也不懂)。各种引号运算符同样容易掌握。相比之下,Python的yield from语法同样简单,但语义却复杂得多。
BEGIN?花60秒读懂它的含义。若你懂awk,就无需如此,因为它直接借鉴自awk。
> BEGIN?花60秒读懂它的含义。
没错,这正是症结所在:它增加了你必须额外研读的认知负担。
当文件里出现60个这类细微怪癖时,你就会突然发现自己耗费一小时处理Perl的怪癖,而非 真正调试 那位退休同事十年前写的晦涩脚本。原本5分钟就能修复的问题,却因Perl变成了65分钟的折腾。
大多数编程语言的语法结构大同小异,少数语言特有的怪癖通常也能从上下文中推断出来。这意味着熟悉任何编程语言的人,都能在一定程度上阅读、调试并修复用其他语言编写的代码。而Perl晦涩凝练的语法让这种跨语言协作几乎成为奢望。将一个有缺陷的Python脚本交给日常使用JavaScript的开发者,他们很可能能修复它。但将同样有缺陷的Perl脚本交给同一位JavaScript开发者,他们很可能完全摸不着头脑。
这种特性使Perl成为技术债务。它几乎找不到真正最适合的天然领域,因此经验丰富的Perl开发者极为罕见。任何用Perl编写的脚本,最终都可能需要由非Perl专家阅读——这比阅读其他语言的脚本困难得多。结果就是,你手头的Perl脚本本质上是颗定时炸弹:既无法维护,最好直接替换掉。
问题不仅在于“阅读文档”,更在于不同语言采用的概念/构造差异。Python虽经年累月不断扩充,但我认为其丰富度仍远不及Perl。
好吧,我从未见过这种语法,但它确实如你所料——与“if”语句后的行为完全相同。
以下语句是等效的:
以下代码同样等效:
鉴于Python对字符串前缀符号的偏爱,前文评论者应该能轻松接受这种由单字母操作符决定后续令牌解释方式的晦涩设计。
关于BEGIN语句
AWK需要BEGIN语句的唯一原因在于其隐含的数据循环机制。据我所知,Perl拥有显式数据循环,因此无需BEGIN语句。
天啊,Perl不是有隐含的数据循环模式吗?唉,现在我正翻Perl手册页查证。
更新:果然有,-n或-p参数
若觉得这还不够糟,试着在不懂英语的情况下学习Python这类冗长语言吧——while、for、if、else、break这些词对你而言全是天书,写出的代码简直是英语残片和母语碎片的怪异混合体。我有个假说:简洁性利于普适性。若不懂英语,像 $_ 这样的符号反而更易理解——它看起来就像简洁怪异的数学符号。
没错,Perl的设计初衷确实不要求完全的新手能在零基础情况下直观理解代码。它确实存在学习曲线,而这正是Perl创造者们完全预期的。是的,你必须掌握上述惯用法,但它们终将化为本能。对我们许多人而言,这种模式在脑海中豁然开朗,简洁性带来的价值远超代价。用极少字符就能表达丰富功能,若你愿意投入学习,就能迅速领悟——因为常见模式已被转化为语言中熟悉的抽象概念。
然而随着行业扩张,各种背景的人涌入这个领域,对怪异/简洁风格的包容度逐渐降低,转而青睐明确/冗长/易懂的表达方式。这或许终归是好事,但总让人觉得像街角那家摆着怪异腌菜的夫妻店,后屋还有位老奶奶看店,如今却被缺乏灵魂的连锁便利店取代了。
> 然而随着行业壮大,当各种背景的人汇聚于此,对古怪/简练风格的包容度与需求逐渐消退,取而代之的是对直白/冗长/通俗易懂风格的偏好。或许这终究是好事,但确实让人感觉像是街角那家摆着怪异腌菜的夫妻店,后屋还有位老奶奶看店,如今被缺乏灵魂的连锁便利店取代了。
这是个绝妙的观点,此前从未见有人如此论述编程语言。
作为在Perl鼎盛期后入行、从未学习使用该语言却师从Perl资深用户的程序员,我深感Perl蕴含着前企业化/无政府主义/朋克精神,这与Go语言那种“为企业而生、由企业打造”的风格截然相反。Perl虽古怪,却充满生命力(即便社区已式微)。反观Go语言,却显得死气沉沉,毫无灵魂。
坦白说,Perl中的
$_和“函数未传入参数时的默认行为”设计相当巧妙,理解起来也不算困难。我认为许多语言都该借鉴这种“默认变量”机制。$_正是让我对Perl却步的原因之一,因为相同语法在不同上下文中的含义截然不同。
当时《实用程序员》刚开始推崇Ruby,于是我选择了它而非Perl,从此便沿用至今。我厌恶PHP,也不喜欢Python的空格语法。我从未接触过Ruby on Rails。不过我的首个交互式网站,本质上就是用CGI/Perl实现的“Hello World”按钮。
但通过阅读他人Perl脚本学习编程,远比学习当时的新兴语言困难得多。
如今年过半百,这些都已无关紧要。记得年轻时我曾固执己见,执着于“这个比那个强”——这不过是成长历程与文化环境的产物。这也解释了为何近期出现CSS最小化实现FizzBuzz的帖子:我们这么做是因为能做到,而非必须如此。
要真正理解Perl(即便不必接受它),你需要一个实验环境。
当你意识到Perl深深植根于UNIX命令行工具、UNIX规范及某些UNIX shell默认设置时(当然也有例外),它的一些特性就会变得合情合理,例如:
$_遵循了shell变量的精神(如$*, $@, $!等,在Korn、Bourne系中广泛使用,但在C系中则不然),但它要么被重新定义,要么——更可能的情况是——通过掷骰子从一堆空闲字符中随机选取而来。这就像古埃及人借助精密起重机建造金字塔,却用高能粒子束蒸发工具,让后世惊叹“他们究竟如何完成这项壮举”。这正是Perl的主要争议点之一。
Perl最初是作为awk的改进版本诞生的,而BEGIN正是awk中频繁使用的语法结构,例如:awk ‘BEGIN { IFS=":" } { …执行操作… }’
它遵循UNIX实用程序的标准约定:当未指定输入文件名时,预期输入来自标准输入流(文件描述符0或shell中的<file-in>)。因此,当chomp未接收<FILE1>时,它会从标准输入进行截断操作。
你竟因需要查阅陌生编程语言的关键词用法而恼火?若你认为Python永远清晰明了,我敢保证(作为精通Bash、Ruby、Go且曾长期使用Perl的人)——事实并非如此。
关键标准似乎不在于能否用它写出晦涩代码,而在于该语言能否让你用清晰可读的代码完成多数任务。这两者并非互斥。
希望我转述得准确。
就是这样。我曾用Perl的面向对象特性编写过大型系统,效果很好。
唯一让我始终无法掌握的是正则表达式——不是表达式本身,而是实际应用的代码行。
Python就简单多了,只需定义正则表达式,然后调用函数即可。我本该花几天时间在Perl里写个封装函数——这样反而能节省整体时间。
至于单行代码,我原本是APL程序员,这不成问题。但写单行代码实在不是好习惯,更该采用可维护的形式拆分操作,让逻辑清晰可见。
如今我尽量避免使用lambda表达式——命名函数才更便于后续调用。
> Python就简单多了,定义正则表达式后直接用函数处理即可。我本该花几天时间用Perl写个封装函数——那几天投入反而能省下更多时间。
有意思。我尽可能避开Python,但最讨厌它处理正则表达式的方式。Perl的实现(无论是搜索替换还是条件判断)都直观得多。
没错,Perl简直像是未见大学——呃,我是说伯克利语言学系的产物。
我曾喜欢它,觉得符号标记变量的方式很俏皮。但当处理深度嵌套的数据结构时,解引用数组和哈希的过程变得繁琐又烦人。如今我更偏爱Ruby。相比之下,Perl确实像咒语混杂着C语言和Posix元素。但若想感受智力飞跃,我宁愿写些Scheme代码,谢谢。
>>现在不得不学点Perl了,虽然没参与社区交流,但它确实_感觉_像是巫师为巫师编写的语言。
那个年代截然不同。如今耗费数月乃至数年完成的事,当年人们往往数日或数周就能实现。
不仅交付速度与雄心渐逝,那种文化本身已荡然无存。你可曾见过有人在当下打造下一个Facebook或亚马逊?
我记得管理者曾询问Java程序员完成任务需要多久,得到的答复竟是数月乃至数年。但只要找我们Perl程序员,一周就能搞定。
那个时代没持续多久。我常开玩笑说,理想状态下,十年经验的Java程序员相当于一年经验的Perl程序员。这正是多数企业程序员想淘汰Perl的主要原因之一。
> 不仅交付速度与雄心渐逝,那种文化本身已荡然无存。如今你还能看到有人打造下一个Facebook或亚马逊吗?
难道不是吗?人类智能/克劳德工具的开发速度简直疯狂,AI炒作让我频频想起90年代。
“替代性活动”这个词浮现脑海——特指某些人热衷耗费时间却毫无实际价值的行径,只为自我感觉良好。
人们登顶珠穆朗玛峰(靠后勤保障)
> 我始终觉得Perl“社群”充满僧侣巫师之类的荒诞设定,令人极度反感
Perl社群通过CPAN向世界推出了首个语言模块仓库。从此告别手动从FTP服务器搜寻tar包的时代
作为编程语言,Perl极具表达力——这对于一次性脚本堪称完美,却对需要共享或重读的代码而言灾难性。在纯文本处理领域,Perl至今无人能敌。当其他语言使用Perl兼容正则表达式时,我总觉得语言本身成了障碍。
虽然能写出可读性强的Perl代码(毕竟“通往地狱的路有千万条”),但它不像Go(语言体量小)或Python(通过约定和文化定义“Pythonic”标准)那样强制规范。
CPAN的灵感源自CTAN(Comprehensive TeX Archive Network,综合TeX档案网络)。
Perl犯了个错误,这种语言过度追求表达深度,而在编程语言中,这只会导致千百种写法表达相同功能——其中大概只有两种读起来还算顺眼。
Python(此处刻意使用“曾是”)则截然相反,它贯彻“每件事只用一种方式”的理念,坚持追求更简洁的代码,哪怕这意味着更冗长的表达。
你当然能写出优雅的Perl代码,但必须主动选择这样做;而Python从一开始就引导你走向优雅。
尽管我厌恶用空格控制流程,但这种设计确实能确保代码始终保持合理缩进——即便是刚接触语言的新手也不例外。
更糟的是,Perl(以及后来出现的PHP、JS、 Python)都背负着“新手语言的诅咒”——许多人未经训练就直接上手(毕竟在mod_php革新网页托管模式前,它曾是网页开发的唯一合理选择),在这种既不限制用户操作又缺乏规范引导的语言里… 最终催生出那些丑陋的单行代码和充斥噪音的脚本。
> 所谓“完成一件事的方式只有一种”
人们常从《Python禅》中截取这句话(正如你所做),刻意断章取义地将其与Perl的“TMTOWTDI”(完成一件事的方式不止一种)对立起来,而这种对立关系从未真正存在于Python的哲学体系中。
Python禅的 原文 是:“实现某件事的方式应该只有一种——最好是唯一一种——且应当显而易见”(省略部分以斜体标注)。
这是Python自我标榜的故事。然而,非日常使用者不断发现:这种“唯一性”仅限于单一版本的Python。随着时间推移,实现诸如遍历映射这类冷门操作时,竟会出现多种相互冲突的实现方式。
…正因如此我用了“曾经”。当前语言的发展方向大多背离了“Python禅”。
Python从未真正遵循过《Python禅》,这正是我对其不满之处。例如“显式优于隐式”简直是个冷笑话——Python明明默认将非布尔类型当作布尔值处理。
我不了解整个Perl社区的情况,但听过Larry Wall的几段访谈,他给我的印象就是个沉迷于编程乐趣的极客。我挺喜欢听他说话的。
我虽非Perl程序员,但这基本就是我接触过的所有Perl程序员给我的印象。
此外,拉里·沃尔的《勤勉、耐心、谦逊》[0]堪称我最喜爱的编程类文章之一。
[0] https://www.oreilly.com/openbook/opensources/book/larry.html
拉里更应因开发“patch”而非Perl而被铭记。若没有这种对修改源文件模糊应用补丁的概念,就不可能有“git rebase”或“git merge”。
拉里曾是(想必现在仍是,不过我已脱离那个圈子)一颗瑰宝。他是编程界的“怪人阿尔”——风趣幽默且心地善良。
但那些记得efnet #perl频道常客的人(这里不是求助频道),肯定感受到过冷漠。我可能也曾参与其中,因为那便是当时的文化氛围!这里是高手聚集地,你来问问题算什么?
和cms一样,我也不愿点名道姓,但那些人当年在Perl圈绝对是赫赫有名。
社区里也有许多杰出人物,他们在我90年代开启技术生涯时给予帮助,至今我仍与其中几位保持着深厚的网络友谊(对已故的某些人更是怀有美好回忆)。但确实也存在混蛋。
我亲身经历的 Perl 圈子多是退伍军人出身,不拘小节又随性而为。反观 Java 和 .NET 圈子则拘谨刻板,充满书呆子气。
个体很少(并非绝无可能,但确实罕见)是问题的全部根源。正如作者所描述,群体行为才会形成反馈循环和文化强化效应。有时这会形成良性循环,但更多时候,水井终将被毒害。
我认为当你长期沉浸于某个生态系统时,这种模式确实有效。
但偶尔需要与之交互时总会遇到障碍。Bash也是如此:该用[还是[[?分号该放哪儿?if then用fi结尾,而while循环用done(而非elihw)。-eq还是=?函数带()却无参数。
当你只写Bash/Perl时这些规则或许合理,但初学者难免望而生畏。
当然Python的元编程也能玩得很花哨,JavaScript的原型机制同样令人困惑。而Ruby(尤其是RoR)堪称冠军——变量在执行行当下的解析机制,让调试代码块变得极其困难。
代码中的魔法越少越好。
>我敢肯定,当你只写Bash脚本时这些东西确实有道理
其实不然。Bash因历史遗留问题而以语法混乱著称。你终究会习惯它的怪癖,但这些特性依然荒谬,某天可能突然反噬。Perl代码可能(甚至必然)变得难以阅读(毕竟它被戏称为“只写不读语言”),但至少更具健壮性。
你应该知道这些知识都能轻松在网上学到吧?确实,一种需要兼容四十多年前脚本的语言难免存在混乱之处。这就是它拥有如此惊人生命力的代价。
关键不在于这些怪癖无法掌握,而在于它们让语言变得极其难用。
我曾钟爱Perl,这是我作为硬件工程师日常使用的首门语言。近年转用Python后,最怀念的便是用正则表达式捕获实现单行if语句的便捷性——Python长期无法实现这种操作。虽然海象运算符有所改善,但仍不及Perl简洁,不过已更接近了。
看到这个让我会心一笑——毕竟Python对蒙提·派森的致敬情有独钟,比如奶酪店梗等等。
当年(2000年代中期)初见这些梗时我还觉得有趣,但后来它们频繁出现的频率和毫无顾忌的程度确实让人有点尴尬。不知年轻一代是否还记得蒙提·派森——在我那个年代,《银河系漫游指南》早已被遗忘,即便“42”这个梗还流传着。
作为外籍人士,我学语言读文档时根本不认识蒙提·派森,这些梗也完全没注意到。对我来说大概就是噪音吧。
现在的孩子都把42分解成6和7了(语气带点夸张,还比划着)
这是你编的?要是真这么说,太棒了!
6和7?不,我家孩子每天要说上千遍呢。然后不知为何总跟着说41!搞什么鬼!我喊过无数次42!还试图告诉孩子42在文化和科学上的重要性。据我所知,它的因数是2、3、7。
67和41是TikTok/Z世代的行话。
67代表“无所谓”“我不在乎”,或者循环使用67!
41表达震惊或难以置信——“太疯狂了”“不可能”之类的。
> 41!
这可是个超大的数字!
老兄这不尴尬,只是傻气。
假装使用严肃成年人语言才叫尴尬。
我同意,但别忘了当今程序员平均都是刻板的职场人,个性就是MacBook上贴满Node.js贴纸——和团队里所有人毫无二致。
他们忘了Perl之类的语言是70年代那些吸了太多LSD、留着长发马尾的人写的。
我斗胆猜测,拉里·沃尔——这位虔诚的福音派基督徒、牧师之子——在70年代可没在“觉醒、接轨、出世”。
我始终觉得Perl纯粹丑陋:某些设计过于花哨(比如在标准输入上遍历正则表达式匹配结果),某些又极其愚蠢(变量语法、那糟糕透顶的OOP系统)。相比之下Python简洁优美且设计周全。即便两者社区对调,我仍会选择Python: 99%情况下我只需阅读文档,极少需要与社区互动。正如文章所言,Python本质上并非面向爱好者的语言——它主要用于辅助性任务。
语法问题只是表象。深层存在真正的问题:
单一实现方案的性能低下。
仅有单一实现方案。
泄漏的引用计数垃圾回收机制,但“幸运”的是引用语法如此笨拙,没人会做复杂到真正需要它的事情。
在面向对象语言席卷全球的时代,那些被生硬附加的面向对象特性从未获得应有的重视。
多数高手纷纷投奔Perl6——这种“开发”多年却始终没有实际实现的新语言,让他们彻底脱离现实。
> ‘幸运’的是引用语法如此笨拙,以至于没人做过足够复杂的事来真正体现其重要性。
这话让我发笑。但实际操作Perl引用时,却让我想哭。
> 我始终觉得Perl“社群”充满僧侣和巫师的荒诞设定,令人极度反感。
Ruby主义者和Python主义者的对立也好不到哪去。
把编程语言当作反主流文化的生活方式选择,用年轻人的话说真是“尴尬到爆”。
这种情况会持续下去,直到我们开始用某种人工智能驱动的界面编程——即便那样也未必能改变现状。
人类具有部落属性,而人力资源部门招聘时只看重特定要点,因此当人们需要求职时,都想证明自己属于正确的部落。
我认为“Pythonista”这个词在2000年代并不流行。Python历史悠久,直到最近才逐渐成为一种“潮流”。
绝对存在这种现象。
> Ruby主义者与Python主义者的对立同样糟糕。
嗯,表现形式不同。Ruby群体常因其工具能给程序员带来多少乐趣而略显自满/情绪化。原文对Perl的描述很精准:Perl群体常表现出小团体主义、傲慢和防御性。Python 用户有时则表现出居高临下或过度轻视的态度。
而所有这些社区中最显著的差异在于:社区中存在这些病态行为的人数比例,与绝大多数正常用户之间的差距——这些用户在使用语言时分享技术或代码,回答问题时从不耍混蛋。
Perl让我失望之处在于,其社区及我认识的用户更容易显露这些糟糕行为。坏苹果比例更高——整体而言虽不多,但足够引人注意。
奇怪,或许因为我是70年代的孩子又痴迷D&D,这种特质恰恰是我最初钟情Perl的原因。
更重要的是,Perl让我得以用一种暴露所有UNIX API接口的受管语言在UNIX环境中进行安全编程,仅在需要额外性能或Perl未完全支持的底层功能时才切换回C语言。
当然,我也是Haskell、C++、Scala、Idris等“魔法语言”的狂热拥趸。
我从未在生产环境用过Perl,但我的编程启蒙是PHP——依我之见,PHP入门门槛极低,这也是我选择它而非其他语言的原因之一。
说得对,这话出自一个至今仍偶尔用Perl处理文本的人之口——当awk/sed力不从心时尤其如此。试试在终端输入:
你会看到这段代码:
天啊这简直是另一个时代的产物…但让我告诉你,若能驾驭awk/sed或Perl这类单行命令,你就能用更少的资源实现相当实用的功能——这比用Python编写同等功能的代码更具优势。当你需要反复处理海量数据或在有限硬件上运行时,这种优势就尤为重要。
第一次看到关于Perl的这种评价。这是Perl鼎盛时期的亲身经历,还是从某些表述推演出来的?
我曾痴迷Perl及其晦涩特性。当年它就像黑魔法般神秘。它本该成为如今Python的模样。
实际上Perl曾是如今Python的模样——当时首选的脚本语言
这正是我当年对Perl的感受(2000年代全职开发四年),也是如今对https://raku.org(即Perl6)的体验。约18个月前我曾尝试在此收集类似感受:
https://rakujourney.wordpress.com/2024/05/22/perl-love-notes…
令人遗憾的是,Perl因提前宣布不兼容升级的错误而遭人唾弃。我理解人们的迫切心情。但如今Raku已然问世,我认为值得重新审视。
我从未接触过这些,对我而言Perl始终是“内置文本处理功能且无字符串插值陷阱的Bash”。当需要编写一两页长的实用脚本时,我总会选择它。Python总爱废弃功能(加上2到3版本的灾难性更新让我吃尽苦头),所以我只用它处理确定会长期维护的项目。Perl才是编写永久不变的shell脚本的不二之选。
Perl是系统管理员的语言。系统管理员与开发者之间“始终”存在着这种紧张关系。
在我当时作为开发者的认知里,会业余地将这些无稽之谈心理分析为某种维护自我形象的自卑情结。不必要的复杂性竟也能成为特性!
而如今我们都是开发者了!
> 某种旨在维护自我形象的自卑情结
或者用年轻人的说法:炫耀,但少了性感意味。
(顺带一提,这让我想起莫菲的名言:
下棋是绅士的标志,下得好棋则是虚度光阴的标志。
这句话对我来说并不太有说服力。两部分都值得商榷。
仅仅会下棋根本不算什么高标准。多数六岁孩童一小时就能学会。难道华盛顿广场公园的棋局骗子都是绅士?
我认为下棋技术高超并非缺陷。这可能只是某人的爱好,未必意味着他们像鲍比·费舍尔那样陷入疯狂。
(我虽会下棋但水平平平,所以这句话两部分都与我无关)
2000年代Python同样是系统管理员常用语言。
编辑:不过我明白你的意思,2000年代末谷歌SRE团队确实更倾向使用Python而非Perl。
我认为即便在今天,Perl作为系统管理语言仍比Python更流行。2000年代末确实如此。或许谷歌是特例,但整个行业范围内Python几乎无人问津,Perl却无处不在。
我的经验:
系统管理员主导的企业(通常基于Sun架构)常使用Perl。
开发者主导的企业则采用其他语言,运行在更经济的X86架构Linux系统上。
(90年代)确实如此,但后来发生了变化。
作为亲历过这种转变的人,我们曾广泛使用Perl管理约30台Solaris和Irix工作站,其表现堪称卓越。
当时Guido仍在弗吉尼亚州雷斯顿的CNRI工作,我们曾在当地Pyggies(Python用户组)多次讨论将工作迁移至Python。虽然我们主要使用C++/Java,但Perl完美填补了所有其他“缝隙”。
Python当时的库支持还不足以满足我们对“瑞士军刀式链锯”的需求。尽管如此,当时已能预见它终将实现这一目标,而我尤其着迷于其“唯一正确方式”的编程哲学——即便在字节码层面亦是如此。
> 以上内容纯属玩笑,
确实如此。
记得90年代我在IRC提问时,有人让我“RTFM”(去读手册)。幸好我当场追问对方是否认真。对方当然回答开玩笑的!
随后他们私信发来隐藏链接,里面是Perl高手的图像地图——我能预约免费见面喝咖啡,作为新手入门。我当时很怀疑——谁会在意网络上某个随机菜鸟?!事实证明,Perl在乎。那次面对面交流让我浑身起鸡皮疙瘩,至今想起仍心潮澎湃。这段经历极大增强了我的信心,更成为我踏入编程领域的关键阶梯。
毫不夸张地说,若非Perl注重社区拓展,我绝无可能担任软件工会2142分会主席。
就像那位魔法导师在我试图支付那杯咖啡时所言: Perl it forward!
搞不清这算真实经历还是绝妙玩笑。
我得了解更多关于软件地方分会2142的事。
公平地说,Perl的衰落源于它在巅峰期后涌现的其他语言面前缺乏竞争力。人们总会转向更优的选择。
Perl是种 伟大的 语言,如同Scala和Haskell的伟大之处:作为公开实验性的语言,它们尝试了各种新奇非常规的方法,并取得了不同程度的成功。“实现方式不止一种”正是Perl的座右铭,我认为这源于其大胆的实验精神。
不过就实用性而言,Perl并非 顶尖 语言。正如面包板上的临时装置不适合作为最终硬件产品,但若没有它,以及在调试过程中发现并解决的错误,就不可能设计出精美的消费级PCB。
> “实现目标不止一种方式”是Perl的座右铭,我认为这源于它大胆的实验精神。
Perl允许每位开发者以独特方式编写代码。
而每位开发者确实如此。
当我不得不阅读一个由十位开发者历时十年编写的文件时,这种情况就变得非常痛苦——每位开发者都有不同的观点和技能水平。
我猜到2026年,将会有11位开发者耗时11年编写代码。我向后继者致以诚挚的歉意,也向前辈们送上诚挚的去你妈的。:)
直到2010年代我才领悟到:代码异味的主要代价体现在调试环节。当调试升华为艺术时,关键不在于按概率排序所有可能原因,而在于验证的便捷性。
验证成本低廉的环节应优先排查,除非其发生概率极低。这相当于将数字博弈从追求最大切割面,转向快速完成的小块处理(更重要的是,这种处理对思维消耗更小)。
代码异味会搅浑水。因为有烟必有火,代码异味往往暗藏漏洞。正如托尼·霍尔在图灵奖演讲中所言:要么没有明显的漏洞,要么根本不存在明显的漏洞。
因此我最终选择简化变更流程,然后实施简易变更——因为每周代码都在增长,若想让后续人员理解整体架构,现有代码必须更简洁。
Perl似乎完全没意识到这点。
正是如此。Perl的精髓在于实验精神——按自己的方式尝试,探索编程的新方法。这种能力对科研探索、艺术创作或娱乐消遣固然绝妙,却不太适合工业化生产。
正因如此,在1980年代末至1990年代初互联网爆炸的黎明期——或者说引爆阶段——Perl与同样倡导DIY魔法价值的Lisp、Smalltalk一样,堪称绝配。但当行业真正成型并走向成熟后,Java、PHP和Python这类更利于团队协作的语言便开始取代它们。
> 到2026年,将有11位开发者耗时11年完成编写。
或许,一款持续活跃维护达11年的工具,本身就是极致成功的证明。
我不认为是“巨大”。更准确地说,它对公司运作至关重要,因此投入了足够资源维持运行,但资源量不足以考虑重写或重构以提升可维护性。
它本该有一本像《Perl精粹》那样的优秀指南。
当团队成员都采用相似风格编写时,Perl表现得无可挑剔。Mod_perl运行迅捷,我曾钟爱Perl。
直到Django横空出世,接着是Numpy,Perl便败下阵来。但Python至今仍慢得离谱……
推荐Damien Conway的《Perl最佳实践》和Chromatic新近出版的《现代Perl》。两者均有平装本,且我认为都可免费获取电子版。
我更进一步说:抛开Perl特有的部分,康威的《Perl最佳实践》堪称有史以来最优秀的通用编程书籍之一。
书中蕴含大量适用于任何编程任务的宝贵建议,从变量命名、测试、错误处理、代码组织到文档编写等无所不包。归根结底,关于编程职业的永恒建议与具体语言无关。
说真的——从这里开始——Python的编写效率简直慢得离谱。谁还有这种时间?
编写慢,运行慢,还抛出空格错误。真没想到它能发展到今天。
这描述简直就是学术界的写照,不过对企业来说可能反而是卖点。
类似地,随着行业成熟,我们从由魔法师团队打造产品的时代,转向了由“够用就好”的开发者组成的团队——可互换、易上手。Perl文化过分强调技艺精湛,最终与多数企业文化格格不入。
遗憾的是,作为前Perl开发者,其他环境总让我觉得索然无味。效率或许更高,但依然乏味。在新生代语言中,Nim确实具备独特魅力。至于当Rust和Go语言根基稳固后,它能否获得广泛采用,则是另一回事了。
它并非 卓越 的语言。
但它确实是 重要的 语言。它在编程文化与产业中留下了深刻印记与影响,绝非等闲之辈。
我从Larry Wall那里领悟到的核心智慧,似乎与我作为局外人观察到的Perl文化相悖。这始终让我对Perl有些困惑。
简而言之:让理想的使用方式成为最简洁的实现途径,而让晦涩的功能变得冗长繁琐。
这本可成为整个社区的基石,却被他们贬低为代码高尔夫。
他们就不能在向所有用户发布功能前,先摸索出一种像样的实现方式吗?我试用过Scala,最终认定它毫无必要地复杂。
Haskell我不了解,但用过同样纯函数式的Erlang。无论使用多久试图欣赏其优雅,都清楚这并非普遍便捷的编程方式。不过它设计得很好,不像Scala那样。
依我之见,Erlang根本算不上函数式语言。函数式语言不仅需要不可变值,强迫用户保持变量不可变更是个错误设计——Elixir修正了这点。实际的Erlang代码本质上是用不可变值编写的命令式代码,像许多现代语言那样偶尔调用函数式编程借来的特性(如
map),但它不符合现代意义上的函数式语言定义。若你开始学习Haskell,会发现它能阐释许多Erlang未曾教导的函数式编程精髓。你还会意识到自己已跨越了掌握Haskell的主要障碍之一——不可变值的编程实践。这极大降低了对整个语言体系的消化难度,使其相对容易掌握。我之所以说这是条相对轻松的路径,是因为我曾亲身践行。
> 依我之见,Erlang根本算不上函数式语言。
你这是怎么想的?
函数式编程的本质在于函数具有`数据 -> 数据`的形式而非`数据 -> 空值`,弱化基于对象的身份概念,并将函数视为抽象的一流工具。当前已有足够多的动态函数式语言证明,这些特性与静态函数式语言具有共通性。难道Clojure不算函数式语言?
> 函数式语言不仅需要不可变值,强迫用户保持变量不可变是错误的设计,而Elixir修正了这一点。
Elixir中所有数据都是不可变的。绑定关系可重新绑定,但被引用的数据保持不可变,这与Erlang完全一致。
Elixir仅将
x = 1; x = x + 1重写为x1 = 1; x2 = x1 + 1。不可变值语义得以保留,表达式间任何涉及x的操作都不会改变其值。> 实际应用中的Erlang代码本质上是用不可变值编写的命令式代码,如同许多现代语言那样,偶尔会调用“map”等借自函数式编程的概念,但它并非现代意义上的函数式语言。
在接触Erlang/Elixir之前我曾大量使用Scala,虽然Applicative和Monoid给我带来不少乐趣,但我不确定它们是否构成函数式编程的精髓。它们无疑是重要组成部分,但并非全部。
我确信函数式编程正是你所描述的。若非如此,我宁愿称其为“无变量语言”。
若要编写快速开关脚本,使用魔法变量等机制尚可理解。但若要编写长期维护的代码?请勿采用这些手段。不过Perl 5引入引用机制时,本可借此简化语法。
通过类比进行推理?
并非如此。它的大胆设计并未服务于任何创新目标。例如Haskell将函数式编程推向极致,Scala则试图成为更擅长并发的进阶Java。
Perl是早期动态(垃圾回收)“脚本语言”,但在这方面并不比同时代的Python更先进。
它因糟糕的设计选择而拥有怪异的符号。
它拥有大量全局隐晦变量和隐式变量,同样源于糟糕的设计选择。
它采用奇怪的显式引用机制,只因设计者错误地将嵌套列表扁平化为单一巨型列表。
它恰恰是你所否认的那种语言——至少在Web和系统管理领域,它并非优秀的实用通用语言。直到更优秀的竞争者出现并构建起完善的库生态系统。
“按我所想执行”的表象下隐藏着太多复杂性。例如标量与数组上下文的微妙差异:
更糟糕的是:
据说这曾让某高中生陷入麻烦[^1]。
[^1]: “It’s all about context” (2001): https://archive.ph/IB2kR (http://www.stonehenge.com/merlyn/UnixReview/col38.html)
我认为最可能的情况是:* 某个了解原理的开发者在代码中刻意使用此法获取首行内容* 刚入门的新手直接复制代码,误以为这是将命令内容赋值给变量的正确方式
本质上是在抱怨故意错误使用特性,因为犯错者从未真正掌握这门语言。
my($var1, $var2…) 是从数组中多变量赋值的方式。
仔细看就会明白其合理性。Perl 没有多重返回,但若需要返回两个变量的函数,用以下方式实现非常简单:
Perl根据调用者返回不同类型的特性确实容易混淆,但
返回行数据在此场景下完全合理(调用外部命令解析其输出时,通常需要按行处理,这样就能直接执行:
即可“直接运行”。
现在你可能会问“为什么要设计这些快捷方式?”。其实Perl开发时犯过一个重大错误——它试图取代sed/awk成为单行命令的替代品,因此语言里充斥着各种“巧妙的操作捷径”,用它在命令行快速编写临时单行命令确实很爽… 但人们试图在实际代码中沿用这种“聪明”,最终却酿成众人熟知的Perl代码乱麻。
你能够写出这样的代码:
恰恰说明该特性在使用上保持着“一致性”——当你传入数组时,它就会用执行命令的输出行填充数组。
你给它传了数组,它只是按数组处理机制行事罢了。
那就别用底层接口。Perl的语言特性都是即插即用的,所有功能都封装在模块里。改用核心模块List::Util吧。
这和“*”执行乘法、“+”执行加法一样不复杂。有时你只需要学习语言本身。
这并非对Perl的普遍辩护——它确实常令人难以理解——但若你真正尝试编写Perl代码而非强行套用其他语言逻辑,这个例子完全合乎逻辑。*
这里根本无法公平比较 Perl 的用法与多数语言中 + 和 * 的工作方式——恰恰因为多数语言里 + 和 * 功能一致,而 Perl 这里的实现纯属特立独行。
就连 C 语言也因将 * 重载为三种含义(乘法、指针声明、解引用)而饱受诟病!
有趣的是,像这样写:
或者
反而更直白,但我又说不清原因。
这到底复杂或“极其微妙”在哪里?难道是教程第一章的教科书级示例吗?
问题在于快速浏览时很难看清代码的实际行为。
尤其在Perl这类动态语言中,你根本无法预知传递的是整数还是函数——直到代码在完全无关的函数中出错时才发现。
那就用Perl的类型系统之一吧。
https://metacpan.org/pod/Type::Tiny
若你连最初的符号谜题都放弃,就别想做到这点。
我对此毫无异议:要用Perl编程,你必须能理解手册、man页、专家解答——甚至Perl食谱、CPAN或网络搜索。它是个技术工具,是瑞士军刀式的链锯。值得拥有。
你和其他几位评论者恰恰印证了文章观点——Perl文化封闭保守,新手宁愿学习Python、Ruby或JavaScript,也不愿钻研符文含义。
我不认为它封闭,因为各种文档极其详尽且易于获取——只是宣传不足罢了。在我看来这里没有门槛。新手受到欢迎。它很容易学习(对阅读不是障碍的人而言)。
但不可否认,当今世界正沉迷于极简主义。Python凭借极简理念胜出,更因大型软件公司选择它(且不抱怨语法噪音问题)。若想从事专业编程工作,未来多年你都需要掌握Python。
我不确定是否该将JavaScript归入同一类。它恰恰相反:表面简单实则复杂。
但Python确实赢了——它看似简单,又得到谷歌的力推。
如今众多语言都不得不面对Python的霸主地位。这并非Perl/Raku独有的困境。任何语言要取代Python都需付出巨大努力。
我始终对上下文评估机制感兴趣。某种程度上它类似toString方法的泛化版本
这并非复杂性,而是 魔力 。当懒得写array.length时就派上用场。空数组时用if (@a)也是同样道理。
> 它只是相较其他语言不够优秀
我觉得这不过是人们口耳相传的说法,缺乏具体经验佐证。就像有人宣称丰田卡罗拉优于本田思域——事实果真如此?抑或它们本质上只是同类产品的不同形态?两者都能载你前往超市,都可靠耐用且价格亲民。个人偏好与实际优劣本非等价。
确实,我本可以算作Perl圈子里的“核心成员”,但让我转向Python的并非文化因素。
真正促使我离开的是Django及其相关社群。
> 以及相关社群
文化?
我同意,Steve Yegge 在这里阐述得很好:https://sites.google.com/site/steveyegge2/ancient-languages-…
他关于引用机制的论点至关重要。其他动态语言在语法层面很少要求用户区分引用与值。但在Perl中,只有使用引用时才需要频繁使用“->”箭头运算符。因此访问数组内的映射结构或反之,与读取映射或数组中的字符串有着截然不同的语法。
更糟的是,它在生硬的参数传递机制之上,又生硬地堆砌了笨拙的面向对象功能。你必须从魔法数组变量(@_)中移出“self”(或“this”)。
默认情况下,即使尝试读取未声明变量、在条件语句中使用未声明变量或向其赋值,系统也不会发出警告。必须声明“use strict;”才能解决。这本不算难!但这些笨拙的设计层层叠加,如同无数细微割伤。别忘了还得在每个Perl文件开头添加“use warnings;”。
若勉强将这种笨拙语法归因于模仿shell和常见Unix命令行工具,或许能视作文化问题。
但90年代中期任何语言都沾染了作者所说的“RTFM教条主义”氛围,因为当时互联网充斥着系统管理员类型的人群——尤其那些能在Usenet解答编程语言问题的群体,而Usenet正是当时必经的求助渠道。
例如Rails的胜出源于技术优势:相比Perl实现,它更简洁且陷阱更少。Rails兴起时我正用Perl编写网页程序,但很快转投阵营。这并非文化因素使然——Perl本身提供多元选择(可惜Ruby至今未能在Rails之外培育出文化生态,这点确实值得改进)。更关键的是它诞生于2000年代中期,那时人们已能通过网络而非Usenet求助,加之首支Rails演示视频在YouTube发布,这些都助推了其发展。因此Ruby最终形成较弱的系统学派文化,但这更多源于其成功的时机而非成功本身。
> 附加的、笨拙的参数传递
Shell不得不这样做,因为Shell的特性使然——比如在不该出现空格的地方需要空格。Perl比C语言晚了十多年问世,因此没有理由采用笨拙的参数解包机制。
其实有其缘由——Perl 汲取了 Lisp 的精髓(万物皆列表),而众所周知 C 的可变参数机制极易失控。
因此 @_ 机制正是对此问题的回应:Perl 本质上是动态无类型的语言,当时既无 IDE 也无代码检查工具能基于函数签名进行类型检查和重构。
JavaScript长期存在相同问题,最终在ES6中实现了余数/展开运算符。Python虽自诞生就支持可变参数,但直到Python3才引入余数运算符。而Perl早在80年代末就为可变参数提供了展开/余数机制。出于兼容性考虑,Perl沿用了70年代在Bourne shell中代表可变参数的@运算符。
尽管Perl默认会自动展开列表,这点并不特别像Lisp。
Perl曾是(至今仍是)处理文本和Unix风格系统时极具表现力且简洁的语言。它存在于壳语言与通用语言之间的特殊领域。
但shell脚本编写已逐渐成为冷门技能。我认为文章精准指出:Perl因学习难度过高而难以延续其价值优势。Python在该领域虽远不及Perl的表达力,但无论阅读还是编写都更易上手——换言之,它更利于编写可广泛维护的代码。Ruby则颇为相似 (尽管我认为人们严重夸大了该语言本身对语义可理解性的普遍促进作用)
> Perl曾是(至今仍是)处理文本和Unix风格系统时极具表现力且简洁的语言。它存在于shell语言与通用语言之间的特殊领域。
GvR在描述Python设计初衷时也用了类似措辞(近期纪录片里应该能找到具体时间戳)。但Python的目标是成为真正的“通用语言”(更注重可读性与实用性而非艺术性),同时汲取他眼中shell语言的精华。
此后Python经历了诸多变革,事后看来其中不少决策显然是明显的失误。
我们常戏谑计算机科学的艰深难题,但在我看来,编程语言设计(乃至更广泛的软件工程领域?)的真正难点在于:如何兼具审美品味,又该如何处理向后兼容性问题。
我认为这篇文章一针见血地指出,Perl 难以生存的原因在于其学习难度远超其提供的价值。Python 在该领域的工作表现虽不及 Perl 那么——呃——富有表现力,但学习门槛确实低得多。
随着时间推移,应用场景也发生了变化。大量开发者最终转向了 Windows 平台(尽管这种趋势或许正在逆转),而该平台对“shell”的规则和期望截然不同。更不用说Web开发领域——“cgi-bin”遍布各处的时代早已一去不复返。
Shell之所以是糟糕的脚本语言,在于其原始的数据结构和数据流控制机制,使得跨应用程序处理数据时难以管理和操作。换行符问题就是典型例证。
Python作为shell脚本语言同样糟糕,因为管道和子进程相关的语法实在笨拙。
Perl成功兼顾了良好的数据结构和子进程调用的优雅语法。
但我觉得Python的invoke模块已能满足我对子进程调用的所有需求。如今我基本将所有非简单的“shell脚本”都写成Python调用命令。
你指的应该是https://www.pyinvoke.org/这个项目,我刚查阅过。看起来很有前景,感谢提醒。
而这恰恰可能是它失去人气的关键原因之一。它过去容易编写,现在依然如此,但可读性极差。
完全正确。Perl在正则表达式方面表现 极其出色 ,基本哈希表也还行,但其他功能都相当糟糕。
当出现既能处理正则表达式又能管理哈希表,同时其他功能也相当不错的语言后,Perl就被边缘化了。
Perl曾是我最钟爱的编程语言,从1999年到2012年转投Python前,它几乎承载了我所有开发工作。
如今工作中偶尔仍会遇到Perl脚本——通常是在梳理遗留系统架构时——每次看到都忍不住感叹:“谢天谢地我转用Python了”。
这种反应与文化无关,纯粹是技术层面的考量。
仅举几个主要原因:我不明白Perl程序员为何如此排斥注释,简直像某些人沉迷于编写最难以解读的代码。
那简直像意识流的倾泻。
我曾以精通PCRE及其他方言为傲,翻看旧版Perl脚本便知缘由——每十行代码必含正则表达式。如今每当意识到这些场景都能用更符合OOP/Python风格的方式解决时,总会感到如释重负。正则表达式已被我归为边缘场景的专属工具。
我曾是Perl的重度使用者,但最终转向Python。主要原因在于CPAN中的模块质量普遍堪忧,远不及Python的第三方包。我发现自己耗费在修复CPAN下载模块上的时间,远超实现相同功能所需的Python开发时间。尽管Perl生态后来有所改善,但我等不起。
我转向Python主要因为Perl脚本启动速度明显更慢。90年代至2000年代初我曾是重度Perl用户。
并非如此。Perl的衰落源于其他语言开始出现类似CPAN的生态系统,且其极度灵活的语法无法适应中大型团队协作需求。
若限制灵活性确实可行,但Perl文化致命缺陷在于主张“在协作中允许所有人朝不同方向进化”。这种理念固然迷人,却与“可互换零件”式雇佣模式本质冲突,仅适用于每位开发者都是代码领域“魔法师领主”的环境。即便成功让所有人掌握Perl语法解析,训练彼此理解语法决策的认知开销仍呈O(2^n)级增长——这与Python的机制形成鲜明对比:后者将高昂认知成本转移至提案系统,同时通过缓慢的版本迭代和“我们已争论过的内容,免去你每季度重复讨论”的任务简报机制,实现了语言产出的稳定性。
我从未涉足Perl的部分原因在于,它与Ruby相似,似乎鼓励随意地动态修改类。更因其缺乏静态类型系统。Python同样不具备静态类型(现已引入可选类型系统或类似机制),但我的观察是:相较于Perl和Ruby,Python中猴子补丁的滥用程度较低。当然,我使用Python的经验并不丰富。
我转向Ruby是因为MRI在编写扩展时的卓越品质。这简直是一场革命。再也不用SWIG,再也不用复杂的类型魔法,再也不用为在终端用户系统上编译模块而苦苦挣扎。这一切都被封装在gem中,因此这次转换简直是不可避免的。
当时Perl 6正从虚无中初现雏形。但其极度摇摆不定的开发路线和长达十年的开发周期,最终彻底摧毁了我回归Perl的念头。这反而成为我将所有旧Perl代码迁移到Ruby的动力。
>>Perl的衰落源于其他语言纷纷涌现出类似CPAN的生态系统
据我所知,除npm外,至今没有其他语言拥有类似CPAN的生态。
PyPI不算吗?(或者Rust的cargo)
职业生涯早期我曾多次尝试学习Perl,当时公司内部仍有部分Perl系统和工具链。当时在网上实在找不到优质学习资源,接触到的Perl代码大多写得极其糟糕,令我完全无法理解。那时我已掌握C和Python。
不知这种经历有多普遍?为何我们那代人(当时的新人)最终都没学成这门语言?
我的经历如出一辙。职业生涯早期接触的Perl,其晦涩程度远超其他语言。学习过程也毫无进展可言——每当自以为掌握要领,就会遭遇新符号或新模式,瞬间又陷入对代码毫无头绪的境地。
> 当困难本身成为荣誉徽章,你就设下了陷阱:任何降低系统门槛的尝试,都会被视作贬低你的成就。你开始执着于守护那些曾被你攻克的壁垒。
这种心态始终令我愤慨。我愿意攀爬这些山丘,一半原因正是为了获得俯瞰全局的视野,以便下次寻找更轻松的路线。这是我艰苦跋涉的回报,而非为招揽谄媚之徒。
在我看来,除非你曾修改配方使其更臻完美,否则便不能称之为真正掌握。我最爱的南瓜派配方,恰恰如此。按原配方操作会形成结块,唯有电动搅拌器能解决。但南瓜馅料本不该需要电动搅拌器。若先混合所有干料,便不会结块。而且馅料太稀,需要特大号鸡蛋而非大号。所以 那 才是我的最爱配方。
或许正因如此,我最终写出了这么多工具和文档,而非囤积居奇。
Perl专为智者设计——他们视混淆代码为竞技,更怀有自虐倾向。
其核心价值在于率先实现服务器端脚本化/解释型语言运行。
其余成就既非文化意义也非技术意义。纯商业角度看,耗费半数精力对抗特立独行的工具实在毫无意义。
请勿无谓地卑躬屈膝,尤其当你对相关时代背景或编程语言知之甚少时。
Perl并非首创。Perl代码无需刻意晦涩。Perl本非为“服务器端”脚本而生。
Perl社区曾盛行极致简洁的写作风气,却忽视了可维护性与可理解性。这种理念在人员流动频繁的领域根本行不通。
没错,有个玩笑说Perl是只写不改的语言。
或许是只写不改,但用Perl只需写一次就能永续运行, 无处不在 。无需担心更新破坏,无需容器,无需为特定应用准备特殊版本的Perl,系统自带的Perl就够用。
正因如此,实践中Perl程序所需的系统管理维护成本远低于Python等语言——后者常因依赖地狱和语言快速迭代而迫使开发者反复重写代码。企业应用场景中重写本就是常态,但对系统管理而言这差异至关重要。
Perl真正被迫大规模重写仅有一次——从2版到3版。讽刺的是,Perl后来因未能在5版到6版实现同样升级而衰落。
不过我同意Python的版本管理,尤其是库打包机制,确实是该语言最糟糕的部分。
深表赞同!我父亲(安息吧)对Perl痴迷至极,总能用极简代码完成惊人壮举。我虽精通正则表达式,却远不及他的造诣。向那些与他齐名的高手们致以崇高敬意。
Perl模块难道不是与编译时的具体版本绑定吗?
我多次遇到这样的错误:“哈哈不行,版本不对,需要Perl 5.31.7”
纯Perl模块并非如此,除非它们使用了新版本才出现的语法特性。
带C扩展的模块必须与运行时对应的libperl重新编译,就像CPython扩展需要链接特定libpython那样,Ruby应该也是如此。但绝大多数情况下,这些模块重新编译后都能正常运行。XS虽然晦涩难懂,但其向后兼容性表现良好。
根本不存在这种压力。这太荒谬了。人们常不读文章甚至不看教程就随意找理由形成观点,最终选了PHP或Python,甚至天杀的Java,多年后才发现这才是问题所在。
倒不是说必须写出精简代码,但如果你把代码贴到某个地方,很可能会有人回复说用更少的代码就能实现同样功能,接着又有人把那段代码再精简几行/几个字符,如此循环往复。
虽然绝大多数时候这只是大家在玩乐(Perl本就充满趣味且鼓励尝试),并非对你代码的指责或示范正确写法,但我能理解某些人可能产生误解。特别是Perl新手,他们更习惯于那些不存在“实现方式多种多样”(TIMTOWTDI)的语言。
代码高尔夫起源于Perl。
当时存在强烈的文化压力,要求以尽可能少的字节数编写Perl代码,理想状态是实现命令行单行脚本。相关主题甚至出版了专著[1]。
https://www.thriftbooks.com/w/perl-one-liners-130-programs-t…
强烈反对。许多Perl程序员 乐于 参与代码高尔夫(据我所见纯属娱乐),但近三十年Perl编程生涯中,我从未感受到任何来自他人的 压力 要求如此行事。
单行代码是Perl的用法之一。你也可以将其作为嵌入式语言用于大型项目,作为Perl CGI,作为mod_perl等。这些用途都不存在所谓“文化压力”。你可以选择玩单行代码,也可以选择花时间精简代码字符——或者完全不做这些。没有哪条路是唯一正统的,这可不是Python。
> 根本不存在这种压力。太荒谬了。
我亲身经历过。至今仍存留着邮件列表存档和IRC片段,充分展现了Perl圈内那种极端恶毒的炫技风气——争相证明谁能用最精简的代码实现功能。既然能直接做Z,何必折腾X和Y?你到底想实现什么?诸如此类。
如果你愿意,且愿意为此投入大量精力,确实可以参与单行代码、混淆代码或高尔夫编程这类友好的竞赛。这些竞赛正是得益于Perl的表达力强的语法结构。没人强迫任何人参与其中。相反,“实现方式不止一种”的理念旨在确立解决问题才是终极目标——而非强求唯一正确路径(如Python所倡导)。
此后,专家们回答问题时常会提出多种解决方案。他们认为这种智力游戏充满乐趣与刺激,至今仍是如此。而对我们普通人而言,这正是深入学习和理解日常工具的绝佳途径,至今依然如此。
你显然从中看到了恶意,这确实令人不快。
那些专家确实恶毒至极。我能列出具体人名,至今仍能描述他们轻蔑的残酷行径——毕竟我在Perl5核心社区持续社交了十年(拥有CPAN账号,并在Perl5核心作者列表中留名)。想象“那个尚未学会停止贬低他人价值、转而专注批判其作品的林纳斯”。这种行为本质上是文化传播手段:我能更简洁地实现,所以你应当在我面前感到羞愧。若你从未接触过这种文化,我真羡慕你。
有趣的是,这种自负的“我的方法如此明显优越,考虑你的方案简直是荒谬的浪费”心态,最终延续到了Mozilla。这个项目部分由Perl5保守自由主义社区的文化输出推动建立,十年间开发者招聘始终以文化契合度为筛选标准,造就一片“解决问题的方法不止一种”的森林——其中将草地视为亟待重新造林的异常现象。
你确实遭遇了有毒环境。但普通的新晋Perl程序员入门路径绝非如此——至少我从未经历过。
论坛等渠道的支持本可更周全,却总以“自己去读手册”草草了事。其实只需贴一段指向文档入口的指引,就能解决问题。
别忘了当时很多人还在用拨号上网,冗长的论坛帖子可能更容易被“自己去读手册”这类简短回复取代。
EFnet/#perl频道聚集了核心开发团队的主力。非核心社交圈的状况我确实不太了解,抱歉。
> [TIMTOWTDI]字面意思是“Perl中实现方式不止一种”——由此或许能推断出,几乎没有理由使用其他语言实现
恕我直言,这完全不符合我的经验。对我而言,以及过去30年合作过的绝大多数Perl开发者来说,TIMTOWTDI绝对意味着某些“实现方式”并不需要Perl,这不仅完全合理,甚至理所当然。Perl当然不是万能的终极解决方案。不过它确实充满乐趣!
(至今我仍主要用Perl编程,它是我最钟爱的语言。天啊,我甚至觉得它代码清晰易读,调试起来轻松又有趣)
猴子修补在Perl中曾经/现在有多流行?
我认为关键在于:初学者是否听说过Perl的存在?答案是否定的。他们从Python起步,之后便很少有机会接触Perl。
这解释了它为何 持续 消亡。但无法解释其死亡原因——人们不会突然停止接触一种常用编程语言。
VBScript是怎么消亡的?PHP又是如何衰落的?更好的替代方案出现后,它们就失去了生存空间。
这(可悲地)令人发笑,因为大多数人选择Python的理由恰恰如此:他们被告知“这里用这个”,或是被“行噪声”这种无稽之谈所迷惑。他们从未真正深入钻研过。
但我认为真正热爱编程的人很快会发现存在多种编程范式。互联网让探索不同方向变得轻而易举——比如突然爱上Haskell之类的语言。Perl的可见度完全够用,至于Perl 6/Raku就不好说了。
值得指出的是,Python的流行始于谷歌的采用。还记得当年每个网上的极客都热衷为谷歌辩护吗?当人们需要学习新语言(比如当时新兴的数据科学领域)时,他们总会选择那家酷炫科技公司使用的、略显冷门却易于上手的语言。学校采用它让更多人接触到它,但人们选择它的原因,归根结底还是因为谷歌在用,而且它容易上手。
整个决策过程中,根本没人考虑它是否真的是个好语言——更高效、更灵活、更强大、更快等等。关键在于易用性,以及“潮人都在用”。
虽然我自己不用Perl编程,但我常用的现代工具之一就是用Perl写的:https://github.com/digint/btrbk
25年前Perl能让你将脑中的想法以比主流语言精炼十倍的方式表达出来(这些语言后来也追赶上了部分特性)。
这在他人(甚至半年后的自己)阅读代码时未必理想。但对于快速实现其他语言下过于繁琐的功能而言,它堪称绝佳选择。
对我而言这无关文化因素。
Perl是我的首选语言,因为我想开发交互式网站,而90年代末这正是最主流的实现方式。不久后众人纷纷转向PHP——毕竟mod_php比Perl CGI脚本快得多。
那些纯粹因Perl CGI脚本性能问题而转投mod_perl的人,难道不是理所当然的选择吗?我粗略搜索后未能确定mod_php的具体发布时间,但考虑到mod_perl仅比PHP晚诞生一年,几乎所有考虑用PHP重写应用的开发者都应能接触到它。因此我推测其中必然存在其他原因。
维基百科引用某资料[1]称早期PHP版本基于mod_perl构建,但因故无法访问该存档,故无法核实。
[1] https://web.archive.org/web/20130625070202/http://www.theper…
我唯一一次接触Perl的经历是这样的:1997年,我出于好玩尝试用Perl编写程序,想把Mozilla书签转成网站。折腾一周毫无进展后,我沮丧地转投Python。两天就实现了目标,编程过程充满乐趣。这让我认定Perl(及其整个文化生态)不适合我,因此完全理解他人可能有相同感受。(公平起见,确实存在一条简化生活的单行命令:`… | perl -pe ‘s{…}{…}’)
希望这番话不会显得争辩。你说用Python“两天就实现了目标”,但换个角度看:在Perl耗费一周未果后,加上Python的两天,你最终达成了目标。
我不知道,但对我而言Perl根本没过时。我至今仍用它写小型脚本和部分CGI程序。或许我是个退休的老古董,但遇到需要Perl风格解决的问题时,它仍是我的首选工具——就像需要C语言或其他语言时我会选择它们一样。
赞同。它常驻我的工具箱——主要是因为我已掌握它,且偏爱分号驱动的语法——但它只是我使用的众多语言之一。
说不清,我在2000-2003年间曾少量接触Perl,它始终显得亲切友好,我钟爱PerlMonks社区,对此记忆犹新。
对此我有些质疑:
> (请暂停片刻思考:究竟是怎样的社会文化既容忍此类公开场合行为,又将其奉为文化精髓?)
有人为表达观点砸一两个咖啡杯就这么可怕吗?听起来有点小题大做。
我对PERL的困扰始终在于需要记忆的内容太多,尤其当调试代码出自精通该语言者之手时。参与PERL项目不久,就被调去处理Java或Ruby等任务。待到再次需要用到PERL时,只能重新学习所有知识。Java、Ruby、Python或JavaScript从不会让我有这种困扰。
更糟的是,PERL能写出我见过的最难以维护的代码。我曾见过一行PERL代码:读取缓冲区→执行简单数据转换→添加帧信息(部分信息如长度、数据类型和校验和需从数据中推导)→写入完整缓冲区。
这段代码美妙绝伦,却也彻底无法维护。连作者都记不清原理,折腾二十分钟才想起某个变量是受后续语句副作用影响而被赋值的。这种代码适合编程竞赛,但绝不该交给刚入行的开发者维护生产环境。
诚然,你 可以 编写可维护的PERL代码。但多年来,在不同岗位和项目中,PERL始终毫无争议地是最难维护的语言。
导语称Perl消亡源于其“反动”和“文化保守”,但正文却指出Perl的衰亡实因其 糟糕 的文化——那种充满愤怒、腐蚀社会的匿名网络评论文化。
倘若Perl拥有 良善 的文化,那么守护它本该是美事!
这恰恰是当时整个互联网的普遍文化。多年间它如同“狂野西部”,因为它本质上正是现代版的相同现象。
良性文化随着时间推移不会变得反动保守,至少因为它始终向年轻一代的贡献敞开大门。
坦白说,这篇博文充满不诚实、前后矛盾和精神分裂的特质。
按诸多标准衡量,这语言相当糟糕:难以阅读、隐含性强、逻辑混乱,特殊字符等特性更让编写过程痛苦不堪。仅默认参数这个设计就足以成为致命伤——这根本是个灾难性的糟糕主意。
据我所知,Perl6的出现加速了Perl5的停滞,但即便没有它,Perl5终究难逃消亡命运。
Perl的消亡源于多重因素。对我而言,它始终是种令人难以抗拒的“半吊子聪明”语言。1995至2000年间(从Perl4到Perl5)我曾大量使用Perl,直到接触Python(1.5.2版)[^1]。我极度欣赏它的简约性、禅意、内置标准库和REPL特性,发现安装附加包比处理CPAN更轻松。自此我转向Python,基本再未回头。
[^1]: https://news.ycombinator.com/item?id=44790671
我在ZipRecruiter入职时经历了一件趣事:当时(2022年)发现公司大部分代码都是用Perl编写的。他们的CTO刚对Perl忍无可忍,便下令今后所有新项目都必须用Go语言开发。我是团队里第一个用Go写代码的人。
几位资深前辈不断向我强调Perl是完全合格的语言,其运行速度足以满足多数需求。我并未与他们争辩,只是慢慢退出了讨论。
作为编程语言,Perl在1990年代作为Unix shell的进阶替代方案尚可接受。但对我而言,它作为语言的失败之处在于:要实现哈希数组或数组哈希,必须依赖引用机制。这种技巧在1990年代或许堪称巧妙,但到了2005年仍显得原始过时。更糟的是它依赖由$符号及各类非字母ASCII字符构成的魔法变量,比如$_、$#之类。这种设计在1992年或许很酷,但时代早已不同。
总体而言,Perl适合编写20行以内的简短脚本,但绝非构建整个公司的理想选择(比如ZipRecruiter)。这更多是针对ZipRecruiter的批评,而非Perl本身。
初次见到Perl时,它就像来自外星的语言,那些符号看起来简直疯狂。
但一旦掌握,其实相当直观。
最糟糕的是面向对象编程的语法,而Raku(Perl 6)在这方面做得更好更直观。
Raku引入了语法规则等优秀设计,但新增了大量神秘符号,还丢失了我认为Perl 5中直观的正则表达式用法。
=~ vs ~~
我不明白为何Perl衰落而PHP却未受影响
我认为PHP的语法门槛低得多,尽管人们常对它有各种抱怨。在2000年代初期,它感觉就像“嵌入HTML模板的简单C风格函数调用”。这种语言几乎无需教学。
部署也简单到“把文件拷贝到Web服务器的公共目录”就行。
Perl是门非常难的语言。PHP相对简单得多。它最初只是C语言的脚本语言,在开源库还处于零散混乱的时代,尽可能整合了大量开源C库。
当时PHP的成功和Perl的衰落已是显而易见。
PHP已式微。如今还有谁在PHP领域开创新局?
PHP在Web领域的历史积淀远超Perl,只因它更易上手。但它已无未来可言。Wordpress、Drupal、Joomla…这些都曾风光一时,如今皆成过往云烟。
作为既不懂Perl也不懂PHP的人,我认为PHP更像是一种领域特定的扩展动态语言(EDSL),而非主流编程语言。
这篇博客里为数不多不愚蠢、不虚假、不矛盾且不精神分裂的见解,是关于PHP创建新进程的常见做法。
mod_php的使用体验远比mod_perl简洁。系统管理员配置后,开发者无需关注底层机制,常规PHP运行速度极快。更重要的是,它独创了“可编程HTML文件”范式——这种特性深受开发者青睐,相较于Perl大幅降低了技术门槛。这正是导致Perl衰落的导火索——它不再是最易上手的互联网入门语言。PHP在重大语言升级时也未重蹈Perl的覆辙。
RoR曾暂时延缓Ruby的衰落,但其命运终将与Perl相同。Python则因成为机器学习领域的事实标准而幸运地延续了生命力。
至少对我而言,PHP的可读性高出许多。它与Java足够相似,无需重新学习太多语法。
与其说Perl“曾衰落”,不如说它的 存在本身 就是文化现象。所有编程语言(或任何思维工具)都是创造者与维护者群体认知价值观的映射与投射。简言之,Perl语言的结构本质上就是典型Perl开发者思维的映射。
转向Python或Ruby,本质上是转向另一套核心认知模式。这将影响问题解决方式与世界认知方式——编程语言作为工具,不仅促进思维过程,更常常引导思维方向。
我们目睹的企业文化变革与协作规范、编码惯例等社会化实践的兴起,恰与一种语言的式微同步——这种语言背后的文化传统曾严苛要求人们“阅读手册”。如今科技领域的主流文化,要么通过集中化解决方案攫取租金,要么刻意忽视复杂性与细微差别以追求极致速度,将后果推诿至未来。
若你在此论坛久居,此论当觉似曾相识——其根基早已在《计算机编程的变态指南》中铺陈,该书运用拉康精神分析学阐释各类编程语言中的认知模式[1][2],由此可解 Perl 所谓衰落之谜(实则仍有众多开发者默默在后台使用),亦能说明 Rust 与 C 文化间的冲突。
顺带一提,我开发了一款工具,能运用此分析法帮助企业招聘开发者,即使对方使用Zig或Nim这类非常规语言。我还曾考虑将其作为SaaS服务推出,协助人力资源部门理解这些现象(因为多数人力资源专员不会编程,只能凭直觉面试,这迫使他们重复已有的认知模式)。但必须指出,在当前招聘市场环境下,此类工具的市场需求可能不足。当然,我的判断也可能有误。
[1] [PDF] — 《变态的计算机编程指南》https://s3-us-west-2.amazonaws.com/vulk-blog/ThePervertsGuid…
[2] [YouTube Vulc Coop]– https://www.youtube.com/watch?v=mZyvIHYn2zk
抱歉重复提问,Perl中的猴子补丁技术曾经/现在有多流行?
Perl深刻塑造了早期网络文化。有趣的是,一种语言的衰落往往并非源于能力不足,而是因为社区的重心转移到了别处。
Perl堪称互联网的万能胶带。
抛开文化问题不谈,它确实 高效 !
确实:回望过去,Perl社区(甚至整个语言本身)都令人尴尬,或许还带有毒性。
但当时,这种精英化且晦涩的语言吸引着我和许多人,就像*BSD乃至Linux所做的那样。就像编程本身所具有的魅力。
那绝非值得重现的愉悦氛围,但当年对许多极客而言,Perl确实代表着酷炫的存在。Perl的文化式衰落实属好事:这正说明行业已成长成熟。
关于Typescript超越Python的评论让我非常困惑,它们解决的根本不是同一类问题吧?
我觉得这个观点非常敏锐。看看JS最初的设计目标,再对比它如今实际承担的任务。
事实证明,最初试图解决的领域并不重要。只要你偶然发现了一种实现其他目标的低摩擦方式,人们就会用你的工具来完成那些任务——即使它并非这些领域的最优解。
我对JS/TS的未来感到忧虑,但它显然势不可挡。
我主要使用Python的原因在于
python3 -mvenv env命令。若能确定所需功能都包含在Perl内置模块中,我更倾向于Perl。产品社区文化与维护者态度的影响力毋庸置疑。
但我当初使用Perl并最终弃用它时,对它的内部政治或社区一无所知。PHP、ASP、Java JSP以及后来的Rails在Web开发领域都远胜Perl。
* 我知道提及JSP会让某些人感到陌生,毕竟它曾丑陋不堪……但在2000年代,它可是尖端技术
我原以为Perl的衰落源于其混乱的语法。这确实是我最终弃用它的原因。
Perl6/Raku终结了Perl。
Python 3几乎终结了Python。
这是常态。当社区失去信心,便难以阻止人才流失。
我更进一步认为,真正杀死Perl的正是那些催生Perl6的设计缺陷。Perl6只是加速了这个进程。
我确实设想过更理性的迁移方案——例如规定正则表达式不能以未转义空格开头,除法运算符必须用空格包围(以解决解析问题),同时采用常规的
use渐进式迁移机制。完全赞同。我们被告知要等待所有想要的改进或新特性,只需等待Perl 6——但它永远没有到来。
没错。Perl 6成了Perl 5永远无法跨越的壁垒。二十五年后的今天,它依然停留在Perl 5阶段。
Python 3连Python 2都消灭不了!
人们都在哭哭啼啼;批评者极少却异常嘈杂。Python 3 在各个方面都提升了语言性能,其升级工具至今无人能及。
Python 3 简直是场灾难,十年后企业仍在推进毫无意义的 2->3 升级项目
一个月前我不得不修复内部系统中一段Python 2.6代码的小漏洞。这套系统永远不会迁移,既无能力也无价值
虽然令人烦躁,但若没有这次变革,Python至今仍在Unicode这类基础功能上挣扎。
企业确实为此困扰,但它们本质上对每次重大变更都难以适应。我所在的工具团队曾协助某机构完成约500万行数据科学代码从Python 2.7到3.2的迁移。我们还处理过其他破坏性变更:Airflow升级、Spark 2→3迁移、处理器从英特尔→AMD→Graviton的转换。
在这种规模下,所有变更都是重大事件。甚至Python 3.8的pickle协议变更对我们而言都影响巨大。我不会认为Python 2到3的迁移比其他变更更棘手。从许多方面来说反而更容易——正因为当时被炒得沸沸扬扬,积累了大量知识和工具支持。
> 虽然过程烦人,但若没有这次变革,Python至今仍在Unicode等基础功能上挣扎。
他们本该直接将Python 2的字符串作为UTF-8使用。无需破坏所有现有程序,只需弃用并劝阻使用旧版Python的Unicode类型即可。新版Unicode类型(Python 3的字符串)实则复杂混乱,任何认为它简单明了的人都未曾洞悉其底层机制。
将字符串设计为简单的字节数组——无论其编码是UTF-8还是WTF-8——这种方案在Go语言中运行得相当出色。
我从未想过“真希望Python能采用Go的Unicode方案”。在所有运行时中,Go的字节/字符串分离机制堪称最简洁的设计。
但事后看来,Python 3本可实现无缝升级。
试想若同一解释器同时支持Python 3和Python 2:Python 3代码可导入Python 2模块,反之亦然。代码库就能更渐进地迁移。Python 2代码中的“字符串”本质是字节,Python 3中的“字符串”本质是Unicode,但双方 都能 理解对方的语言——只是命名不同,迁移自然可行。
字节与Unicode的分离造就了更优质的代码。字节是网络传输的原始数据——究竟是PNG图像还是文本段落?无人知晓!但在Python 2中,两者都被视为相同的字节序列。
这种强制要求在必要时将字节序列解码为文本字符串的做法,消除了大量潜在错误。比如忘记在将原始数据传递给期望字符串而非字节序列的函数前执行
value=incoming_data.decode()?嘭!问题在于,这种错误其实一直存在,只是现在变得 显而易见 了。更不必纠结某个值是否已解码——因为最终结果的数据类型已然不同。在Web服务器内部函数中,旧版粗糙的实现导致有时传入解码后的字符串,有时则是原始网络传输的字节流——这常导致非ASCII字符处理错误。若试图通过强制解码传入值来修复,又会破坏原本正常调用的功能。唉,简直一团糟!最初一个月我痛恨这种分裂,因为它破坏了我大量陈旧糟糕的代码。其实并非如此——它只是迫使我正视这些陈旧糟糕的代码,并完成艰苦且无法自动化的修复工作。最终结果远比最初状态优秀得多。
这种区分确实至关重要,我并非主张取消它。我的观点是:你可以为所有类型命名,并通过让Python 3更改默认值(例如将字符串默认为unicode)来管理过渡。
我有些困惑。这不正是Python 3的做法吗?在Py2中,“foo”是字节串,而u“foo”是Unicode。在Py3中两者都是Unicode,而bytes()才是字节串。
关键区别在于两者无法互操作。你无法在Python 2中导入Python 3模块,反之亦然;必须使用完全独立的解释器运行它们。
我提议采用单解释器运行Python 2和Python 3的模型,底层类型保持一致,从而实现跨版本传递。你需要知道在Python 2中创建的“foo”等同于Python 3中创建的b“foo”,但这很容易处理。
好吧,当社区本可以承担一点责任时,谁会提出这种建议呢?
不过事后看来,Python 3本可以作为一次无缝升级来实现。
除非付出巨大且不必要的代价。
谁的代价?将所有必须移植的代码迁移到Python 3确实很痛苦,这样Python开发者才能更轻松。
没错,客户若想被认真对待,就该停止耍赖。
这样做 绝对 更艰难。但这条路带来的痛苦,或许比Python 2到Python 3的过渡更小。当然也可能更糟——即便事后看来,我也不敢断言这种权衡是 显而易见 的。
我觉得你因果颠倒了:声称迁移Python 3比原地踏步更难,这种说法至少夸大了两个数量级。不过随你便啦亲亲 :emoji-kissey-face:
这根本不算灾难。人们只是抱怨升级代码库需要付出努力罢了。
但Python从1版迁移到2版时走了 另一条路 ——猜怎么着?那次同样被称为“灾难”。
唯一区别在于Python 3时代程序规模已扩大 数个数量级 ,痛苦程度自然加倍。
规模差异确实会带来本质区别,迁移时必须考虑这一点。
真正的问题在于将3.0当作稳定版发布,而实际可用版本是3.3/3.4
编译autotools、openssl、nasm等仍需Perl支持。
因此Perl很可能长期存在
Python有时也用于软件编译,但上述依赖Perl的项目尚未转向Python
Perl鼎盛时期我始终难以亲近它,但Perl的dbi模块堪称完美。若你需要它能实现的功能,它能让你快速上手且直观,代码也相当简洁。这两点正是Perl的魅力所在。
Perl 5的保守主义让旧脚本能永久运行,但也意味着它从未像Python 3那样提供明确的迁移路径,这使得长期规划变得困难得多。
Perl确实有
use strict机制,至少为通过新指令实现无破坏性变更提供了可行路径。原帖作者提出的“Perl 6的激进主义使Perl 5得以保守”的理论,在我看来颇有道理。
但与此同时,
use strict可选的设计最终让许多人望而却步——至少部分原因在于,我们总会遇到某些未针对use strict设计的特性,它们的失败模式相当…独特。这与当下从JS转向TS的趋势如出一辙,也类似于Python添加类型提示的动机,甚至在某种程度上解释了人们选择Rust的原因:当你犯错时,它拒绝执行并给出解释,而非产生怪异的运行结果。
据我观察,业界正普遍摆脱“更糟即更好”的理念,而Perl堪称这一转变的早期牺牲品。部分原因也在于科学进步:当Python和Perl初现时,主流类型化语言虽繁琐却远不及当今标准下的“优秀”类型系统。Perl是我习得的第一个语言,若回到1990年代,即便2025年已不再使用它,我仍会选择它。
(好吧,或许我会全情投入OCaml。反正骆驼总能赢。)
我的客户使用IBM服务器及其阉割版Unix(AIX)。Perl和Copilot的访问权限帮了我大忙。虽不热衷Perl,但能拥有如此广阔的实践空间实在庆幸。
我不喜欢CPAN,而Python更简单易得。若Python不存在,我想我会重金押注Perl——毕竟它曾无处不在。
早期Perl的魅力在于拥有强大工具随心所用。团队协作中几乎无需编写代码。
人们仍为能在1行代码完成X操作而非100行而惊叹——毕竟有些人根本写不出那100行代码。
因此“配方/咒语/黑客技巧”的概念是刻意设计的隐喻。
这逐渐形成文化现象。新人渴望用精炼代码赢得尊重,就像当年他们被震撼的那样震撼他人。
> Perl始终存在大量可称为“BOFH”的文化,源于其古老的UNIX系统管理根基。那些被动攻击式的惯用语和内部梗如“RTFM”、“lusers”、‘wizards’、“错误求助方式”等皆属此类。
> […]
> 文化保守主义作为首要原则。
与此相对的是Rust。Rust虽存在类似的RTFM/“向导”文化,却在任何意义上都不保守。
我的看法:Perl的衰落与其“文化”关系不大。我认为Perl的问题根源更深。它建立在腐朽的根基之上,本质上是脚本语言(尽管后来拼凑了些特性勉强算面向对象),因此在构建大型软件项目时,它继承了所有脚本语言的先天缺陷。
这些问题无法快速解决,要根治就必须彻底抛弃这门语言——既然如此,何不直接换用其他语言(事实正是如此…)。
此处或许过度延伸了文化隐喻,但Rust确实散发着“无产阶级先锋队”的气息,似乎也容易陷入这种政治使命带来的困境。
哦Perl啊,这门语言简直是自掘坟墓的代名词。它已经消亡了吗?
第一眼就觉得糟糕透顶。这足以让我永远远离它。
感觉自己并未错过什么。
Perl属于特定时代,因此铭记它曾存在的年代至关重要。CPAN确实是首个真正可用的编程语言包管理器。从历史语境看,它的参照系是bash、sed、awk等命令行工具。Perl实现方式过于繁杂,源于其多元化的实现风格与解决方案。在C/C++时代,它也是编写CGI应用的趣味选择。这是否是当今的最佳实践?当然不是!它曾是仅用寥寥数行代码解决复杂问题的解决方案,在许多方面堪称那个时代的Python。
Perl蕴含着大量影响现代语言发展的奇趣特性,对我而言
“<=>”太空船运算符尤为妙趣横生。翻阅骆驼书便能窥见那个时代常见的编程特技。这是一种作者语言,其开发模式与当今语言体系截然不同。
Perl 6对社区造成巨大伤害,主要因其差异性过大而形同幻想语言。加上Parrot虚拟机的混乱局面,我基本放弃了这类工作,转而用R语言处理生物信息学事务。Bioconductor堪称绝妙之选。
看到这么多恶意攻击我感到惊讶,你们要么不到30岁,要么对一个初生的技术时代过于苛责。Perl经历了.bomb事件前后,我记得它在perlmonks.org上建立了最早的大规模在线社区,共享技巧和窍门。它比stackoverflow还要早!那是个与现在截然不同的时代。
那还是人们为编译器付费的年代(!)
我对此深有偏爱——当年我用Perl编写了小分子药物三维距离计算工具。我们通过生物筛选寻找双硫仑类似物并进行模拟,当时优秀的PDB结构库帮我节省了大量时间。这已是2005年前后的事了,距今可谓沧海桑田。
1999年我耗费整年用Perl开发CMS系统(基于ActivePerl的HTA应用,不知是否还有人做过类似项目)。那段经历让我心有余悸,换工作后第一件事就是学习Python并用它开发核心系统。不少朋友也从Perl转投Python阵营。
至今仍记得和同事们坐在大楼外的长椅上,试图破解前任开发者留下的#@$%$^&$%@something = []sd[dsd]@$#!&lala这类神秘代码
在最终转向PHP之前,我曾编写过多个通过
cgi-bin运行的CMS类解决方案,但内容写入到webroot目录(即如今所谓的静态网站生成器)。由于当时标准共享主机的限制,我不得不发明自己的单文件数据库格式(其实就是个简单文本文件)来保存状态。这个方案运行得相当完美,支撑我在2000年代初作为网页开发者的头几年。我了解ActivePerl,也很喜欢Komodo。值得庆幸的是,除了短暂尝试用ASP写过单文件CMS外,我始终避免在Windows/IIS环境下开发。
加入该公司前我已掌握php2+msql(还略懂php3)。和你的情况类似,核心是静态网站生成器,但管理端采用HTA(基于IE浏览器的应用程序,可使用vbscript/python/perl等ActiveX语言开发)。
后端采用Oracle数据库。初期尝试过Oracle/Linux组合(刚发布时),但始终无法正常运行(连Oracle工程师来现场也未能解决)。最终我们为其配置了专用Sun服务器。
某日闲来无事,我在工作站安装了MySQL,修改了几个查询语句后,性能竟达到Sun服务器运行Oracle时的20倍。首席开发者认为这是糟糕的方案,因为MySQL无法正确支持参照完整性(不过我记得我们实际在Oracle中也没用过这个功能)。
昨天我用
pwgen生成随机密码时,乍一看还真以为是能运行的Perl代码。我一点都不开玩笑。Perl开发者们正在给你点踩,但作为长期前Perl用户,我也认同那些符号确实是嘈杂的无用之物。
最初的设计意图是通过符号识别变量类型——$scalar表示标量,@array表示数组,%hash表示哈希表。
但他们立刻破坏了这个设计:决定让符号适用于从数据结构中提取的值。于是你声明数组@foo,却要用$foo[1]访问元素?这逻辑虽存在,却违背了多数人的预期,那还保留符号何用?如今符号不仅未能澄清概念,反而令多数人困惑。
当引入引用机制和“复杂数据结构”时(即像其他语言那样嵌套数组——在Perl中这曾是特殊功能,因其默认扁平化列表结构导致无法嵌套),符号机制彻底崩溃。
因此要访问嵌套哈希时,你不能用%而必须用$——因为引用是标量类型。$hash1->$hash2->{“key”}。而简单哈希只需$hash3{“key”}。这种冗余语法简直糟糕透顶,全因最初糟糕的语言设计所致。
最后那段描述让我彻底放弃Perl转投Python。初次用Python写出hash1[hash2][“key”]竟能运行,接着尝试hash1[hash2][“array_name”][3]也成功——这才是直观的表达方式,自此我便深陷其中再未回头。
我再也不愿在嵌套哈希引用中追踪指针的迷宫里苦苦挣扎。
哎呀,最后那个示例应该写成 $hash1->{“hash2”}——这是通过 $ 引用整个哈希表的写法,因为实现细节上它作为引用存在于 hash1 中,被视为标量。
严格来说你可以这样用 %:%{$hash1->{“hash2”}}。不过嘛——哈哈。
难怪人们总在质疑:为何Raku需要如此大刀阔斧地改造,才能释放语言核心的卓越理念?
在从事Perl工作前,我写过汇编/Tcl/Delphi/C/PHP(后来又接触了许多其他语言)。
Perl的语法曾让我产生近乎生理层面的抵触。许多朋友也有同感。《Python禅》简直是清风拂面。
Rust社区是否该从中汲取教训?Zig社区或许也该有所反思?
在我看来,Rust社区中某些人——或许因其声音最响亮——正与激进的社会运动紧密捆绑。
总的来说,我更希望技术社区能完全远离政治和社会议题。
赞同。Rust社区之所以充满毒性,正是因为他们执意将政治引入技术领域。我热爱这门语言,但尽可能远离其社区。
我也渴望政治别渗透生活的方方面面。但在每个人都能至少部分地自由生活——不受其不可改变的特征、信仰体系、所爱之人或自我认知压迫之前,我认为为这些事业奋斗是我们的公民责任。
> 我认为为这些事业奋斗是公民的责任
但为何要动用技术社区的资源来奋斗?这必然疏远那些与你重视的事业立场不符的人。
履行公民责任的方式在城市里比比皆是。比如挨家挨户敲门鼓励投票。何必非要通过技术社区来实现?
不可能完全不疏远任何人。问问女性软件工程师是否感受过疏离感。这正是Python社区等群体开展科技领域少数群体外展活动的原因。
身为白人男性,我在所谓进步派圈子里从未感到“疏离”。
若厌恶政治,大可分叉Rust。可惜对任何人而言,Rust都不值得分叉。
这很合理。我自己的经历是:从Perl转向Python(用于系统和API开发)和PHP(用于模板与HTML)。
唯一让我十多年持续使用Perl的项目是RADIUS(我们运行Radiator——堪称ISP领域最疯狂灵活的AAA服务器)
提到Python时,我认为它持续增长而Perl衰退的关键原因在于其开放包容的文化氛围。
Python宣称“你一无所知,却想自动化完成小任务”——社区会全力相助,这种支持力度远超其他语言。
不过话说回来,Python 2和Python 3本质上是两种语言。
极少有项目愿意承担如此大规模的迁移成本。
“Willing”这个词的选择很有意思。尽管好处显而易见,Python社区仍存在相当大的抵触情绪。(2.x版本确实无法修复,因为其语义在许多地方都存在根本性缺陷。)
这是开源项目。
任何人都可以(相信已有尝试者)分叉2.x分支继续使用。
3.x版本异常易用,非程序员一个月内就能上手Python。
> 任何人(我确信已有尝试者)都能分叉2.x版本继续使用。
他们尝试并成功了:https://docs.activestate.com/activepython/2.7/
我仍认为该结果“存在缺陷”。
早年Perl之所以能崛起,关键在于它与当时的C编译器不同——在Unix系统上编写的代码通常无需修改就能在其他Unix系统运行。在我早期的工作环境中,面对各种商业Unix系统的混杂环境,这种特性无可匹敌。它还像高级Shell那样编写,这使得系统人员易于学习——毕竟多数时候,真正关心跨平台运行的人只有他们。
随着环境趋于同质化,加之其他语言也具备了这种“跨平台支持的奇技淫巧”,Perl及其社区的缺陷便暴露无遗。
Perl的失败源于它是种只写不读的语言。唯有编写时才能真正理解Perl程序。若半年后重读代码,祝你好运——这如同解读他人编写的正则表达式,而Perl与正则表达式的关联绝非偶然。
Perl之死源于“写一次,永远不读”的诅咒
可执行行噪声。
我曾瞥过Perl一眼,当即决定永不使用,更祈愿它消失殆尽免遭沾染。抱歉,这种衰退很可能源于它本身的问题。
Perl的“衰退”意味着存在某种衡量其地位的指标。它曾经更高,现在更低。不过我认为这个指标定义得并不严谨。
Perl作为老牌语言,在处理数据流或管道任务上极具速度优势。某些场景下甚至快于C语言,但更胜一筹的是它能快速生成实用脚本程序,兼具隐式语法糖特性。其高度灵活性让你只需用熟悉的方式操作,通常已足够高效。
Python在这方面同样出色,现代计算机的高速运行使其比Perl慢得无足轻重。但若需处理数千兆字节文件,不妨花时间寻找或编写Perl的一行式代码,将其折腾到满足任务需求。
Perl在正则表达式方面同样令人惊叹。这正是Perl编写体验远胜Python的原因之一。至今我仍用Perl处理重度正则任务,真希望Python也能像它那样将正则表达式深度集成到语言中。
我的手指早已遗忘曾经熟稔的Perl代码,但那段时光始终令人愉悦。
不,Perl本身就不是个好语言。并非所有语言都同样优秀。
Ruby同样销声匿迹了,这篇文章却在赞美它?Lisp呢?反观无处不在的C、PHP、JS,这些就是好语言?有时精英主义与成功并不相符。
[已删除]
讽刺的是,暗示他人会因你讲道理而责备你,这种行为本身就和责备一样令人反感。
我们无需多言,因为Perl代码中那些令人作呕的语法糖浆和喷溅的线路噪音已足以说明一切。
显然还不够响亮——看看这里多少人还在追寻它失败的神秘文化根源。
我在某大型机构工作数年,该机构将Perl用于构建脚本、测试自动化等领域。若要总结这五年Perl的学习曲线:初始阶段是困惑,中级阶段是近乎宗教般的推崇,高级阶段则是彻底幻灭。
在大型团队中扩展使用Perl时,总会感到某种别扭且摩擦巨大的体验。
相关阅读:
《Perl之死》
https://news.ycombinator.com/item?id=45977900
Perl的“衰落”使其免于比死亡更糟的命运:流行后因功能增删导致分裂成数十个互不兼容的版本(如Python)。相反,Perl始终以稳定形态无处不在。脚本总能直接使用系统自带的Perl解释器。更难得的是,当今编写的脚本往往能在二十年前的Perl系统解释器上完美运行(反之亦然)。这使其成为系统管理与个人应用的理想语言——尽管它不适合机器学习这类需要持续重大变革的前沿领域。世间万物皆有取舍。
这种早期普及带来的无处不在特性,结合因Raku等语言导致的热度骤降,造就了其他同类语言无法企及的独特优势。Perl就是无处不用的存在——无需容器、摆脱依赖地狱、无需特定版本。Perl就是Perl,始终如一地可靠运行。
我深爱它。衰落反而成了救赎。
Perl的二进制特性使其能运行5.8及之后的所有版本。你可以随意混用5.30、5.8、5.20等不同版本的代码,只需在每个模块或脚本开头声明“use v5.20.0;”即可。
相比之下,Python几乎无法在单个版本中同时引入新特性又移除旧功能,因此任何Python代码只能在脆弱且狭窄的版本窗口内安全运行,为其编写的程序必须持续更新才能维持现状。
Python解释器:若能识别“print”作为关键字而非函数调用(以便指责程序员此操作),同样也能直接执行该函数调用。
> 相较之下,Python几乎无法在两个版本之间保持稳定,总要引入新特性并移除旧功能
被移除的绝大多数是标准库中的内容,且都是极其陈旧的组件。直到3.11版本,你仍能使用`distutils`(Setuptools的前身)。而在3.12版本中,你仍能使用
pipes(subprocess的前身, 即便subprocess刚推出时也无人提及 ;当时普遍认为subprocess直接取代了os.system及os.exec *系列函数的DIY实现)。还有sunau和telnetlib。*能否举例说明实际存在的包因依赖即将终止支持的3.x Python版本解释器 的功能或语义*而受阻?
> Python解释器:若能识别“print”作为关键字而非函数调用(以便警告程序员此类用法),同样也能直接执行函数调用。
不行,这行不通——因为语句形式具有截然不同的语义。你需要保留完整的语法规则(还得处理有人试图在更大表达式中嵌套“print语句”的情况)。况且函数调用通常可解析为带完全合法括号的语句形式,因此必须决定使用语句形式的文件是否应全部切换为旧式解析。此外,函数调用支持原始语句形式无法兼容的语法,需决定是否接受这些用法,或如何报告错误。更关键的是在2.7版本中,外层括号并非冗余,而是改变语义:
字节/字符串处理机制的根本性变更同样不可忽视。至少需要通过编译指令来适配。
asyncio.get_event_loop ?
我似乎搞砸了斜体强调。重点本应放在“来自解释器”上。asyncio.get_event_loop是标准库函数。
真是太好了。我最在意的设备都是32位架构。我使用的Perl版本是2008年左右的5.0。不知amiga386或其他朋友能否告知我升级到Perl 5.8需要哪些条件?是否只需升级到Perl 5.8并搭配同期版本的gcc?我2008年左右的Suse 11.1系统其他部分还能用吗?同台机器/发行版能同时安装两个gcc版本吗?需要时能否指定路径调用新版?我坚持用Suse 11.1的原因是后续版本破坏了其他早期组件,而我无法修复。
suse 11.1内置perl 5.10版本:https://ftp5.gwdg.de/pub/opensuse/discontinued/distribution/…
Perl 5.8于2002年发布。Perl 5.000(实际上并不存在Perl 5.0版本)发布于1994年。我很难相信您安装的是Perl “5.0”版本。
Python的方法似乎更适合避免隐蔽的错误。这又体现了“实现方式不止一种”(TIMTOWTDI)与“应该存在唯一明确的实现方式”的对立。
您指的是哪些不兼容的Python版本?我完全不知道存在任何分支版本,目前我能提供的最新版本是3.9——这个版本已有五年历史,且在所有支持平台上均可使用。
试着在不使用容器的情况下,用你的Python 3.9系统解释器运行任何中等依赖的随机Python程序。你很可能需要使用venv之类的工具,为该应用单独配置特定版本的Python。这已成为标准做法,因为系统Python无法胜任。实际上,从实用角度看,根本不存在“Python”这个单一实体,只有各种Python实现。这还没涉及点版本升级的重大兼容性问题,更不用说Python 2到3的语言迁移了。
> 通常你需要使用venv之类的工具,为特定应用单独配置专属Python版本。
使用venv轻而易举 (且比容器轻量级数倍)。几乎所有主流软件包都遵循政策:每次新版本发布时, 至少 支持所有当前受支持的Python版本。
你需要设置venv, 正是因为语言的设计机制 ,以及它自诞生以来 始终如一 的工作方式。Python无法在同一运行环境中容纳多个版本的软件包,句号。语法本身不支持在导入时指定版本号。导入操作通过符号名称缓存,程序正确性完全依赖此机制(即库可维护全局状态,客户端始终获取单例模块对象)。人们未曾察觉/在意这个问题,只因当时整个“生态系统”概念尚未形成。
我至少本地手动编译过从3.3到3.14(含)所有版本的Python(另含2.7版),操作并不复杂。但我这样做纯粹是为了测试,而非被迫使用他人项目所致。除非你专门使用PyTorch/CUDA/Tensorflow相关技术栈,否则生态系统 根本不存在这种需求 。
> 之所以成为标准,是因为系统Python无法做到。
你的系统Python完全可以安装包。限制存在是因为 你的Linux发行版需要管理系统环境 。系统包管理器不该处理它未安装的文件,系统工具也不该冒风险加载你手动添加的依赖。请参阅https://peps.python.org/pep-0668/,尤其关注动机与原理章节。
> 版本升级导致的重大兼容性问题
我能想到的唯一案例是(
async成为关键字,破坏了将其用作参数名的Tensorflow)。对此他们通过引入软关键字概念作出回应。除此之外,3.x小版本升级根本不会导致代码语法失效或语义变更——仅标准库存在增删改。通过封装旧代码即可轻松解决。> 这还没涉及点版本升级中的重大破坏性变更,更遑论Python 2到3的语言迁移。
Python从未采用语义化版本规范,也从未宣称遵循该规范。但将“x.y”版本视为独立的重大版本(例如2.7→3.0是重大版本,3.10→3.11亦然)或许更合理。如此处理后,版本体系将更具逻辑性。
我的编程学习历程(从10岁开始):8086汇编语言、QBASIC、C语言、Perl、Java、MAGMA、JavaScript/HTML/CSS、Python、Haskell、C++、vibe编程
你现在多大了?我五十多岁了。所谓“vibe编程”具体指什么?从编程角度看它不具吸引力,但从“AI最擅长什么”的角度呢?我经历了类似但不完全相同的成长轨迹,如今在Python/HTMX/Flask环境中进行氛围编程时无需深度审阅代码(注:仅限内部应用,非对外系统),使用Claude Code Max。近6-8周的氛围编程似乎也开始胜任嵌入式编程——ESP32/Arduino/ESP-32平台,同样借助Claude Code。
35–44岁。情况相同,偶尔会出现规划错误,或忽略文件中显而易见的上下文,但总体而言是巨大的助力。无需深度审查,只需设置测试环境让它迭代即可。潜力巨大,令人振奋。
我认为当前的大型语言模型虽“尚未超越人类智力”,但它们拥有更广博的知识储备、无限专注力与无拘束的能量(当然需在计划/积分/配额范围内!)。我迫切期待真正超越人类的AI诞生,它们将创造的奇迹令人心驰神往。
得了吧。这语言简直像霍格沃茨里诞生的东西,满是魔法咒语和念咒。它之所以失败,是因为学习难度太大——而其他语言(特别是Python)同样强大却更易上手。
我不明白为什么Ruby会排在PHP前面。我唯一接触过的Ruby项目是GitLab,而且印象并不美好——直到三四年前,特别是Sidekiq始终是个令人头疼的存在。
我猜是因为Ruby处理字符串的方式深受Perl影响。
当年从Perl转用Ruby时,虽然感觉熟悉,但一切都显得更…合理。
我也对此感到意外,看到文末日期前还以为是十年前的文章。更离谱的是两者都排在Python之前,而JavaScript竟完全被忽略。
后端使用JavaScript实属罕见,即便在“简历驱动开发”场景中,通常也只是某种静态构建后部署到S3之类的平台。
Node.js可是StackOverflow开发者调查中最热门的Web框架/技术。同份调查中Express的受欢迎程度甚至超过FastAPI、Django、Flask和Rails。你到底在说什么?
你是从1998年穿越来的吗?那年AOL收购Netscape后就把Livewire晾在一边了。
我不同意,Python就是更优秀。虽然没用过Perl,但因某些古董工具需要安装过它,每次都是难以理解的混乱。至今仍搞不懂Perl的包管理机制。而且Perl里似乎万物皆字符串?语法看起来也乱七八糟。
或许程序员们难以承认语言设计本可以更优雅,当真正优秀的语言出现时,众人便蜂拥而至。
> 而且Perl里似乎所有东西都是字符串?
实际情况比这更糟。Perl的类型系统简直荒谬至极,多数资深Perl开发者都未能完全理解它。
https://blogs.perl.org/users/leon_timmermans/2025/02/a-deep-… 是篇不错的入门文章。
看到这么多博主懒得优化文章在手机端的可读性,实在令人震惊。难道大家在学习CSS时都跳过了媒体查询那部分吗?
文章内容不错,但在手机浏览器上简直是噩梦般的阅读体验
(作者)很抱歉造成您的阅读不适。我的博客“引擎”确实是个拼凑的破玩意儿,勉强能用,CSS都是手写代码,而且大多是在移动优先时代之前搭建的。最近刚调整过以适应竖屏手机显示,但网站体验确实很差。我确实努力生成简洁的语义化HTML,因此页面在“阅读模式”或用户自定义样式表下应该表现良好——若您能启用这些功能,这可能是最佳体验。