Get the top HN stories in your inbox every day.
dang
mimischi
Did all the timestamps get reset? Seeing most (all?) comments at about 30min ago
dang
Ah sorry - that was an unintended side-effect of re-upping the original submission. I must have done some of the steps in the wrong order.
notso411
You mean you don’t have a distributed merge post microservice that emits post migration events, which are then consumed by a post owner conversion service using your existing event-driven architecture to facilitate seamless data synchronization and user notification processes??? That is not very hacker news of you from the guy who owns hacker news.
notso411
[dead]
grashalm
Pkl was built using the GraalVM Truffle framework. So it supports runtime compilation using Futamura Projections. We have been working with Apple on this for a while, and I am quite happy that we can finally read the sources!
https://github.com/oracle/graal/tree/master/truffle
Disclaimer: graalvm dev here.
Edit: typo
krajzeg
> ...GraalVM Truffle framework... Futurama Projections...
I know it's partly on me for not knowing the domain, but I honestly suspected somebody is trying to make fun of me with some concentrated technobabble.
Especially since I wouldn't expect the topic (configuration languages) to require complex mathematical machinery to work with. Now I have something interesting to dig into.
TimTheTinker
What has most impressed me about GraalVM and Truffle is their capability of deep-optimizing high-level code like Python and Ruby.
I once saw a demo where someone took a simple operation in Ruby using inefficient-but-elegant syntax (including creating and sorting an array, where a simple loop would have been the appropriate approach in C). He compiled that using TruffleRuby and the entire array construction and sorting was completely optimized out of the generated bytecode.
Alifatisk
Really? Link?
grashalm
Shameless self plug: Giving an introduction in this video: https://youtu.be/pksRrON5XfU?si=CmutoA5Fcwa287Yl
refulgentis
Gently teasing: linking a 2 hour video with "shameless self plug" definitely did _not_ help obviate the surreality.
hoherd
I'm not sure if it was part of the humor, so pardon me if it was, but it's actually "Futamura" as in Yoshihiko Futamura, not "Futurama".
https://en.wikipedia.org/wiki/Partial_evaluation#Futamura_pr...
Xiol32
Really glad it wasn't just me. Genuinely thought someone was trying to make a joke.
avisser
Same - it doesn't help that I read Futamura as Futurama the first 3 times.
tomcam
Same. There was a mini subthread years ago that applies.
EPWN3D
Glad I'm not the only one who had this reaction. I just can't bring myself to accept that a problem that could be solved with a slightly better version of JSON or property lists requires this many buzzwords.
duped
Those aren't "buzzwords" though, it's a very specific way to implement programming languages. It's not really meaningful except for the PL implementation nerds.
Especially the Futamura projections. It's almost magic and very few people have even heard of them.
usrusr
If Futamurma means what I think it means skimming across the Wikipedia entry, it would mean that simple value-holder-file configurations would be parsed and checked at the speed of a general purpose tokenizer. But without closing the door to what the language can express in more elaborate configuration file "landscapes". Best of both worlds and presumably all without requiring anybody but the toolmakers to understand what the buzzwords really mean.
paufernandez
The best video I know about this stuff is "Compilers for free" by Tom Stuart (https://youtu.be/n_k6O50Nd-4). It is hilarious at one point. Brilliant.
dbu21
Fantastic talk! Thanks for sharing.
junon
Genuinely read "Futurama Projections" and figured the same. This doesn't sound real (though I fully trust it is, just sounds funny).
konstante
>...suspected somebody is trying to make fun of me...
I think that too, "Futamura projections" are important but they are very very far from "complex mathematical machinery" as you may hear it. They are indeed very simple (even mathematically trivial) and require no special background to understand.
jgrahamc
> Pkl was built using the GraalVM Truffle framework. So it supports runtime compilation using Futamura Projections.
What now?
pdpi
As I understand it:
GraalVM is an alternate JDK that can, among other things, do ahead-of-time compilation for Java.
Truffle is a framework for building languages, that sits on top of Graal.
Futamura Projections are a particularly interesting use case for compile-time partial evaluation.
With partial evaluation you have static (known at compile time) arguments to your function, and dynamic (known at runtime) arguments.
When “your function” is an interpreter, and your static arguments are source code, the output is effectively a self-contained compiled binary.
When your function is an interpreter, and the static arguments are the source code for the interpreter itself, that “self-contained compiled binary” is now itself a compiler.
iainmerrick
That all sounds cool, but is any of that especially useful for a configuration language?
matheusmoreira
> With partial evaluation you have static (known at compile time) arguments to your function, and dynamic (known at runtime) arguments.
That's pretty clever... How is this implemented in actual code though? I can't even begin to imagine how that magic machinery works.
EPWN3D
> Truffle is a framework for building languages, that sits on top of Graal.
wtf is Graal? That sounds like a supporting character from Beowulf.
verticalscaler
On tonights episode of Futurama bender and the gang explore the temple of Pkl on planet VM where truffles are considered the holy graals and barely run away in time from - The Compilations - an ancient secretive order of silver voiced kong-fu monks tasked with protecting the shrine from alien invaders as has been foretold in prophecies - and strangely reminiscent of 20th century Earth doo-wop group The Drifters.
Cue chase montage shenanigans with Under The Boardwalk playing in the background
Do you smell toast.
giancarlostoro
I definitely did a double take to make sure they didn’t write Futurama.
pasta1212
holy graals
txdv
A LOT of projects in the Java world do add new features to java. My favorite is CraC
catchnear4321
new game: llm hallucination, attempt at humor, or legitimate technical explanation.
usrusr
Too close to the "reliably solvable by simple heuristic" end of the spectrum to be a good game: if the text is short it's probably a joke, if it is a very long wall of words it's LLM and anything of somewhat reasonable length can only be a legitimate technical explanation, no matter how unlikely.
undefined
cyanydeez
all I saw was oracle
SOLAR_FIELDS
FWIW Graal is probably one of the most exciting technologies to come out of Oracle in a long time.
fmajid
Agreed. Anything by Oracle is an automatic hard nope.
lpage
Your mention of Futamura Projections was a nice reminder of how very mathy/theoretical foundations underpin Nice Things in high-level languages, like Hindley–Milner inspired type systems and modern optimizing compilers targeting SSA form. Value Lattices in Cue [1], another config programmable configuration language, also fall into this bucket.
corysama
Currently using Cue in a major project. It can be a puzzle. But, we like it a lot. Wish it had a bigger community.
SirGiggles
Not completely related to the OP, but is Truffle going to be upstreamed as part of Project Galahad or will it remain as a library maintained by Oracle Labs?
I ask cause the Project Galahad page on openjdk.org is a bit sparse on details.
grashalm
The truffle compiler extensions in Graal will be part of Galahad. For example the partial evaluator. The truffle framework and all the languages are consumed from a maven repo as a regular java library these days.
Some background on the recent changes there: https://medium.com/graalvm/truffle-unchained-13887b77b62c
summerlight
It'd be interesting to understand what kind of performance problem Apple had and tried to solve with GraalVM/Truffle. I've seen some instances of heavy configs that generate literally several gigabytes of data, but those were usually not significant bottlenecks since configs are not updated very frequently.
Of course, I know those two frameworks are one of the engineering marble of the age and would understand even if they decided to go without any concrete needs for it.
simonfxr
I guess you mean Futamura projections?
lionkor
I wish people named more tech products after popular media instead of common words. Would make it equally hard to web search, but at least it would be funny for non-techies to listen to
nindalf
You'll really like the Quantum Resistant key exchange algorithm - Kyber. A related project is Cryptographic Suite for Algebraic Lattices or CRYSTALS.
Sadly they renamed Kyber to MLKEM.
undefined
notso411
[dead]
grashalm
Damn you autocomplete! This happens all the time :D
aardvark179
Oh wow, this wasn’t the sort of language I expected to see being built on Truffle, but I’ll be really interested to take a closer look when I’m on a decent net connection.
undefined
Fischgericht
25 years ago pretty much every program had a GUI to do the configuration. With help texts. On Windows, programs then either saved stuff into an ini file or the windows registry, both you could also edit manually.
Today we have a programming language coming as a 87 MB binary to create config files. And to run that programming language you need to manually crate a ... config file.
So what we are missing now is a 500GB framework that can write the config file for the programming language that is writing a config file for the actual program I wish to use.
I am sorry, but very clearly a huge chunk of today's "developers" really are in the business of creating problems.
n42
Yes, the windows registry, the peak of our craft. No need to innovate, this one’s solved, wrap it up and move on
Try taking more time to consider the problems you don’t have that others do, instead of writing anything off that doesn’t make sense to you (and simultaneously gatekeeping an entire industry)
bborud
Pointing out that a proposed solution to a problem creates more problems is not the same as saying the original problem doesn't exist or isn't worth solving. Nor does it imply that some random other solution is better.
niutech
How about .ini/.cfg files? Simple and portable, allowing comments, unlike JSON.
cachvico
Not scalable though, like JSON with nested objects.
Fischgericht
Creating complex layers upon layers just to "solve" a very simple problem is not innovation. It's shittification.
n42
If your configurations are simple, you don’t need this. If they are not, you might.
Because you have not run into the problems this has addressed in your career, does not mean that you know better than Apple how to solve them. In fact, it means like you are uniquely unqualified to solve them. Acting like you are in a severely condescending dismissal of the engineers who worked on this makes for boring conversation.
cqqxo4zV46cp
Misappropriating a trendy word to use as a descriptor for anything you don’t like. This is how someone speaks immediately before taking a look in the mirror and realising that they sound like their parents. You are not the be-all end-all and your drive-by analysis of a technology is going to be biased by its suitability for what you do day-to-day. No amount of experience justifies your attitude.
bborud
It is no different when you are trying to solve a complex problem and complex layers upon layers obfuscate and confound you when you are trying to figure out why some component ends up with configuration values that are nowhere to be found in your input files.
sigzero
I am taking your comment as a joke because the Windows Registry is a joke.
fallensatan
I think they are being sarcastic about windows registry.
koromak
40 years ago I wrote Assembly that ran directly on the CPU. You could modify the registers directly. Then these crazy people came along and made a compiled language? And it outputs... Assembly?
I'm sorry, but a huge chunk of todays "developers" really are in the business of creating problems.
bsdpufferfish
except when you moved to C there was no corresponding increase in fixed time which you must spend on tool setup just to program
jhardy54
Yeah, it’s really great that compiling C is a straightforward endeavor that doesn’t require any tools, and definitely doesn’t depend on executables that generate or parse configuration files. I’m confident that no C developers have ever spent time on tool setup just to program.
ivlad
25 years ago admin would be responsible for one server, that they would setup and then never touch until (and sometimes after) someone hacked it.
Now people are responsible for thousands of containers, and GUI simply does not scale. And the configuration of those containers is domain-specific and/or varies enough so that you cannot write a single config file and copy it over. This is why configuration management systems first came with template engines and now require a separate tool to render the configuration.
Nobody would develop anything like that if it was not needed.
Fischgericht
Oh yes, people DO develop stuff that is not needed. Back in the 90ies pretty much every nerd sooner or later had to write his own programming language (myself included). The difference between then and today: We did throw it away afterwards. These days every week someone spews out a new "programming language", claiming that the re-invented wheel is so much more round than the others.
If fully agree that you might need to automate editing and deploying config files. But you don't need a new programming language for that. Just use one of the thousands of existing languages and tools.
You can for example use sed. A standard since 1973. Available everywhere. 76KB in size. Extremely fast.
Or use AWK. Exists since 1977.
Or you can use Perl. Natively able to read/write ini files, and in general very good at string processing. 6MB in size (or 250KB for embedded versions).
Or use Javascript, PHP, shell scripting, whatever.
But no, there is absolutely no need to invent a new programming language for a task where there are very established tools for.
ivlad
You are proposing to use general propose language vs domain-specific ones. I think, this discussion has been settled quite some time ago. For example, awk itself is domain-specific, built for processing text (or filed-separated) files. On the other had, m4 is as old as awk. m4 was heavily used even before autoconf (sendmail configuration is probably the best-known and possibly the ugliest application of it), for configuration, so one can argue, the need for macro expansion and rendering of configuration (as well as othe types) files was recognised even back then.
m4 just shows its age, and we’ve learned what is good (being Turing-complete) and what’s less useful (multiple output streams).
m4 could’ve evolved into m5, m6, etc., but nobody did it, instead people developed tools like jinja. One could argue, this is wrong and should’ve been evolutionary, but the point still is, domain-specific language to render configuration existed because there was use for them. Perl indeed could be such, I guess it did not happen for totally unrelated reasons. If Perl worked, Python would not gain popularity.
Pkl is not conceptually a new invention, it’s a new attempt to solve a real problem.
__MatrixMan__
I stopped using sed because it behaved differently on my coworker's machine than it did on mine.
hot_gril
I'm surprised there's no widely-adopted library for general-purpose languages that handles user-friendly object input and outputs static config (perhaps in JSON) for machines to read. Instead, there are several DSLs that act as dynamic config, and even some that generate dynamic config, or something in the middle like k8s YAMLs.
Have I just not thought hard enough about this problem yet, and a DSL is really needed for it? Or should I go write that lib?
mieubrisse
100%. Containers are essentially language-agnostic software libraries, and the config we write for them is analogous to the wiring we'd normally do in a to wire libraries together. Yet, our current tools aren't adapted to write and distribute the "programs" formed from gluing them together.
(Mostly-shameless plug, this is what we're trying to solve with Kurtosis: https://github.com/kurtosis-tech/kurtosis )
afavour
That strikes me as a very uncurious perspective. There’s absolutely nothing that could be improved about configuration files? An 87MB binary feels like a very arbitrary measure of worthiness.
Fischgericht
ONE actual standard that everyone uses would be fine. For non-tree (nested) configurations, an ini file would do. It's a standard that worked well in 1990, and still does today.
For nested data, it doesn't matter to me if it's JSON, YAML, TOML or whatever. Just agree on ONE format.
TOML also is a good example of "creating problems instead of solutions": They deliberately (!) broke compatibility to the INI format due to "I can't stand unquoted strings". Yeah, emotional feelings about CONFIG FILE FORMATS.
And again: If your config files are so complex, how about just creating a TUI/GUI so the user can configure your program in an accessible fashion?
Anyway, yes, there is something that can be improved: Create a standard instead of adding another layer of complexity for something that should be very simple in the first place.
Yes, binary size may feel arbitrary, but it often gives a hint about the hammer's size.
ivlad
> TOML also is a good example of "creating problems instead of solutions": They deliberately (!) broke compatibility to the INI format due to "I can't stand unquoted strings". Yeah, emotional feelings about CONFIG FILE FORMATS.
INI is hard to parse because without quotes the parser would not know whether it’s a “True” as a string or True as Boolean value. Formal parser that can be included into a program as a library and would reliably generate internal config representation (e.g., read config file into an object in application memory that will be used to modify the behaviour) is a good thing and TOML helps with that while INI does not.
flexagoon
> They deliberately (!) broke compatibility to the INI format
There is no "ini format" though? INI is a weak set of conventions that different programs parse in a completely different way, it's the opposite of standardization.
wtetzner
> ONE actual standard that everyone uses would be fine
Sounds like a social problem. How do you get _everyone_ to agree on anything?
cqqxo4zV46cp
It’s pretty clear that you are putting “things that I [think I] understand above things that are better. Have you ever written an ini parser? If you have, I doubt it was good, because none of them are, because ini is a flawed format.
Aeolun
I mean, there is something to be said against using the equivalent of 87 novels worth of text to produce a note’s worth of configuration.
pradn
The general shift to infrastructure-as-code is tied to a number of new trends and requirements:
1) Code review (config code can be reviewed by humans)
2) Automated pre-submit checks (config code can passed through automated pre-submit checks - such as preventing huge changes, or giving you a nice diff to look at
3) Auditability / history-tracking (you can look at the history of a config file to see who, when, why changes were made - this may even be necessary for compliance reasons)
4) De-duplication (you can extract common components into templates/functions - this supports variation across envs/regions/customers and repetition across tasks/machines/DBs)
All of these features help build large-scale systems in modern corporate environments.
__MatrixMan__
25 years ago, the only way to get two pieces of software to talk to each other was to get their authors to talk to each other.
I'm quite happy that remix culture has finally made it to software tooling. The extra layer of abstraction is a small price to pay for the power it brings.
(I don't know Pkl, but it seems like it scratches part of the same itch that you might use nix for).
Bost
> So what we are missing now is a 500GB framework that can write the config file for the programming language that is writing a config file for the actual program I wish to use.
That exists since 1960. It's called LISP. The e.g. https://guix.gnu.org/ uses with great success, the Guile Scheme dialect of LISP, to be precise. And FYI the "framework" is:
$ ls --human-readable --size $(readlink $(which guile))
16K /gnu/store/1gd9nsy4cps8fnrd1avkc9l01l7ywiai-guile-3.0.9/bin/guile
Yes, only sixteen kilos, not gigas.iso8859-1
Guix/Nix can use dynamic linking without risk since they know the exact dependency closure. It's not fair to compare a statically linked executable to a dynamic one.
panzi
Right, so its still just about 9 MB:
guile=$(readlink -f $(which guile))
sizes=$({ echo $guile; ldd $guile|grep /|sed 's+^[^/]*\(/[^ ]*\).*+\1+'; }|xargs -n 1 readlink -f|xargs du -ab|cut -f 1)
sumsize=0
for size in $sizes; do
sumsize=$((sumsize+size));
done
echo $sumsize
Gives 9041632 here.mbesto
25 years ago, you didn't have thousands of websites and applications supporting billions of users and millions of TPS. In hindsight, the innovation around DevOps is nothing short of a marvel IMO. 87 MB in the context of a $100 16GB stick of RAM is basically cheap in relative terms.
jaseemabid
Pkl was one of the best internal tools at Apple, and it’s so good to see it finally getting open sourced.
My team migrated several kloc k8s configuration to pkl with great success. Internally we used to write alert definitions in pkl and it would generate configuration for 2 different monitoring tools, a pretty static documentation site and link it all together nicely.
Would gladly recommend this to anyone and I’m excited to be able to use this again.
filleokus
Was about to ask if you had k8s api models available internally, and that someone should create some tool to generate that from the spec. But turns out it already exists in the open!
physicles
Coming from yaml+kustomize, all those curly braces are a tough sell. It looks like they roughly double the number of lines in the file.
fzeindl
While I learned to accept YAML it messes up editor usage.
It is so sensitive that basic text editing like copy and paste, tab, in/decreasing indent never quite do what I expect in IntelliJ.
I paste parts of yaml into another yaml and it ends up somewhere unpredictable.
manmal
Curly braces are great at ensuring correctness though, as goto fail; has shown.
crabique
Why yes, I would like to see more of those in my k8s, so glad we finally have the technology
https://github.com/apple/pkl-k8s-examples/blob/96ba7d415a85c...
dev_0
[dead]
asimpletune
Let us review the progress we've had so far in this area
* XML has the advantage of being almost perfect except its too verbose and isn't JSON
* JSON has the advantage of being JSON, but is strangely broken at even basic stuff (i.e. comments, no trailing commas)
* TOML has the advantage of being "better JSON", for people who like rust, but it is still too limited for a lot of scenarios
* YAML is not as limited, but it has the advantage of giving bad people promotions and good people PTSD
* HOCON has the advantage of being the goldilocks child of JSON and YAML, but nobody read the documentation
* <YOUR PROJECT'S PL> has the advantage of being able to do anything and this is a disadvantage
* Etc... for various reasons
In all seriousness, I welcome Pkl! Configuration seems simple and I think another configuration language opens up a lot of pent-up frustration, but I am legitimately very happy to see some fresh ideas in this space.
Incorporating a collection of typed records with a modicum of behavior and logic might be the secret recipe needed to crack the code. The fact that it can produce equivalent JS tells you that they've chosen a very intelligent subset of functionality of programming language features.
My best wishes to the team!
MrBuddyCasino
^ This is really the only required comment in this whole thread.
havaker
Built-in fetching of http resources and reading files from the filesystem[1] combined with turing-completeness are features that I wasn't expecting from a configuration language. I wonder if the complexity this brings is justified.
1: https://pkl-lang.org/main/current/language-reference/index.h...
Yeroc
Those sound like features that will eventually lead to major security issues.
bioballer
I/O can be sandboxed via flags.
For example, see these CLI flags: https://pkl-lang.org/main/current/pkl-cli/index.html#common-...
And when using the different language bindings, you can specify sandboxing options directly in that library.
zelphirkalt
How many people will run a malicious config at least once without the flags? At some point it becomes a numbers game.
p10jkle
For me, that's where all the power of the language comes from. It's like writing your config in Go or Python (which I think is also a great approach) except its designed from the ground up for this use case of config generation.
rockwotj
Ah just give me typescript, I do not need to learn a new thing for configuration languages and at the end of the day the output is compatible with JSON. Typescript has all the stuff I would want: types, first class json support, an ecosystem of libraries (if you want it, I would probably not for config generation). And the tooling is amazing. Does pkl have LSP, syntax highlighting in every editor, debugger or repl?
jwoq9118
Agreed. If we're getting the point where you're saying "it's like writing your configuration in [insert Domain Specific Language Here]" then I'd prefer to simply use that language. I understand the point Pkl is making in that "configuration won't work across DSLs so here's one language for all of them" but I don't know that that's enough motivation for people to adopt it.
However, I haven't built anything cool like this so what do I know. I'm just procrastinating on the my personal project and browsing hacker news.
mieubrisse
A big problem we've hit with allowing users to write Typescript (or any other general-purpose programming language) for our product is that it's too powerful.
Observationally, it seems that all that power eventually gets used, and then you end up with config that has complex interfaces, or becomes non-portable because it's doing arbitrary file reads, or is non-deterministic because of an ill-advised call to random or the system clock. The config then becomes something not maintainable by the rest of the team - just the few who know it.
Config languages seem to need to strike an interesting balance between being complex enough to allow for reasonable DRY code (which helps maintainability at the expense of readability), but not so complex that they're not generally-maintainable.
__MatrixMan__
My impression of typescript is that if you do:
a = 1;
and elsewhere:
a = 2;
The ultimate value of 'a' will depend on the order in which those statements are executed, right?
A configuration language should surface that as an error and tell you where all of the conflicting references are.
flexagoon
> Ah just give me typescript, I do not need to learn a new thing for configuration languages
People who don't know Typescript will still have to learn a new thing in that case, so there isn't really any reason to pick TS over any other existing language
> syntax highlighting in every editor
There is a tree-sitter parser for pkl, so it'll work anywhere where tree-sitter works. And for VSCode and JetBrains stuff, they have official extensions.
undefined
mikepurvis
Nix does this too and maintains perfect caching from top to bottom.
SAI_Peregrinus
Nix is a build & metaprogramming system, not (just) a configuration language.
tazjin
Nix is a bunch of things, one of which is a configuration language.
sanderjd
But I have no idea how I would build a config structure for an application using Nix... It seems very powerful so I'm sure it's possible, but I just have no idea where I'd start for this specific use case.
Whereas this documentation for Pkl is entirely about that use case.
mikepurvis
I agree that there's a huge documentation and user awareness gap, but NixOS is obviously possible to configure this way so it's definitely possible.
Might be room for a tool that exposes just the configuration management side of Nix in a more approachable way... on the other hand it would be a bit silly to use nix for conf files and not also for the underlying packages.
zelphirkalt
Sounds a bit like Mako in Python, that allows you to code Python in the template, iirc.
usrusr
Having read through the the docs a little, my gut reaction is that they might be a little too much in love with the idea of having created a language that can serve both as schema definition and as minimal values carrier. It smells of unexpected failure modes through overuse [1].
But perhaps this is exactly the core feature: everybody who adds pkl to their software implicitly signs up for participation in whatever configuration monstrosity the downstream stack will end up having. Based on the assumption that that it will be a monstrosity anyways, and that a uniform system would be less bad than an unstructured mess.
Next stage of concerns: if it's a heterogeneous stack that shares one configuration graph, the runtime implementation that is linked into parts of the stack can't ever be allowed to evolve. Ouch. And then there's runtime performance, I wonder if that could eventually become a factor, e.g. if short-lived go processes are involved?
It all seems surprisingly ambitious, very far from the "why not json-with-comments" that was my first reaction (shared with many I assume)
[1] digression: e.g. it reminds me of how in the dark days of peak XML java, a lot of typechecking was effectively thrown overboard because for some unfathomable reason everybody agreed that it would be nice to rearrange objects without a helpful compiler in the room
garethrowlands
It's normal for a programming language to have the ability to define types and create values of those types. Pkl is entirely conventional here.
OJFord
> We offer plugins and extensions for IntelliJ, Visual Studio Code and Neovim, with Language Server Protocol support coming soon.
Why? Why would they not have just done the language server first (or only)? All of those have built-in support for it, so separate implementations wouldn't have been necessary; that's the point.
I just don't understand why you'd make that decision on a greenfield project today, especially if LSP support is planned at all?
avianlyric
Probably because JetBrains only recently added native LSP to IntelliJ[0] etc.
Given that writing anything in Java/Kotlin basically requires the use of IntelliJ, it’s not really surprising that a language built on top of Truffle and GraalVM, all Java technologies, would ship with an IntelliJ plugin, _but not_ an LSP. Because such an LSP would have been useless in the primary IDE used by the language developers.
So if you wanna blame anyone, blame JetBrains for deliberately making hard to use LSPs with their IDE. Presumably to build a moat around their plugin ecosystem.
[0] https://blog.jetbrains.com/platform/2023/07/lsp-for-plugin-d...
9dev
The experience with LSPs is quite underwhelming compared to what a native language plugin in IntelliJ can do. That isn’t to say the approach is bad, but it’s definitely a trade off.
mardifoufs
How come? I don't know anything in say, pycharm, that can't be done with a LSP server and plugins. But that's probably because I don't know enough so I'm curious about what limitations an LSP would involve!
snom380
Why assume it's a greenfield project? I would think most open source software that comes out of companies have lived internally for a while before going public?
rcarmo
This. I’m willing to bet I talked to one of the people who use this internally at Apple a few years back when I interviewed there (before they decided to do away with remote hires). They didn’t mention it, but it fits the context.
p10jkle
Yes, I was using it when I joined Apple in mid 2020
giancarlostoro
Additionally I cant think of other such projects from Apple. They tend to build things that get used extensively till the end of their life is consumed.
I wish Apple would continue to open source much more. Especially old software much like Microsoft does. I would kind of enjoy a Linux Distro that can natively run old Apple software and tools.
samatman
Clang leaps to mind. Most of LLVM was developed under Apple's auspices, although the project predates Apple hiring Chris Latner. Swift is also open source, although in practice it's almost always used in a macOS context. Which I think is a shame, it's a great language for writing the sorts of servers for which people usually reach for Go.
That's not a complete list of programs Apple has open-sourced, although clearly open-source software isn't what they're best known for. But clang alone is a worthy contribution which deserves to be recognized.
OJFord
Fair point.
coldtea
>I just don't understand why you'd make that decision on a greenfield project today, especially if LSP support is planned at all?
How about if the LSP doesn't cut it for the kind of they IDE support they want to offer?
OJFord
Well I suppose that's what I'm asking, is that the case? I'm not aware of other projects that have a separate plug-in due to LSP shortcomings, so just interested if there is something they're doing that's not possible/won't be in the LSP one.
criddell
I think the answer to your question is yes: LSPs can’t do everything that a plugin can do.
https://blog.jetbrains.com/platform/2023/07/lsp-for-plugin-d...
bradly
Pkl has been widely used at Apple for years. It is not a greenfield project.
whazor
When distributing LSP servers you need to compile them to the target platform. Afterwards you normally also need an extension or plugin to actually activate the LSP server. So it is possible that there is an LSP server, but they haven’t figured out the distribution yet (sharing binaries? Homebrew?).
_ZeD_
have you worked with ide native extensions? while LSP is useful, his expressiveness and power and integration is limited.
isodev
I can imagine the answer if I were in their shoes. Say I already have something working as a plugin (or know how to make plugins vs. learning from scratch about implementing LSP), I'd rather have this out there as soon as possible and add more tooling/language support in subsequent releases.
OJFord
If it was just one I would have assumed the same, but Intellij, VSCode, and Neovim..?
throwaway-42808
From https://pkl-lang.org/blog/introducing-pkl.html#editor-suppor...:
"We are also releasing two other plugins: our VS Code plugin, and our neovim plugin. Today, these plugins only provide basic editing features like syntax highlighting and code folding."
spullara
Language Server support isn't nearly as good as building a native plugin for the IDE.
kibwen
I've had a good long think about configuration languages, and after a long-term on/off love/hate relationship with schemas I think I've finally concluded that I don't want rich types in my configs, thank you very much.
I use statically-typed programming languages, and for my purposes I'd rather have a config language where the only types are strings, arrays, and hashmaps, and then push all type validation into the parsing stage.
avianlyric
Guess the obvious question is why don’t you want types in your config language? Pushing all the validation to parsing state just makes it hard to write valid config, because you only know if the config is valid when you feed it into your program.
Having the ability to pull all that validation forward, and into your IDE, means you can be told about invalid config as you’re writing it. To me the idea of only wanting to validate config at the last possible moment, is a bit like advocating for only using simple text editors, and replying purely on build failures for feedback. Sure you can do it, but why would subject yourself to that?
Pkl is interesting because it makes it possible to describe not just the types, but also valid configs. Effectively allowing you to ship your applications config parsing and validation into Pkl, so your code can just expect valid config. Then Pkl can expose all that parsing and validation logic into your IDE, so you get pointers as you type. Just like you do in any modern IDE for any modern language.
hgs3
> Guess the obvious question is why don’t you want types in your config language?
The disadvantage of typed configuration languages is they make assumptions about the format of the data. For you a "date" type might mean ISO 8601, but for me it might mean RFC 3339. Config languages that make assumptions are coupling the language and schema validation together. The alternative is to decouple them: offer a flexible configuration language with a separate schema language. The latter would let you define the schema specifically for your data for validation.
avianlyric
> For you a "date" type might mean ISO 8601, but for me it might mean RFC 3339
A generic date type doesn’t come with any specific string format. ISO 8601 and RFC 3339 are both ways of representing a date as a string. Which has little to do with Date as a type.
There’s also perfectly good solutions to those problems. Use a type alias to create a date type backed by a string, with formatting constraints (such as a regex). Then people can define dates using any string representation they want!
Incidentally this is exactly what Pkl lets you do. You can use Pkl schema to define in detail how you want to validate your data using various primitives like regex. And then separately create a config template that uses those custom data types. As a dev you can choose how tightly bound your config template is to a data validation schema, define all the validation in line, or import an external module to provide you with richly validated data types.
Too
Even more reason to standardize the format used in configurations and to validate it early, rather than at runtime.
cpeterso
Seems like someone should create a new datetime standard, documenting the safe intersection of ISO 8601 and RFC 3339. I did find this useful comparison: https://ijmacd.github.io/rfc3339-iso8601/
usrusr
One argument I might put on the cons side of AOT type validation for configs is that there will always be some invalid inputs that can't be statically checked (e.g. port number already taken), and not failing simple type errors before runtime helps keeping in mind and view whatever feedback channel exists for the runtime failure. I wouldn't consider that a winning argument, but it's not entirely without merit.
avianlyric
That’s not a reason for giving up on all config validation before runtime. Just because we can’t solve a problem in every possible situation doesn’t mean shouldn’t solve the problem for any situation.
srcreigh
duplicate port number can be checked in the type system if you’re using racket, at least
youerbt
My take on this is that there is not obvious reason not to, but it just so happens that typed configuration languages are not rich enough and not integrated enough to be that useful.
Those languages that arrived with the JSON hype train like yaml or toml might be great for dynamic languages, where you can load them to some native object. But in statically typed languages you are gonna declare your types, in code, anyway. So configuration providing types doesn't really do much.
avianlyric
Ah! Well this is the hole that Pkl does a very good job of filling!
Being able to use Pkl code-gen to create language bindings means you can take any arbitrary Pkl schema and turn it into native structures in your language, typed based on the Pkl schema. Then you can let Pkl do all the heavy lifting of parsing and validating a specific config, and turning it into native objects in your language.
So no need for double declaring types. Declare them once in Pkl, generate the equivalent types in your language, then just start using those types like any other primitive. The Pkl bindings will handle the loading glue for you.
jen20
The whole _point_ of Pkl is that it is both rich enough and integrated enough though?
riffraff
Yaml predates toml by ten years or so _and_ has an extensible schema to define types.
Sadly, nobody ever cared about that.
jmull
Yeah, generally, you want to validate as early as practical... catching problems sooner is better than later.
I think the problem might be separation of concerns...
pkl comes in early, and by design is separated from your app and the details thereof. It seems good for validating high-level or external configuration constraints. But suppose you have some constraints based on implementation details of your app. Now you face a choice: eschew pkl and put that validation logic in the app where you lose the benefits of early validation or put it in pkl (if that's even possible) which implicitly makes it dependent on application implementation details. Of course, we devs aren't great at stopping to consider the deep implications of each config param we add, so which one happens in practice in each case probably depends on the dev or dev group and how much they've bought in to pkl... some will pretty much always add a config to pkl because that's what it's there for, while others will ignore pkl whenever they can. I think this is inherent in the ambiguity the choice presents. There's probably a right choice in each case, but devs will only sometimes be that careful about the location of each config validation.
That's my guess anyway, as to why the previous post wants to just put all the validation at the level it's used. If that's your rule the ambiguity is resolved and it works perfectly for config dependent on specific app concerns and pretty well for config that also has high-level or external concerns, since those are less volatile and when they do change, it generally implies app changes in any case.
My gut says pkl is over engineered for the vast majority of cases and people should not reach for it unless they have a specific problem that it will solve for them.
seer
Hmm isn’t pickle designed for exactly this use case? External config module deps you pull for overall config validation.
E.g. so you always write valid k8s manifests.
And then you can extend them with your own additional validation rules for what you think your app needs? I’ve just skimmed the docs but it seems it allows you to be as loose or as precise as possible, plus packaging and publishing those rules for others to use.
Seems kinda awesome.
HelloNurse
Fixing the app implementation details so that the configuration stays "clean", or at least forcibly documenting them so that the configuration can be written correctly, is vastly better than allowing the app to make undocumented surprises with its private validation.
lucianbr
I am convinced the Pkl config will grow in complexity until it has a yaml or json config for the configuration program.
wtetzner
> Guess the obvious question is why don’t you want types in your config language?
Where do you store the schema?
maximus-decimus
Because with a real programming language you get an actual IDE, auto complete, a debugger, sane compiler errors instead of a vague helm error "invalid thingy at line 4", you can log a bad config the same way you log stuff for the rest of your program and you can't guarantee your config is valid anyway if your config language can't see what class you're going to feed it to.
avianlyric
That’s a consequence of configuration languages not have proper type systems, and robust was to manipulate data.
Helm isn’t a configuration language, it’s a dressed up string templating system with ability to do kubectl apply.
> you can't guarantee your config is valid anyway if your config language can't see what class you're going to feed it to.
Obviously, but that’s hardly an insurmountable problem. We’ve had code gen and language introspection for decades.
Too
Helm is not a proper configuration language. It just does string replace. Unbelievable that people actually use it.
A config language that does have the type information can give proper errors. Try for example terraform.
bioballer
I think this is a reasonable approach if you only have one stack, and don't have a lot of config. If you have one stack, you can put all the validation, types, and everything else in your runtime application, and then you don't need to learn new languages, and everything works.
This becomes a lot more painful if your work is more polyglot. If you need to define config that needs to be shared between different applications, but they're written in different languages, you'll have a much harder time. Also, say, if you need to deploy your applications to Kubernetes, and your Kubernetes specification needs to provide config files to your application, then you'll still end up in a situation where your statically typed programming language won't help. That is where something like Pkl becomes really helpful, because you have just one place to manage all that complexity--right in Pkl itself.
leapis
I mostly agree with this, but I've been a big fan of having primitive types in config. Most of the time if I have something I want to configure, it's either one of the following (or a map/list-based structure consisting of):
- scalar value
- feature toggle
- URI/enum option/human readable display text
Having float/long/boolean is trivial to validate in the config language itself, and if they're useful and simple enough isn't it nice to be able to validate your config as early as possible?
youerbt
It's nice, but it comes at a cost. For example, every user of toml forever will have to put strings in quotes. Why? Because having other types creates ambiguity, that is resolved by this one simple trick. But if you don't quote them then you have "the Norway problem" like in yaml.
ajross
That's my feeling too. Tools like this are trying to squeeze into the space between "straightforward configuration easily maintained in static files" and "complicated state management better served by real code in a real programming language". And that's a real hole for some applications, but it's a small hole.
Basically forcing everyone to learn new tooling (Pkl here, but lots of json/yaml middleware nonsense fits the bill too) just to deal with what really isn't that big of a problem seems like a bad trade.
giancarlostoro
The only thing I want is very basic flow control / environment based code blocks and that’s it. I think nginx has a reasonable config language
acuozzo
Reduce it further: strings and maps. Arrays can be represented as a map.
ricardobeat
Strings can be represented as arrays too. Doesnt make a good argument for removing them.
acuozzo
Doing so would necessitate the addition of another type: character/grapheme cluster.
Representing arrays as maps would impose no additional requirements outside of validation which is already considered as part of the proposal in question.
Spivak
Sounds like you and the INI guy agree here and honestly I'm coming around to it because for complex types you end up typing everything twice.
https://github.com/madmurphy/libconfini/wiki/An-INI-critique...
garethrowlands
You're saying you don't want red squigglies in your IDE when you do your configuration wrong? Why?
mirekrusin
So like cue [0] but more primitive, less principled and in java?
IshKebab
Looks like it might fix three big issues I had with Cue:
1. The only way to use it is to run their Go CLI app to convert the Cue into JSON and then load that. That sucks. I want native support. Jsonnet does this a lot better (https://jsonnet.org/ref/bindings.html), and PKL at least supports 4 languages. Cue only supports Go directly. Not good.
2. Cue has a super fancy type system, but as far as I could figure out there's no way to actually take advantage of this in an IDE, which is like 60% of the benefits of fancy type systems. In a Cue document you can't say "this is the schema". XML had that decades ago (and it has awesome IDE integration with Red Hat's XML extension for VSCode). Even JSON can sort of do it via `$schema`. The docs are a bit scant but it looks like this supports it too. The fact that Cue doesn't sucks.
3. Cue is pretty much only a fancy type system. It's a really elegant and nice type system, but that's it. It doesn't even have functions. So it isn't going to help with a lot of the things that Jsonnet and PKL help with.
This is not really in the same area as Cue. It's a way more direct competitor to Jsonnet and looks better, based on my brief skim.
My only concern with these sorts of things is that they're basically a whole new programming language, but without many of the features you'd want from a real programming language. It's in an uncanny valley.
Does look nice though.
4ad
> [CUE] doesn't even have functions.
Note that CUE has comprehensions, which are morally (but not syntactically) functions (actually closures). They are a way to transform values (which can be types) into other values.
We are also adding real function types to CUE. At least in the beginning these functions will be written in other languages than CUE itself, however.
While we are very principled when it comes to language design, we are also very responsive to finding solutions to user's problems, and we welcome any sort of feedback, especially if it's backed by specific use cases and experiences.
As mentioned in another comment, support for languages other than Go is coming.
atombender
What does "morally" mean here? I've not seen that term used in compsci except when about ethics.
bbkane
Love this comment and I agree with basically everything. What are you using for configuration these days?
I've fallen back to YAML because at least its already used for a lot of tools, and has comments, jsonschema support in VSCode giving IDE features, language library support, yamllint, and yq for formatting/querying/mass-updating from the CLI
IshKebab
Yeah I actually haven't found a great answer yet. Here's everything I've tried and why it sucks:
* JSON. No comments. Deal-breaker
* JSONC. No unique file extension so its difficult to distinguish from JSON. Poor library support due to library authors drinking the "comments are bad" koolaid.
* JSON5. This would be an excellent option IMO except that library and IDE support is not great.
* JSON6. This just complicates JSON5 for minimal benefits. Pointless.
* Cue. As described.
* Jsonnet. Pretty good option tbh! However I couldn't get the Rust library to work. It's a low level parser, seems like you can't just plug it into Serde, which is what 99% of people really want. Also I ran into the "uncanny valley" effect where you can do some things but not all. So it tricks you into writing some programmatic config (e.g. with string manipulation) but then you find you can't do that string manipulation.
* Dhall. Weird syntax (backslash to declare functions. I've also heard it is slow. Didn't try this too much.
* YAML. Obviously YAML is the worst option. However I did realise you can use it as basically JSON5 except with a different comment character, which is not too bad.
* Starlark. Actually I haven't tried this yet but it looks promising.
So yeah I have no idea at the moment.
I wonder if it would be worth defining a "YAML JSON5" format, that's basically YAML-compatible JSON5.
gregwebs
Looks like it has better IDE integration. Still, I am going to stick with cue because of what you mentioned and also because it is a community project. Apple has very few actively maintained open source projects and sometimes such projects are difficult to contribute to or have wavering support for the open source side. It is great having corporate backing behind something like swift that needs a massive amount of work, but for cue, I am happy with steady improvements meeting the needs of a wide community once I can figure out a good IDE integration.
4ad
FWIW, we (CUE) are currently working on a LSP for CUE which should improve the IDE experience.
the_duke
I really like CUE, but for most use cases I have I would want to embed it in an application, and Go is the only language with support.
For it to gain more adoption it really needs a rewrite in a low-level language (C/Rust), so it can be exposed in various languages through an extension/FFI.
bbkane
I've been somewhat surprised that CUE bills itself as "tooling friendly" and doesn't yet have a language server- the number one bit of tooling most devs use for a particular language.
I'm assuming it's becaus CUE is still unstable?
Anyway, if others are interested in CUE's LSP work, I think https://github.com/cue-lang/cue/issues/142 is the issue to subscribe to
leblancfg
That’s what I’m seeing as well. Curious to try it out to see how its expressiveness compares to Cue. Looks like it’s Turing-complete as opposed to Cue, which is a plus… but that comes with downsides.
One thing I like to see is the direction of “declare types and validations in a single place, integrate with any language”.
My daily codebase atm has types declarations in typescript, cue, pydantic and for our database… and it’s driving me bonkers seeing as most types are already declared in Cue to start with. I played a little with packages meant to translate them i.e. Cue -> TS, but nothing worth the effort.
IMO it would be a big upside for Cue to handle these as first class language features.
ratorx
What advantages does Turing-completeness provide for a configuration language?
neongreen
There are three (maybe more?) ways things can be Turing-incomplete:
1. You are limited to N evaluation/reduction steps.
2. The language doesn't include primitives like recursion or loops.
3. You can have recursion or loops, but the language makes you somehow prove that your program will terminate.
I think (1) would be fine, but I don't know any configuration languages that use this approach.
(2) is restrictive/annoying whenever you want to implement any logic in the config language library. Eg. a tool uses a homegrown data format BAML and you need to convert JSON to BAML in the config. Now either you have to write and manually call a preprocessor, or you need to use a patched version of the <config language evaluator> that will have JSON->BAML as a built-in, or you must implement JSON->BAML without loops or recursion. For a more realistic example, imagine that a certain config string has to be HTML-escaped and the config language doesn't provide a built-in for that purpose.
(3) -- you don't want it. There are languages (like Agda) that let you prove things like "this program terminates", but writing those proofs can be harder than writing the program itself.
leblancfg
Many data transformations that you take for granted in other languages are either impossible or require amazing feats of contortion of the language to make happen.
mirekrusin
Javascript/typescript don't have introspection or any autogen between static and runtime types either.
Cue is not general purpose language, with emphasis on it - because it's a good thing.
Asking for upstream embedded support feels like asking for bash interpreter, why would you need it in the first place?
It's based on completely different, logic based paradigms, use it as it is meant to be used - as top level configuration aiding language. Declare policies and generation in it and interface with other languages/tooling though input/output json/yml.
aeontech
I think everyone appreciates links to similar projects for comparison, but a more in-depth comment would probably come across better - the "less principled and more primitive" sounds like a thoughtless off the cuff ad hominem dismissal.
Consider that some engineers poured a lot of heart into what they were building, and are probably excited to finally share it with the world.
I am not saying you have to love it, but just brutally putting it down with no justification seems really rough. Snark is easy.
runeks
I wish the Cue docs were better. I arrived here https://cuelang.org/docs/usecases/configuration/ but it doesn’t answer basic questions like “can I define my own validation functions (the > < != operators used in the example)?”.
cqqxo4zV46cp
Yes. I am sure it’s that simple. I’m sure that there are all downsides and no upsides. This is the first time in history where one technology is a strict superset of a competing technology, from all perspectives. /s
I really don’t know why this snark is necessary.
mirekrusin
Primitive and less principled doesn't imply "downsides". Go is more primitive and less principled than Haskell, yet it's useful and oftentimes better due to its primitiveness. Cue is written in Go for example.
lclarkmichalek
In a competition with sky/starlark, I feel skylark would win here. “Safe subset of python” is what a lot of people presented with this problem want, and skylark gives them almost exactly that.
OTOH, curious to see what advantages Pkl gains from not having the constraints of maintaining familiarity with another language.
lolinder
Starlark seems to be overwhelmingly bound to Bazel at the moment—searching for it, I had to follow a link from Bazel to the GitHub repo and then from there I got to the implementations and found this:
> The implementations below are not fully compliant to the specification yet. We aim to remove the differences and provide a common test suite.
This does not inspire confidence that I could use this in a project any time soon.
Meanwhile, from what I can tell Pkl has a single Truffle implementation that currently supports 4 languages, it has a syntax that is more familiar to me as a non-Python dev, it has static typing, and it has a dedicated plugin in most IDEs (whereas Starlark just says to install the Bazel plugin). Maybe Starlark is more appealing to people writing Python or already using Bazel, but for the rest of us there's no contest right now.
Terretta
The implementations and users page mentioned above:
lclarkmichalek
Never used Bazel in my life, so while I can appreciate your passion, I guess I don't share your perspective. Generally the pattern I've seen has been providing a skylark interface to allow folks to define rules or configurations, which are then consumed through by whatever service via starlark-rust or similar implementations.
arunkumar9t2
Copybara uses it
lolinder
Step two of installing Copybara is to install Bazel [0], so that doesn't exactly contradict my claim that if you're not already using Bazel you probably won't use Starlark.
mieubrisse
Agree - one of the things we've found using Starlark at Kurtosis is even the small jump from Python to Starlark makes people think, "What's this Starlark? I don't want to learn a new language", and we have to show them how not-a-new-language it is. I can't imagine bringing a truly new language like Pkl to folks and having them enjoy it.
chefandy
I thought the same thing with the Godot game engine's GDScript. Aside from a few class-level implementation details (IIRC, it's been a while) it's essentially Python, syntactically. "Ugh... If I'm going to learn a new scripting language it's not going to be application-specific... Oh NM."
mbo
My employer uses a combination of Protocol Buffers (for the config schema definition) and Bazel/Starlark (for concrete instantiations). Configs are validated at build time and runtime using CEL (https://github.com/google/cel-spec).
Terretta
Trivia note, the bazelbuild starlark readme example shows a rare correct implementation of FizzBuzz, with no unique case for "FizzBuzz".
taywrobel
Wow, I was at Apple back in the 2018 timeframe when Peter was first building this. He was hoping to make it open sourced even back then, 6ish years ago. Great to see that it finally made it.
I really wish Apple would learn to play nicer with the OSS community. I have yet to see them deciding to open-source something backfire on them monetarily or reputationally, and I've seen the act of them abruptly close-sourcing things sour community opinion (i.e. FoundationDB).
bioballer
Hey, I recognize this name :D
Yeah, it's been a long time coming, and it feels great to finally get this out in open source.
FDB is open source too, BTW: https://github.com/apple/foundationdb
Get the top HN stories in your inbox every day.
See also https://pkl-lang.org/index.html
(via https://news.ycombinator.com/item?id=39239265, but we merged that thread hither)