I'm skeptical, because there is already a configuration management language that is strongly influenced by Prolog and logic programming - Puppet - and the results are not that great.<p>The secret of configuration management is that ordering NEEDS to be a first class feature and ordered manifests should be the default, not the option. Puppet suffers hugely from the influence from the fact that ordering is unpredictable and that you have to use arrows or requires to add order. People accidentally forget to add ordering, the resulting code works most of the time, and then one day you start running into an issue because some implicit dependency either didn't happen, or happened in the wrong order. In as much as all logic programming involves not explicitly controlling flow, I think they're inappropriate for configuration management. Sadly, I'm still stuck with using Puppet because of the organisation I work in.<p>Having worked with Prolog in the past, I would also suggest that an important feature of a configuration management language is that the syntax make it hard to make typos and other minor errors because the feedback loop of deploying your code against a local vagrant machine is already long enough. I vividly remember the annoyance of having missed the full stop to end a block. I'm not desperate to repeat that experience.
It's been a while since I've studied Prolog, but it's good to see it getting some press. I learned Prolog before ever dabbling in Scheme or ML, and it was just as much of a paradigm shift from imperative style. It's kind of like FP-style pattern matching, but taken to a whole new level, such that the pattern matching itself is pretty much the entire computational engine.<p>Rather than using functions, which take a number of arguments and return a result, you use predicates on a number arguments. You build your program out of clauses, which are conjunctions of predicates. A process called unification [1] finds the argument values (if any) that satisfy an entire clause. By sharing constants and variables between predicates, the valid results that unification can produce are restricted to what the logic of your program allows.<p>So your algorithms end up being, in many ways, description of what a valid results look like, and the Prolog engine goes out and finds them. This paradigm clearly maps nicely to domains with lots of rules, like decision engines, parsers, and such. Sounds awesome, right? One caveat is that, in practice, you as a programmer have to have a pretty good understanding of how unification works in order to write performant algorithms.<p>This is all from several years-old recollections and a little bit of Wikipedia to refresh my memory, so someone please chime in if I'm incorrect someplace or leaving out key concepts.<p>[1] <a href="http://en.wikipedia.org/wiki/Unification_%28computer_science%29#Application:_Unification_in_logic_programming" rel="nofollow">http://en.wikipedia.org/wiki/Unification_%28computer_science...</a>
Prolog's a surprisingly good fit for many every-day tasks where people otherwise invent DSLs or poorly-defined state machines and pattern matching algorithms.<p>So how come we don't use it more often? Well, the reason is actually quite simple:<p>Prolog's incredibly difficult to reason about once you grow past trivial facts and clauses like in the OP's article -- the examples given by him would've been introduced to you in the first lesson on Prolog in, say, University. The complexities of green/red cuts, backtracking and the procedural nature of Prolog makes it a really difficult language to truly learn -- much less one to specify complex programs in.<p>I've never programmed in a language where 5-6 lines of errant Prolog code could stump myself, a post grad and a professor before until I did Prolog.
Also like the bootstrap.sh - very nicely structured and easier to verify than many others I've seen. I'd still prefer these scripts to output missing dependencies that calling sudo -- but otherwise very nice.<p>That is, rather than:<p><pre><code> function install_git() {
echo 'Trying to install git'
case $(uname -s) in
#...
Linux)
if has_exec apt-get; then apt_update
sudo apt-get install -y git
#...
else bail "Unknown linux variant"
fi
;;
*)
bail "Unknown operating system $(uname -s)"
;;
esac
}
</code></pre>
Simply aggreagate a list of missing packages, and ouput (based on a
similar case-statement for detetining host):<p><pre><code> echo Please install missing packages:
echo sudo apt-get install ${missing-deps}
</code></pre>
<a href="https://github.com/larsyencken/marelle/blob/master/bootstrap.sh" rel="nofollow">https://github.com/larsyencken/marelle/blob/master/bootstrap...</a>
Prolog does seem a reasonable fit for the problem space.<p>That said, even CFEngine's long winded syntax (born of its commitment to "promise theory") isn't so bad. In my experience I don't feel expressiveness of the available languages is the problem most I need of solving.<p>The real problems not being tackled by the existing configuration management tools are testing bundles/(play|cook)books/modules, cleanly injecting metadata to facilitate reuse and the bundle debugging workflow.
The meet/met notation instantly made me think of babushka: <a href="http://babushka.me/" rel="nofollow">http://babushka.me/</a><p>The base principle seems to be the same except that babushka is a ruby DSL and that the dependency solving is part of the library instead of the language.
Very interesting. I wonder if it would be viable to build an entire package management system (like apt) in a similar manner -- and if there are any (semi-recent) improvements to prolog-like systems that might improve dependency resolution "for free"?