Uploaded avatar of iHiD

思维转变五月到啦!

@iHiD
3年多前
视频

介绍

大家好!希望大家都一切顺利。

今年过得真快,转眼就到 Mindshifting May 了。这大概是我最期待的一个月,主要是因为这个月有 Prolog!

希望你们喜欢 Analytical April。参加的人非常多,我觉得它是目前最成功的月份之一。四月里我还和 Simon Peyton Jones 聊了一次,作为 Functional February 的补录访谈。那次访谈真的很棒,我强烈推荐你回看,哪怕只是为了那句绝妙的话:“当命令式编程的石灰岩被侵蚀殆尽,底下显露出来的将是函数式编程的花岗岩。”

好了,进入 Mindshifting May!和往常一样,Erik 和我先给大家简单介绍一下这个月的主题,以及我们要探索的几门语言。

这个月我们足足有六门语言:Ballerina、Pharo、Prolog、Red、Tcl(Tickle)和 Unison。这些语言每一门都和比较“主流”的语言很不一样,所以建议你多试几门,感受一下它们的不同之处。我特别推荐 Prolog,因为它是我这一生中写代码写得最享受的语言之一。Erik 也对 Unison 充满热情,所以那也是一门值得一试的语言。

徽章

要拿到 Mindshifting May 徽章,你需要在五月期间用其中任意一门语言完成任意五道练习。

还有贯穿全年的 12in23 徽章。要拿到它,你需要用这门语言解出五道精选练习。如果你是在五月之后看到这些内容,这一部分在年内任何时候都可以完成,所以你没有错过。挑选这些练习并不容易,因为这些语言彼此差异太大,所以我们选了一些更通用的练习,解起来有趣,也适合探索不同的解法。

  • 首字母缩写:把一个短语转换成的首字母缩写
  • 等字母词:检查一个短语里是否含有重复的字母
  • 罗马数字:把十进制数字转换成罗马数字
  • 雨滴:把一个数字转换成雨滴声
  • 太空时代:计算一个人在太阳系各行星上的年龄

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

语言概览

下面我们逐一深入了解一下这些语言。

Prolog:

  • 思维方式不同。程序被定义为一组关系。然后你通过合一(模式匹配)来“查询”这个关系数据库,找出答案。非常适合基于规则的系统
  • 语法很少,只有一种数据类型(项)和一种语言结构元素(子句)。子句完全由项构成,可以定义事实或规则。
  • 非常声明式。不必太关心计算是怎么进行的,而要更关注应该计算什么。很多情况下,这意味着更少的代码
  • 专为查询大型搜索空间而设计。支持不同的搜索策略(深度优先、广度优先),并支持自动剪枝

Unison

  • Unison 代码里没有版本冲突!Unison 函数知道自己依赖项的哈希值,因此能找到它需要的正确版本代码。
  • Unison 支持在本地开发界面和托管仓库中实时浏览代码,所以你总能点进去查看所依赖库的源代码。
  • Abilities 是一种以纯函数式方式管理“效果”(例如 IO)的方法

Pharo

  • 语法极少,整个语法能写在一张明信片上(只有 6 个保留字!)。消息语法模仿自然语言,有主语、动词和补语(between: 1 and: 2 +)。语义也很简单(例如极其简单的优先级规则)。这让它更容易学习和阅读
  • 一旦跨过最初的学习曲线,开发效率就非常高。原因有很多,包括简单的语义和极少的语法,也有后面会提到的 Pharo 一些突出特性
  • 能在大多数平台上运行(Windows、macOS、Linux,并支持 ARM),运行在快速的虚拟机(OpenSmalltalk)之上
  • 它不只是一个 Smalltalk 实现,而且仍在积极开发中(最新的 Smalltalk 版本是 1980 年的 Smalltalk 80)
  • 社区友好

Tcl(读作 “tickle”)

  • 语法极少,只有 12 条规则,一张纸就能写下。语义也相对直白。这让程序容易阅读和学习
  • 通过协程实现简单的并发,可以让异步代码写起来像同步代码一样
  • 内置事件循环,用于网络编程和异步文件 I/O
  • 成熟,但仍在演进

