Apple ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π» Pkl, язык программирования для опрСдСлСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ

Компания Apple ΠΎΡ‚ΠΊΡ€Ρ‹Π»Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ языка программирования Pkl, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ для опрСдСлСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ³Π°ΡŽΡ‰Π΅Π³ΠΎ модСль «ΠΊΠΎΠ½Ρ„игурация ΠΊΠ°ΠΊ ΠΊΠΎΠ΄». Бвязанный с Pkl инструмСнтарий написан Π½Π° Kotlin ΠΈ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½ ΠΏΠΎΠ΄ Π»ΠΈΡ†Π΅Π½Π·ΠΈΠ΅ΠΉ Apache. ΠŸΠ»Π°Π³ΠΈΠ½Ρ‹ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΊΠΎΠ΄ΠΎΠΌ Π½Π° языкС Pkl ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Ρ‹ для срСд Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ IntelliJ, Visual Studio Code ΠΈ Neovim. Π’ блиТайшСС врСмя оТидаСтся публикация ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° LSP (Language Server Protocol).

Pkl сочСтаСт свойства простого для восприятия Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ языка c Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹ΠΌΠΈ возмоТностями, свойствСнными для языков ΠΎΠ±Ρ‰Π΅Π³ΠΎ назначСния. Π’ языкС ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ², классы, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ выраТСния, условия ΠΈ Ρ†ΠΈΠΊΠ»Ρ‹. Pkl ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ ΠΊΠ°ΠΊ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ статичСских ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ Π² Ρ€Π°Π·Π½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°Ρ…, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ JSON, YAML ΠΈ XML, Ρ‚Π°ΠΊ для формирования ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π·Π°Π΄Π°Π½Π½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π² прилоТСниях Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… языках программирования.

ΠŸΡ€ΠΈΠ²ΡΠ·ΠΊΠΈ для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ Pkl Π² прилоТСния ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Ρ‹ для Java, Kotlin, Go ΠΈ Swift. ΠžΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ с Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠΌ Spring. ΠŸΡ€ΠΈΠ²ΡΠ·ΠΊΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π° основС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π½Π° языкС Pkl ΡΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ с классами для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с описанной ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ. ΠŸΠ°ΠΊΠ΅Ρ‚Ρ‹ с описаниСм ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² рСпозиториях ΠΈ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² качСствС зависимости, Ρ‡Ρ‚ΠΎ допускаСт совмСстноС использованиС ΠΊΠΎΠ΄Π° Pkl ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°ΠΌΠΈ.

Π―Π·Ρ‹ΠΊ прСдоставляСт Π³ΠΈΠ±ΠΊΠΈΠ΅ срСдства для опрСдСлСния условий ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ коррСктности Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΡ… Π²Ρ‹ΡΠ²Π»ΡΡ‚ΡŒ ошибки Π² ΠΈΡ‚ΠΎΠ³ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π½Π° этапС Π΄ΠΎ Π΅Ρ‘ примСнСния Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ. НапримСр, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ допустимый Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ («port: Int(this > 1000)» ΠΈΠ»ΠΈ «age: Int(isBetween(0, 130))»), ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈΠ»ΠΈ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ заполнСния ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ («zipCode: String(matches(Regex(«\\d{5}»)))»). Π’ случаС присвоСния значСния, Π½Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ, Π²Π°Π»ΠΈΠ΄Π°Ρ‚ΠΎΡ€ Π²Ρ‹Π²Π΅Π΄Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 1001 ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠΌΡƒ ΠΊΠ°ΠΊ «Int(this > 1000)»).

НапримСр, Π½Π° языкС Pkl ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Application.pkl с шаблоном ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊ Π‘Π£Π‘Π”: module Application hostname: String port: UInt16 environment: Environment database: Database class Database { username: String password: String host: String port: UInt16 dbName: String } typealias Environment = «dev»|»qa»|»prod»

Π”Π°Π»Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ нСпосрСдствСнно Ρ„Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ коррСктности Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ: amends «Application.pkl» hostname = «localhost» port = 3599 environment = «dev» database { host = «localhost» port = 5786 username = «admin» password = read(«env:DATABASE_PASSWORD») dbName = «myapp» }

А Ρ‚Π°ΠΊΠΆΠ΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ для Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ измСнСния Π½ΠΎΠΌΠ΅Ρ€Π° ΠΏΠΎΡ€Ρ‚Π° для Ρ‡Π΅Ρ‚Ρ‹Ρ€Ρ‘Ρ… Ρ€Π°Π·Π½Ρ‹Ρ… Π‘Π£Π‘Π”: import «Application.pkl» hidden db: Application.Database = new { host = «localhost» username = «admin» password = read(«env:DATABASE_PASSWORD») dbName = «myapp» } sidecars { for (offset in List(0, 1, 2, 3)) { (db) { port = 6000 + offset } } }

ΠŸΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, YAML: 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 Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½Π° Π² классы ΠΈΠ»ΠΈ структуры для встраивания Π² ΠΊΠΎΠ΄ прилоТСния. НапримСр, ΠΌΠΎΠΆΠ½ΠΎ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ привязку для Kotlin: import kotlin.Int import kotlin.Long import kotlin.String data class Application( val hostname: String, val port: Int, val environment: Environment, val database: Database ) { data class Database( val username: String, val password: String, val host: String, val port: Int, val dbName: String ) enum class Environment( val value: String ) { DEV(«dev»), QA(«qa»), PROD(«prod»); override fun toString() = value } }

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: opennet.ru