What do you consider to be the definition of a “de...
# thinking-together
j
What do you consider to be the definition of a “declarative” language? I ask because I keep running across build tools which claim to be easier/superior because they are declarative, yet without fail they run up against a wall where they keep trying to shoehorn in more features while remaining declarative, and instead should have just gone to a full Turing complete language.
❤️ 2
k
What I think of declarative build systems: https://news.ycombinator.com/item?id=15043432#15044027 (That whole thread is about my draconian solution.)
😄 2
Regarding "declarative" more broadly, I still find this thread from April memorable, about the distinction between declarative and composable: https://futureofcoding.slack.com/archives/C5T9GPWFL/p1556655545323500 (before, after and sub-thread)
d
Just because a lot of popular declarative languages (spreadsheets, SQL, CSS, makefiles, XSLT, etc) started off not Turing Complete doesn't mean declarative languages in general can't be! Once you add any kind of circularity over evolving state, you get TCness, and it doesn't need to make the language much more complex or hard to understand.
j
I like what you are saying in that thread @Kartik Agaram. As an experiment I built a simple build system that is just regular JS functions using memoization. So far it’s very easy to read and extend. It feels like having a bunch of build-centric utility functions is better than creating a new declarative language.
also, async and arrow functions make the JS surprisingly concise. If I can write a build system in a ‘declarative style’ while still using regular functions, then the need for a custom build system seems much less.
Am I missing something? Why did build systems evolve towards declarative DSLs ?
d
? they started as declarative languages: makefiles!
it's more powerful to be able to describe the "what" not the "how" of a build: to describe the end state, then hit "go", and let the algorithms decide on the necessary steps
this gives idempotency: you can say "go" whenever you like
k
Yeah, it was this kind of spherical-cow theoretical thinking 😄 When
make
was created the only language available on most Unix machines was C[1]. Many of its design choices are understandable in the context of that constraint. Nobody wanted to design a whole new language, they just wanted to compile their C files. Less understandable is everyone else who's blindly cargo-culted the
make
model ever since, even though there were better options available. [1] According to Wikipedia,
make
was created in 1976, and
/bin/sh
in 1977.
j
here’s an example of what I’m talking about. In the early days of Java people used make files or shell scripts. At some point they started using Ant. Ant is declarative with a syntax based on XML. It worked fine, but people kept extending it to do more things as their code bases got bigger
The only way to extend ANT was to add new tasks, written in Java, but all data had to go from one section to another as strings. You would spend a lot of time thinking about how to shoe-horn what you wanted into the ANT model.
Even though, by definition, you had this very powerful language, Java, which it was built in. Eventually ANT became hard to maintain so they built Maven, which grew into even more of a mess (though it did introduce the repo system which is still the only good part of Maven)
Today lots of tools still run on make, or things which generate make.
I think it would be an interesting experiment to use functional programming in a proper turing complete language to as a build system. Would it be more extensible and easier to understand than a make file? Maybe, maybe not.
g
🤦‍♂️peak HN galaxy brain
j
ha hah
again HN misses the point
w
Historically, declarative answers what, imperative answers how — and beyond that a lot of context matters. At the least, we could say language/framework/library is declarative for a use if it does some part of it automatically or implicitly, which would otherwise require some tedious or tricky work.