编程语言引发大厂“内卷”现象,苹果开源PKL语言,是否因为对JSON、YAML感到厌倦?

发表时间: 2024-02-05 21:16

编译 | 屠敏
出品 | CSDN(ID:CSDNnews)

编程语言数以千计,但是面对不同场景的需求,很多语言依然存在诸多不足,进而促使更多语言的落地。

近日,苹果开源了一款全新的编程语言——Pkl(https://pkl-lang.org/index.html),需要注意的是虽然它和 Python 里保存文件的一种格式同名,但这里的 Pkl 是一种专用于创建配置文件的脚本语言。

值得一提的是,Pkl 语言的开发团队这一次没有选择使用苹果自己研发的 Swift 语言,而是主要使用了 Java、Kotlin。

弥补 JSON、YAML 不足,苹果发布 Pkl 语言

谈及现在市面已有的成熟配置语言,很多开发者首先想到的便是 INI、XML、JSON、YAML 等,但是在苹果开发团队看来,这些语言虽然有相应的优点,但是当配置变得越来越复杂时,它们的缺点也异常明显。

为此,Pkl 开发团队还特别在官网中放了一张“比较”页面,指出传统配置语言的种种缺点,如:

  1. 它们对于阅读和书写来说不太友好。 (JSON、XML)

  2. 它们不提供将大文件拆分为多个小文件的方法。 (JSON、YAML)

  3. 它们没有提供任何方法或非常有限的方法来抽象重复的配置 (JSON、YAML、XML)

  4. 它们不提供标准化或广泛可用的模式验证器。 (JSON、YAML)

  5. 们提供很少或根本不提供模式感知工具。 (JSON、YAML)

也许有人会说,当配置需求超出静态配置格式的能力时,他们往往会采用通用编程语言如 Python、Kotlin、Ruby 或 JavaScript 来生成配置。然而,这些功能强大语言用于描述配置时,可能会显得很笨拙,因为它们不是以定义和验证数据为导向的。此外,这些 DSL 往往与它们自己的生态系统捆绑在一起。如使用 Kotlin DSL 作为用 Go 编写的应用程序的配置层是很困难的。

基于这样的大背景下,苹果开发团队在内部创建了 Pkl 语言,在其看来,“配置的最佳表现形式是静态语言与通用编程语言的融合”。

Pkl 希望取两者之长,提供一种声明式、读写简单的语言,同时借用通用语言的功能来增强其功能。为此,该开发团队在文档中透露,设计 Pkl 时,他们遵循了三个首要目标:

  • 通过在部署前捕获验证错误来提供安全性。

  • 从简单用例扩展到复杂用例。

  • 集成一流的 IDE,让编程变得更加轻松。

Pkl 功能特性

在最初的设想中,苹果开发团队表示,编写 Pkl 代码时,开发者可以使用自己所期望的语言功能,如类、函数、条件和循环;也可以构建抽象层,并通过创建包和发布包来共享代码;最重要的是,希望开发者还可以使用 Pkl 满足多种不同类型的配置需求。让 Pkl 既可以用来生成任何格式的静态配置文件,也可以作为一个库嵌入到另一个应用程序运行时中。

可以通过官方示例初步感受一下 Pkl 语言,以下是一个 Pkl 文件(模块),定义了一个虚构的 Web 应用程序的配置模式。

Application.pkl

module Application

/// The hostname that this server responds to.
hostname: String

/// The port to listen on.
port: UInt16

/// The environment to deploy to.
environment: Environment

/// The database connection for this application
database: Database

class Database {
/// The username for this database.
username: String

/// The password for this database.
password: String

/// The remote host for this database.
host: String

/// The remote port for this database.
port: UInt16

/// The name of the database.
dbName: String
}

typealias Environment = "dev"|"qa"|"prod"

下面是配置数据的定义方式:

localhost.pkl

amends "Application.pkl"

hostname = "localhost"

port = 3599

environment = "dev"

database {
host = "localhost"
port = 5786
username = "admin"
password = read("env:DATABASE_PASSWORD")
dbName = "myapp"
}

根据官方介绍,Pkl 程序可以轻松转为 JSON、YAML、属性列表等任意静态配置格式。如把它转为主流的 YAML 格式:

$ export DATABASE_PASSWORD=hunter2
$ pkl eval --format yaml sidecars.pkl
可以得到如下结果:
sidecars:
- username: admin
password: hunter2
host: localhost
port: 6000
dbName: myapp
- username: admin
password: hunter2
host: localhost
port: 6001
dbName: myapp
- username: admin
password: hunter2
host: localhost
port: 6002
dbName: myapp
- username: admin
password: hunter2
host: localhost
port: 6003
dbName: myapp
要知道,和传统用于配置的编程语言不同,Pkl 在官方网站上明确标注了“Configuration that is Programmable, Scalable, and Safe” (可编程、可扩展和安全的配置语言)的 Slogan,主打一个安全性,其内置了验证环节。
根据官方文档显示,在 Pkl 中,验证是通过类型注解实现的。而且,类型注解可以选择定义约束条件。
下面是一个定义了以下约束的示例:
  • 年龄必须在 0 和 130 之间。

  • name 不能为空。

  • zipCode 必须是包含五位数字的字符串。

Person.pkl

module Person

name: String(!isEmpty)

age: Int(isBetween(0, 130))

zipCode: String(matches(Regex("\d{5}")))

失败的约束会导致评估错误。

alessandra.pkl

amends "Person.pkl"

name = "Alessandra"

age = -5

zipCode = "90210"

评估该模块失败:

$ pkl eval alessandra.pkl
–– Pkl Error ––
Type constraint `isBetween(0, 130)` violated.
Value: -5

5 | age: Int(isBetween(0, 130))
^^^^^^^^^^^^^^^^^
at Person#age (file:///Person.pkl)

5 | age = -5
^^
at alessandra#age (file:///alessandra.pkl)

106 | text = renderer.renderDocument(value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
at pkl.base#Module.output.text (https://github.com/apple/pkl/blob/0.25.0/stdlib/base.pkl#L106)

共享软件包

此外,Pkl 还提供了发布软件包的功能,并可在项目中将其作为依赖项导入。这为共享可用于其他项目的 Pkl 代码提供了一种简便的方法。

你可以轻松创建自己的软件包并将其发布到 GitHub,或将其上传到任何地方。

软件包可通过固定的 URI 导入:

import "package://pkg.pkl-lang.org/pkl-pantry/pkl.toml@1.0.0#/toml.pkl"

output {
renderer = new toml.Renderer {}
}

另外,它们也可以作为项目的依赖项来管理。你可以用更简单的名称导入软件包。

PklProject

amends "pkl:Project"

dependencies {
["toml"] { uri = "package://pkg.pkl-lang.org/pkl-pantry/pkl.toml@1.0.0" }
}

myconfig.pkl

import "@toml/toml.pkl"

output {
renderer = new toml.Renderer {}
}

支持 Swift、Go、Java 和 Kotlin 语言

Pkl 可以以文本输出的形式生成配置,也可以通过语言绑定以库的形式嵌入到其他语言中,并支持 Java、Kotlin、Swift 和 Go 语言的代码生成。

如 Pkl 代码为:

module example.MyAppConfig

/// The hostname for the application
host: String

/// The port to listen on
port: UInt16(this > 1000)

Java 代码:

package example;

public final class MyAppConfig {
/**
* The hostname for the application
*/

public final @Non String host;

/**
* The port to listen on
*/

public final int port;

public MyAppConfig(
@Named("host")
@Non String host,
@Named("port") int port)
{
this.host = host;
this.port = port;
}

public MyAppConfig withHost(@Non String host) { /*...*/ }

public MyAppConfig withPort(int port) { /*...*/ }

@Override
public boolean equals(Object obj) { /*...*/ }

@Override
public int hashCode() { /*...*/ }

@Override
public String toString() { /*...*/ }
}

当绑定到一种语言时,Pkl 模式可在目标语言中生成类/结构体。使用代码生成只是将 Pkl 嵌入应用程序的众多方法之一。苹果开发团队在 Pkl 语言绑定功能中还提供了评估器应用程序接口(API),用于在底层控制 Pkl 评估,用户可在对其应用程序最有意义的抽象层与 Pkl 自由交互。

支持 IntelliJ、Visual Studio Code 和 Neovim 编辑器

“编程语言的好坏取决于编写经验。因此,我们致力于提供一流的编辑器支持。在编辑器中编写 Pkl 时,用户将在指导下完成从给定模板中填写配置数据的过程。此外,如果有任何值无效,编辑器会提供即时反馈,并在需要时立即提供文档”,苹果开发团队说道。

基于此,其发布了 IntelliJ、VS Code 和 neovim 插件,支持包括 IntelliJ、Webstorm、GoLand 和 PyCharm 等编辑器。这些插件能够分析 Pkl 程序,并提供自动完成、导航和验证等功能。

自动完成

导航

验证

除此之外,苹果下一步也计划支持语言服务器协议。

我们是否需要多一门新的配置语言?

苹果这门新语言发布后不久,便吸引了很多开发者的关注。在 GitHub(https://github.com/apple/pkl)上,短短几天的时间,GitHub Star 已经超过 1.5k。

同时,这款可用于从小到大、简单到复杂、临时或重复的各种配置任务的 Pkl 语言,也在 HN、推特上引起了不少的讨论。

对于又一新语言来临,有开发者直言道:

  • 所有不能消灭现有配置语言的新语言,带来的结果都是开发者要在多一个不同语言的多个配置语言中来回穿梭。

  • 自从开源的数据约束语言 cue 出现以后,大厂们都开始卷配置文件了。

还有网友吐槽表示:“25 年前,几乎每个程序都有一个 GUI 来进行配置。并配有帮助文本。在 Windows 系统中,程序要么将内容保存到 ini 文件中,要么保存到 Windows 注册表中,两者都可以手动编辑。

如今,我们有了一种编程语言,它可以用 87 MB 的二进制文件创建配置文件。要运行这种编程语言,你需要手动创建一个......配置文件。因此,我们现在缺少的是一个 500GB 的框架,它可以为编程语言编写配置文件,而编程语言又可以为我希望使用的实际程序编写配置文件。我很抱歉,但很明显,今天的‘开发人员’中,有很大一部分都是在制造问题。”

对此,你如何看待苹果最新配置语言 Pkl 的到来?

来源:

https://news.ycombinator.com/item?id=39232976

https://pkl-lang.org/blog/introducing-pkl.html