Ballerina

  • 通过语言内置查询,对 JSON、XML 和表格数据提供类型安全的声明式处理,是一等公民级别的支持
  • 灵活的类型,结构化类型(鸭子类型)很常见。封闭类型用于实现子类型,而开放类型则能优雅地处理发送过来的过多数据。用于 HTTP 资源时内置数据绑定和验证
  • 内置对常见集成模式和连接器的支持,包括分布式事务、补偿和断路器
  • 每个 Ballerina 程序都能被任何 Open Telemetry 工具自动观测,让你完全掌控并看清代码的行为和性能。
  • 通过 strand(轻量级线程)实现出色的并发。非阻塞 IO 调用很容易。编译器可以帮助检查 worker 之间的发送和接收调用,避免死锁。不可变性对网络编程也很有利
  • 通过联合类型显式处理错误,并用 check 语法糖来帮忙

Red

  • 轻量。整个工具链下载下来约 1.5 MB,单个可执行文件。
  • 可移植。交叉编译容易。生成的二进制文件小,且没有依赖。内存占用低。
  • Red 有自己的元语言和数据格式(类似 LISP)。程序可以转换和读取代码。
  • 响应式:对象可以互相链接,从而减小程序的体积和复杂度(想想 Excel 表格)

这些语言用在哪些地方?

Prolog:

  • 人工智能(IBM 的 Watson)
  • (自然)语言处理
  • 用于知识库的分布式数据库(TerminusDB)
  • 甚至被用来描述 Java 虚拟机的类型规则

Unison

  • 用于编写分布式系统
  • 通用 Web 服务
  • 批处理计算任务

Pharo

  • 用于交互式工具
  • 应用于差异很大的领域:在线交易平台,以及投资管理的云端工具
  • 国防行业的用户界面和交互原型设计
  • 用于活动策划的 Web 应用
  • 用于探索 API、数据和系统的可塑开发环境工具

Tcl

  • 用作胶水代码或嵌入到其他系统中
  • 用于 CISCO 路由器的图形界面
  • 各种制造系统
  • NASA 多次使用它
  • 其他大公司还包括 Pixar、Boeing、Intel、NBC 等等。
  • Tk 这个窗口工具包已被 perl/python/ruby 等其他“脚本”语言采用。
  • Expect 是一个用来自动化交互式 CLI 应用的工具

Ballerina

  • 用于云原生应用
  • MOSIP 使用它。MOSIP 是一个基础身份平台,帮助政府和其他组织以低成本实现数字身份和基础身份系统。

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

Prolog:

  • 逻辑编程语言(最早的一批之一),本身就是一种范式(和面向对象、函数式编程一样)
  • 动态类型

Unison

  • 纯函数式语言
  • 静态类型

Pharo

  • 面向对象的语言,但属于 Smalltalk 意义上的面向对象。和“常规”面向对象语言不同:没有构造函数,没有类型声明,没有接口,也没有基本类型。
  • 动态类型

Tcl

  • 多范式:支持面向对象、命令式和函数式风格
  • 动态类型

Ballerina

  • 多范式:面向对象、函数式和声明式
  • 静态类型

Red

  • 多范式:命令式、函数式、面向对象、符号式和响应式
  • 静态类型

它们各自有哪些突出特性?

Prolog:

  • 灵活。许多内置谓词能在多个方向上工作。可以用同一套语法查询和创建数据。有些在其他语言里很棘手的问题,在这里轻而易举
  • DCG 就像一个内置的解析器组合子,非常适合解析、生成、补全和检查序列
  • CLP 是一种用约束来定义程序的高效方式

Unison

  • 代码不是文本,而是(不可变的)数据。代码存储在数据库里,通过 Unison Codebase Manager 访问和更新。文本文件只是把代码放进数据库的一种方式。不可变数据还意味着测试结果可以被缓存,类型检查也只需做一次
  • 定义通过哈希值引用,而不是通过名字。这被称为“内容寻址”代码。一个定义的语法树决定它的哈希值。没有版本冲突,重命名也很简单。
  • Unison 文档是语言中的一等实体,并且始终与它们所描述的函数保持同步。你可以在文档里嵌入可运行的示例,并确保示例代码能编译通过。
  • 非常适合云计算:不需要构建,函数可以即时分发,为 Unison 服务间通信编写编解码器的时间也更少。

