Uploaded avatar of ErikSchierboom

精简九月来啦!

@ErikSchierboom
大约3年前
视频

简介

大家好!希望你们一切都好。

对 Exercism 来说,八月是非常忙碌的一个月。我们合并了 Premium 和 Insiders,把自动反馈直接加进了编辑器,推出了学习轨道奖杯,还对网站做了大量小改进!如果你还没查看自己的学习轨道、看看能拿到哪些奖杯,一定要去看看。我们已经给获得一个或更多奖杯的所有人发了邮件,也请留意查收。 八月里,我们在 #12in23 中也玩得很开心,探索了人们通常用来开发应用的语言。

这个月是 Slimline September,我们要探索的是那些语法往往非常简洁凝练的语言。具体来说,我们会看 8th(Forth 的后代)、AWK、Bash、jq、Perl 和 Raku(以前叫 Perl 6)。

徽章

要获得 Slimline September 徽章,你需要在九月里完成这些语言中任意一种的五个练习。

还有一个贯穿全年的 12in23 徽章。要获得它,你需要用该语言解决五个精选练习。

  • Gigasecond:处理日期
  • Atbash Cipher:处理字符串
  • Darts:处理数字和条件
  • Luhn:处理字符串、条件和数字
  • Series:处理字符串和序列

这些练习以及前几个月的练习都可以在 #12in23 页面上找到。

概览

我们来深入了解一下这些语言,先看看每一种的概览。

8th

  • 由 Ron Aaron 开发。
  • 名字是 Forth 语言的双关,Forth 是它的主要灵感来源。不过它和 Forth 有很多不同:
    • 强类型
    • 跨平台
    • 更高的安全性(没有直接内存访问,也没有内置汇编器)
  • 提供免费版和商业版,后者功能更多。
  • 闭源,但购买企业许可证后就可以查看源代码

AWK

  • AWK 是 20 世纪 70 年代由 Alfred Aho、Peter Weinberger 和 Brian Kernighan 在贝尔实验室创造的。这个名字是三位作者姓氏的首字母缩写。
  • 它是一种领域特定语言,专为文本处理而设计,但也可以用于其他用途
  • AWK 和 sed、grep 一样是一种 Unix 过滤器,适合在管道中使用
  • Single UNIX Specification 和 Linux Standard Base 规范都要求任何实现都必须包含它,所以大多数 *nix 机器上都能见到它
  • AWK 语言有多种实现:
    • awk(原版 AWK 也叫 oawk):最初的实现
    • GNU AWK(gawk),1988 年发布,对语言做了大幅修改和扩展
    • BWK AWK(又叫 nawk),90 年代末发布
    • mawk:快速的字节码解释实现
  • 在很多 *nix 系统上,awk 命令是指向 gawk 或 nawk 的符号链接

Bash

  • Bash 是由 Brian Fox 开发的 Unix shell,于 1989 年发布。
  • 它被设计成 Bourne shell 的免费替代品,如今已成为大多数 Linux 发行版的默认登录 shell。它是 Bourne shell 命令语法的超集,因此过渡起来更容易
  • 它在很多方面扩展了 Bourne shell:花括号展开、命令行补全、信号处理等等

jq

  • 由 Stephen Dolan 开发,2012 年发布
  • 旨在让你轻松地查询、转换和操作 JSON 文档(“JSON 版的 sed”)
  • jq 工具(也就是该语言的实现)最初用 Haskell 实现,后来移植到了 C。另外还有基于 Go 和 Rust 的移植版本

Perl

  • Perl 由 Larry Wall 在 20 世纪 80 年代末开发,1987 年首次发布。
  • 它被设计成一种通用脚本语言,让报表处理更容易
  • 影响非常大,尤其是它的正则表达式支持(稍后我们会再聊到)

Raku

  • 由 Larry Wall(Perl 的创造者)设计,2015 年发布
  • 它最初叫 Perl 6,本意是清理这门语言,去掉一些被认为没什么用或令人困惑的特性(Larry Wall 有个有趣的说法:“在 Perl 6 中,我们决定与其修正用户,不如修正语言。”)。结果 Perl 6 与 Perl 5 并不源码兼容,于是改名为 Raku
  • 设计理念的核心是让编程愉快而高效,同时提供各种工具来应对各种各样的编程挑战(通用)
  • 由于 Raku 是一份规范,所以可以有(也确实有)多种实现。目前唯一在积极开发的实现是 Rakudo,但也有一些较老的实现,比如 Pugs(用 Haskell 编写)、v6-KindaPerl6 和 Niecza(面向 CLR)

