11 Feb 2024
On February 1st, 2024, A new programming language emerged from Cupertino called Pkl. Pkl is a domain specific programming language intended to provide a way to describe configuration as code.
By default, it is able to render to JSON, PCF, and YAML, amongst other config languages, and a lot of basic code you can write in Pkl is a quine.
When I saw that Pkl had functions and if statements, it immediately became clear to me that Pkl was not only turing complete but also potentially capable of uses beyond its domain.
A couple weeks prior, I had written a basic blog system in bash and decided it'd be a fun task to rewrite this in Pkl, so I got to installing Pkl.
By default, Pkl renders to Pcf, a subset of itself, essentially making a lot of Pkl programs quines. This was not useful for the application I had in mind.
My first idea was to use the following code and render it as YAML:
`Content-Type` = "text/html"
b = 7
This did not work as intended. The output of this code as YAML is
Content-Type: text/html
b: 7
Adding character returns and line feeds at the end of the Content-Type variable also didn't help due to the syntax of YAML:
Content-Type: |
text/html
b: 7
It was at this point that I thought there was no way to do this and I began scouring the language reference with Ctrl+F to find anything and everything that could help me.
I encountered the Module Output section in the language reference which talked about how you could essentially modify how the Pkl renderer worked.
The example code for this was:
a = 10
b {
c = 20
}
output {
value = b
}
which outputted c = 20
, masking the rest of the program. This almost looked exactly like what I wanted but not quite what I needed, so I kept reading.
Then I stumbled on the golden key, output.text
.
output.text
allows you to directly set what the output is going to be, you're able to use variables, concatenation, functions, it's like a normal variable in Pkl but output.text
completely overrides any renderer in effect and allows the programmer to choose what their output is going to look like.
Perfect.
I used my bash blog script as a reference to create the Pkl program.
In comparison to the bash script, I had to find alternatives to the index generator as Pkl cannot execute external programs (the only effect outside of its own state that it can have is HTTP requests) and had to omit the "Retrieved DD/MM/YYYY" text as Pkl cannot natively get time.
An improvement that could be made over what I have written in Pkl was a "main" function which would be the main body of the Pkl program and could be executed via output.text
although this isn't needed
While Pkl can be used as a general purpose programming language, it definitely was not designed to make that easy so I would probably never recommend trying to write Pkl for purposes other than what Apple intended.
Although if you want to make Tim Cook cry or you're just in for a very weird challenge, have at it, the language is quite powerful at string manipulation and has some solid concepts within it so it may be good for doing things with APIs since it has HTTP support and JSON support built-in.
And for anyone curious, the source code for my Pkl CGI blog script is here on my Gitea instance.