Pharo

  • 直白的执行模型:一切都是对象,执行完全通过消息发生(消息本身也是对象)。连控制流也是通过消息完成的。这个模型虽然简单,却非常强大。和其他面向对象语言很不一样。
  • 你的代码存在于 Pharo 镜像里,而不是文本文件中。Pharo 镜像包含应用程序的整个状态,可以在 Pharo 虚拟机中执行。当你保存工作时,Pharo 会把环境的整个状态保存为镜像文件。这个文件包含所有对象、它们之间的关系以及执行上下文。镜像文件可以分享给别人,也可以加载到不同的机器或平台上。这让开发者能轻松地在项目上协作,或分发用 Pharo 构建的应用程序
  • 实时而沉浸,运行时通过 Pharo 专用 IDE 即时获得反馈。可以随时运行和修改程序,甚至在程序运行时也可以!强大的调试器,支持重启方法和随时修复 bug

Tcl

  • 直白的类型系统:一切都是字符串。“一切都是字符串”曾是 Tcl 的实现方式。如今在底层,它有一套健壮的类型系统,Tcl 实体(无论是字符串、浮点数、数组还是字典)既有特定类型的表示,也有字符串表示。这大大提升了 Tcl 代码的性能,因为它不再需要在字符串之间来回转换。
  • “一切以命令运行”。Tcl 没有内置命令。它自带一套命令“标准库”,其中包括 if 和 while 等。添加新的控制流命令非常简单,比如一个 until 循环。覆盖 Tcl 命令也很容易。
  • 由于体积小、语义简单,且以 C 库实现,因此很容易嵌入

Ballerina

  • 云原生。内置从 JSON 到用户自定义类型的转换。创建(微)服务的语法极其轻量。服务的并发执行是内置的。开箱即支持 HTTP(1 和 2)、graphql 和 gRPC
  • 自动生成工件,把你的代码部署到不同的云上。这些工件可以是 Dockerfile、Docker 镜像、Kubernetes YAML 文件,或者无服务器函数。
  • 内置把代码可视化为序列图的功能。非常适合可视化代码流程。甚至可以可视化 HTTP 调用

Red

  • 非常适合构建和解析领域特定语言/“方言”(Rebol 的术语)。内置了好几种方言:
  • Red/System:一种 C 级别的系统编程语言,编译为原生代码
  • Parse:一个强大的 PEG 解析器
  • VID:一种简单的 GUI 布局创建方言
  • Draw:一种矢量 2D 绘图方言
  • Rich-text:一种富文本描述方言
  • 易用的 GUI。完全跨平台且原生。支持双向绑定、实时更新、事件,并能访问操作系统的各种功能

五月里应该尝试哪一门(或哪几门)?

这些语言各自都很有意思,所以每一门都有值得推荐的理由。

  • 如果你对云计算感兴趣,Ballerina 和 Unison 都是很好的选择。Tcl 也有很棒的并发特性
  • 如果你熟悉面向对象编程,但想看看另一种诠释,试试 Pharo
  • 如果你想体验一下用一门不依赖文本文件的语言编程是什么感觉,可以试试 Pharo 及其独特而强大的 IDE,或者试试配上 Unison Codebase Manager 的 Unison。
  • 如果你喜欢极简,Tcl、Prolog、Pharo 和 Red 的语法都相当少,语义也相对简单
  • 如果你想看看范式的有趣融合,Ballerina、Tcl 和 Red 都支持多种不同的范式
  • 如果你想尝试一些更不寻常的范式,可以试试 Prolog 的逻辑编程、Red 的响应式编程,以及 Ballerina 的声明式编程
  • 如果你喜欢函数式编程,不妨看看 Unison,尤其是它的 Abilities。
  • 如果你对元编程感兴趣,Tcl、Prolog、Pharo 和 Red 都提供了很好的支持

当然,如果你有时间,我建议你尝试几门!它们每一门都很独特。挑几门推荐语言,去解同一道练习,看看实现差别有多大。

2023年05月01日 · 觉得有用吗?