这些语言都用在哪里?

8th

  • 很遗憾,我们没能找到它在哪些地方被使用

AWK

  • 用于数据提取和报表,以及一般的脚本编写

Bash

  • 主要用于系统管理,也用来提供 CLI 工具或包装其他工具。我们在批量处理 Exercism 代码仓库时大量使用它

jq

  • 用于查询、转换和操作 JSON 文档,通常以 shell 脚本的形式出现

Perl

  • 用于数据操作、文件解析、Web 编程和系统管理任务。凭借字符串处理能力和庞大的模块生态,它在互联网早期就流行起来。

Raku

  • 用于文本处理、系统管理等等

从编程的角度看,这些语言有什么有趣之处?

这些语言大多是动态类型、解释型的,这和它们的脚本语言本质很契合。不过也有一些例外,特别是在支持的编程范式方面。

8th

  • 强类型
  • 多范式:过程式,但更有意思的是基于栈(基于栈的执行模型)、反射(能够检查和修改自身的结构和行为)以及串接式(所有表达式都是函数,函数的并置表示函数组合)
  • 可以编译成本地代码,也可以在 REPL 中解释执行

AWK

  • 动态类型,通常为解释型(取决于所用的实现)
  • 主要范式是数据驱动,你把程序写成一组语句,描述要匹配的数据和所需的处理,而不是明确地定义一系列要执行的步骤。AWK 也支持过程式编程

Bash

  • 动态、解释型语言
  • 支持命令式和过程式编程

jq

  • 动态、解释型语言
  • 纯函数式语言(所有值都不可变),强调“管道”。很有 Unix 的味道

Perl

  • 动态类型、解释型
  • 多范式,支持函数式、面向对象和命令式编程

Raku

  • 动态类型,但支持渐进式类型,可以在需要的地方加上静态类型(Perl 是动态的)
  • 多范式语言:命令式、过程式、面向对象和函数式

它们好在哪里?

8th

  • 语法极少,让这门语言更容易学习和理解。用 JSON 来描述数据(比如对象和数组)。还支持栈、队列、堆等其他容器
  • 没有保留关键字。子程序被称为“word”,而且很容易定义新的 word。不管是内置的还是用户定义的,所有 word 都可以在运行时重新定义
  • 跨平台。可以轻松为任何受支持的平台生成可执行文件
  • 安全。内置安全特性,能防止各种 bug(没有直接内存访问,运行时也不链接动态库)

AWK

  • 语法简单,AWK 代码结构非常一致,因此容易学习和阅读。它的数据结构也简单而灵活
  • 表达力很强,用很少的代码就能做很多事。非常适合写单行脚本
  • 安装在大多数 *nix 机器上,这意味着你能在很多地方用到 AWK 技能(和 /bin/sh 一样,是标准 Unix 中仅有的脚本语言)
  • 在管道和 shell 脚本中表现出色,AWK 可以处理其他工具的输出,反之亦然

Bash

  • 可以在大多数平台上使用。几乎所有 *nix 机器上都装了它,包括 macOS。有了 Windows Subsystem for Linux(WSL),bash 现在也能在 Windows 系统上使用。
  • 可以把它当作 RE(P)L 来用:既可以逐条运行命令,也可以从文件(即 shell 脚本)中读取并执行代码。如果你用过 Linux 终端,那你说不定已经写过 bash 代码了,因为终端通常就是一个 bash RE(P)L
  • Bash 和 shell 脚本广泛用于系统管理、devops 和计算机管理。
  • 极其通用、灵活
  • 强大的字符串处理能力,包括非常直接的字符串插值

jq

  • 处理 JSON 的语法简单、简短,容易学习
  • 允许自定义函数,以应对更复杂的操作。
  • 支持尾递归优化,非常适合递归处理数据
  • jq 工具以单个二进制文件分发,体积只有 30 KB 左右
  • yq 工具封装了 jq,让你可以用同样的语法操作 XML、TOML 和 YAML 文件(它在底层会把这些数据类型转换成 JSON)
  • C 和 Go 两种实现都支持嵌入到其他应用程序中

