编程语言数以千计,但是面对不同场景的需求,很多语言依然存在诸多不足,进而促使更多语言的落地。
值得一提的是,Pkl语言的开发团队这一次没有选择使用苹果自己研发的Swift语言,而是主要使用了Java、Kotlin。
弥补JSON、YAML不足,苹果发布Pkl语言
谈及现在市面已有的成熟配置语言,很多开发者首先想到的便是INI、XML、JSON、YAML等,但是在苹果开发团队看来,这些语言虽然有相应的优点,但是当配置变得越来越复杂时,它们的缺点也异常明显。
为此,Pkl开发团队还特别在官网中放了一张“比较”页面,指出传统配置语言的种种缺点,如:
也许有人会说,当配置需求超出静态配置格式的能力时,他们往往会采用通用编程语言如Python、Kotlin、Ruby或JavaScript来生成配置。然而,这些功能强大语言用于描述配置时,可能会显得很笨拙,因为它们不是以定义和验证数据为导向的。此外,这些DSL往往与它们自己的生态系统捆绑在一起。如使用KotlinDSL作为用Go编写的应用程序的配置层是很困难的。
基于这样的大背景下,苹果开发团队在内部创建了Pkl语言,在其看来,“配置的最佳表现形式是静态语言与通用编程语言的融合”。
Pkl功能特性
在最初的设想中,苹果开发团队表示,编写Pkl代码时,开发者可以使用自己所期望的语言功能,如类、函数、条件和循环;也可以构建抽象层,并通过创建包和发布包来共享代码;最重要的是,希望开发者还可以使用Pkl满足多种不同类型的配置需求。让Pkl既可以用来生成任何格式的静态配置文件,也可以作为一个库嵌入到另一个应用程序运行时中。
可以通过官方示例初步感受一下Pkl语言,以下是一个Pkl文件(模块),定义了一个虚构的Web应用程序的配置模式。
Application.pkl
moduleApplication
///Thehostnamethatthisserverrespondsto.hostname:String
///Theporttolistenon.port:UInt16
///Theenvironmenttodeployto.environment:Environment
///Thedatabaseconnectionforthisapplicationdatabase:Database
classDatabase{///Theusernameforthisdatabase.username:String
///Thepasswordforthisdatabase.password:String
///Theremotehostforthisdatabase.host:String
///Theremoteportforthisdatabase.port:UInt16
///Thenameofthedatabase.dbName:String}
typealiasEnvironment="dev"|"qa"|"prod"
下面是配置数据的定义方式:
localhost.pkl
amends"Application.pkl"
hostname="localhost"
port=3599
environment="dev"
database{host="localhost"port=5786username="admin"password=read("env:DATABASE_PASSWORD")dbName="myapp"}
根据官方介绍,Pkl程序可以轻松转为JSON、YAML、属性列表等任意静态配置格式。如把它转为主流的YAML格式:
$exportDATABASE_PASSWORD=hunter2$pkleval--formatyamlsidecars.pkl可以得到如下结果:sidecars:-username:adminpassword:hunter2host:localhostport:6000dbName:myapp-username:adminpassword:hunter2host:localhostport:6001dbName:myapp-username:adminpassword:hunter2host:localhostport:6002dbName:myapp-username:adminpassword:hunter2host:localhostport:6003dbName:myapp要知道,和传统用于配置的编程语言不同,Pkl在官方网站上明确标注了“ConfigurationthatisProgrammable,Scalable,andSafe”(可编程、可扩展和安全的配置语言)的Slogan,主打一个安全性,其内置了验证环节。根据官方文档显示,在Pkl中,验证是通过类型注解实现的。而且,类型注解可以选择定义约束条件。下面是一个定义了以下约束的示例:
Person.pkl
modulePerson
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"
评估该模块失败:
$pklevalalessandra.pkl––PklError––Typeconstraint`isBetween(0,130)`violated.Value:-5
5|age:Int(isBetween(0,130))^^^^^^^^^^^^^^^^^atPerson#age(file:///Person.pkl)
5|age=-5^^atalessandra#age(file:///alessandra.pkl)
共享软件包
此外,Pkl还提供了发布软件包的功能,并可在项目中将其作为依赖项导入。这为共享可用于其他项目的Pkl代码提供了一种简便的方法。
你可以轻松创建自己的软件包并将其发布到GitHub,或将其上传到任何地方。
软件包可通过固定的URI导入:
import"package://pkg.pkl-lang.org/pkl-pantry/pkl.toml@1.0.0#/toml.pkl"
output{renderer=newtoml.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"
支持Swift、Go、Java和Kotlin语言
Pkl可以以文本输出的形式生成配置,也可以通过语言绑定以库的形式嵌入到其他语言中,并支持Java、Kotlin、Swift和Go语言的代码生成。
如Pkl代码为:
moduleexample.MyAppConfig
///Thehostnamefortheapplicationhost:String
///Theporttolistenonport:UInt16(this>1000)
Java代码:
packageexample;
publicfinalclassMyAppConfig{/***Thehostnamefortheapplication*/publicfinal@NonNullStringhost;
/***Theporttolistenon*/publicfinalintport;
publicMyAppConfig(@Named("host")@NonNullStringhost,@Named("port")intport){this.host=host;this.port=port;}
publicMyAppConfigwithHost(@NonNullStringhost){/*...*/}
publicMyAppConfigwithPort(intport){/*...*/}
@Overridepublicbooleanequals(Objectobj){/*...*/}
@OverridepublicinthashCode(){/*...*/}
@OverridepublicStringtoString(){/*...*/}}
当绑定到一种语言时,Pkl模式可在目标语言中生成类/结构体。使用代码生成只是将Pkl嵌入应用程序的众多方法之一。苹果开发团队在Pkl语言绑定功能中还提供了评估器应用程序接口(API),用于在底层控制Pkl评估,用户可在对其应用程序最有意义的抽象层与Pkl自由交互。
支持IntelliJ、VisualStudioCode和Neovim编辑器
“编程语言的好坏取决于编写经验。因此,我们致力于提供一流的编辑器支持。在编辑器中编写Pkl时,用户将在指导下完成从给定模板中填写配置数据的过程。此外,如果有任何值无效,编辑器会提供即时反馈,并在需要时立即提供文档”,苹果开发团队说道。
基于此,其发布了IntelliJ、VSCode和neovim插件,支持包括IntelliJ、Webstorm、GoLand和PyCharm等编辑器。这些插件能够分析Pkl程序,并提供自动完成、导航和验证等功能。
自动完成
导航
验证
除此之外,苹果下一步也计划支持语言服务器协议。
我们是否需要多一门新的配置语言?
同时,这款可用于从小到大、简单到复杂、临时或重复的各种配置任务的Pkl语言,也在HN、推特上引起了不少的讨论。
对于又一新语言来临,有开发者直言道:
还有网友吐槽表示:“25年前,几乎每个程序都有一个GUI来进行配置。并配有帮助文本。在Windows系统中,程序要么将内容保存到ini文件中,要么保存到Windows注册表中,两者都可以手动编辑。
如今,我们有了一种编程语言,它可以用87MB的二进制文件创建配置文件。要运行这种编程语言,你需要手动创建一个......配置文件。因此,我们现在缺少的是一个500GB的框架,它可以为编程语言编写配置文件,而编程语言又可以为我希望使用的实际程序编写配置文件。我很抱歉,但很明显,今天的‘开发人员’中,有很大一部分都是在制造问题。”