Perl

  • 能在大多数平台上运行。非常适合编写跨平台脚本
  • 灵活性是 Perl 设计理念的基石。它著名的口号是:“做同一件事的方法不止一种”(TMTOWTDI)。可以根据手头的任务选择不同的做法
  • 社区强大,留下了许多有影响力的项目。很多脚本、工具和应用都是用 Perl 开发的。它曾被称为“把互联网粘在一起的胶带”
  • 模块和库的生态丰富,可以通过 Comprehensive Perl Archive Network(CPAN)获取

Raku

  • 庞大、复杂、强大,但它的设计也让你不必一次性学会全部。上手很容易,之后可以再慢慢接触更强大的特性
  • 类型系统强大且可扩展,还包含渐进式类型。这意味着你可以指定想要的类型检查程度,从而在动态类型和静态类型之间取得平衡
  • 支持多重分派,让你不用继承也能使用多态
  • 在 Raku 里,Unicode 是一等公民。它原生支持处理不同的字符编码
  • 提供高级的并发和并行特性。它内置支持异步编程、响应式编程和并行执行

它们各有什么突出特性?

8th

  • 需要不同的思维方式。它独特的范式组合与其他语言很不一样,会挑战你想出不同的处理办法
  • 基于栈和逆波兰表示法(RPN)的语法,让程序执行的思维模型非常简单。值被放到栈上,大多数 word 都是按它们对栈的影响来定义的

AWK

  • 数据驱动范式非常强大。它需要一种不同的思维方式:程序被定义为一组“条件/动作”对,文本被拆分成记录(通常一行一条记录),每条记录又被拆分成字段(比如 CSV 的字段,或者一个字段一个词)。一旦习惯了这种思路,你就会体会到这种方法的优雅和表达力,并开始到处发现它的用武之地
  • 处理文本的完美选择。无论是解析文本、转换文本还是生成报表,AWK 都能应付。像打印系统上每个用户的 shell、或者给 CSV 的某一列求和这样的任务,你会惊讶于所需代码之少

Bash

  • 自动化的完美选择。shell 脚本非常适合自动化重复性任务。
  • Bash 脚本使用管道,让你轻松地把其他程序粘合起来。写一个把某条命令的输出传给另一条命令的脚本轻而易举,也可以让脚本在执行到任何一条命令失败时就中止。
  • 强大。能如此轻松地使用其他工具,让 bash 成为一件极其强大的工具

jq

  • 非常适合轻松、干净地提取和操作 JSON 数据(如今这种数据多得是)。它已经成为转换 JSON 数据的事实标准工具。你甚至可以用 jq 创建 JSON 数据
  • 支持流式数据,也就是说你可以处理“无限”的数据而不会遇到内存问题
  • 对管道的强调,对熟悉流(比如 Unix 工具)的人来说很容易上手。这也让 jq 代码相当容易分析和理解

Perl

  • 以简洁和表达力著称。用很少的代码就能做很多事
  • 特别适合处理文本,很大程度上得益于它强大的正则表达式支持。尤其是 Perl 5 引入了很多新特性(比如反向引用、命名捕获组和惰性量词)。Philip Hazel 开发了 PCRE(Perl Compatible Regular Expressions),这是一个实现 Perl 5 兼容正则引擎的 C 库。即使是不基于 PCRE 的语言,也常常把自己的正则表达式支持设计成与 PCRE 兼容(因而使用 Perl 5 的语法)

Raku

  • 支持自动线程化的 junction,让并行处理容易得多
  • 支持惰性求值,让你能处理无限列表和序列而不遇到内存问题。这在处理大型数据集,或者涉及无限数据流的算法时特别有用
  • 非常适合文本处理,提供了更简单、更易读、更强大的正则语法
  • 内置支持用 grammar 定义自定义的领域特定语言(DSL)。这样你就能为特定的数据格式或语言创建解析器,更容易处理复杂的文本数据

该试哪一个?

  1. 如果你主要使用 Unix 系统,或者做 devops 相关工作,那 Bash 是一门非常值得学的语言。学 AWK、Perl 或 Raku 也很有好处,而且前两者在很多系统上都是预装的
  2. 如果你要处理 JSON(或 XML/YAML/TOML),jq 是显而易见的选择
  3. 如果你想处理文本,AWK、Perl 和 Raku 是显而易见的选择。
  4. 如果你想尝试点不一样的东西,8th 是个很好的选择
2023年09月01日 · 觉得有用吗?