What does HackerNews think of differential-datalog?

DDlog is a programming language for incremental computation. It is well suited for writing programs that continuously update their output in response to input changes. A DDlog programmer does not write incremental algorithms; instead they specify the desired input-output mapping in a declarative manner.

Language: Java

#12 in Python
#79 in Rust
The relational model (and generally working at the level of sets/collections, instead of the level of individual values/objects) actually makes it easier to have this kind of incremental computation in a consistent way, I think.

There's a bunch of work being done on making relational systems work this way. Some interesting reading:

- https://www.scattered-thoughts.net/writing/an-opinionated-ma...

- https://materialize.com/ which is built on https://timelydataflow.github.io/differential-dataflow/, which has a lot of research behind it

- Which also can be a compilation target for Datalog: https://github.com/vmware/differential-datalog

- Some prototype work on building UI systems in exactly the way you describe using a relational approach: https://riffle.systems/essays/prelude/ (and HN discussion: https://news.ycombinator.com/item?id=30530120)

(There's a lot more too -- I have a hobby interest in this space, so I have a small collection of links)

This is amazing!

Have you looked at differential-datalog? It's rust-based, maintained by VMWare, and has a very rich, well-typed Datalog language. differential-datalog is in-memory only right now, but could be ideal to integrate your graph as a datastore or disk spill cache.

https://github.com/vmware/differential-datalog

Datalog is a logic programming language for relational data. It is much easier to express recursive relationships in Datalog compared to SQL. The most obvious application of Datalog is for working with graphs. The starter example I've usually seen is "graph reachability", which something like "given a list of edges between nodes, tell me if I can reach node X from node Y".

    // Given an edge x -> y, there is a path x -> y.
    path(x, y) :- edge(x, y).

    // Given an edge x -> z and a path z -> y, there is a path x -> y.
    path(x, y) :- edge(x, y: z), path(x: z, y).
Here is the equivalent recursive SQL (SQLite syntax):

    WITH RECURSIVE path(x, y) AS (
      SELECT
        edge.x AS x,
        edge.y AS y
      FROM
        edge
      UNION
      SELECT
        edge.x AS x,
        path.y AS y
      FROM
        edge,
        path
      WHERE
        edge.y = path.x
    )
    SELECT
      DISTINCT *
    FROM
      path

If you want to play with Datalog, https://percival.ink is an online notebook with a very gentle introduction. I also published a version of percival.ink that converts simple Datalog queries to recursive SQLite queries here: https://percival.jake.tl (the example above is from percival.jake.tl).

As jorkadeen said in their answer (I added emphasis to the last sentence):

> Datalog programs are values. You can store them in local variables, pass them as arguments, and return them. If you have two Datalog values you can combine them into one (effectively it's just the union of them). This allows you to write small "Datalog fragments" and stitch them together into a larger program. The type system ensures that this stays meaningful.

Why this is important: From my perspective is that a very large percent of industrial code interacts with data (in databases) by building query strings. In most languages, we throw away all the nice features of the language when it comes to data access. To regain some level of composability and safety, developers pour years into libraries like [Arel in Ruby](https://www.rubydoc.info/gems/arel) or [Calcite in Java](https://calcite.apache.org/docs/algebra.html). The most notable example of language native database access is [Language Integrated Query (LINQ)](https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...) in C#. But all of these tools are hampered by the constraints of SQL. SQL is very good for flat, normalized data with one or two joins. Once you begin working with trees or graphs, tools based around SQL become cumbersome.

Using datalog instead of SQL means you have a logical langauge that is inherently more accepting of composition in a theoretical way. But, most systems that speak datalog today are extremely specialized. [Souffle](https://souffle-lang.github.io/simple) and [differential-datalog](https://github.com/vmware/differential-datalog) are useful ahead-of-time compilers for datalog, but you have to design your whole program around using them. The datalog variant [inside Datomic](https://docs.datomic.com/on-prem/query/query.html) is dynamic, but is only usable for accessing data in a data store. Good luck using it for analysis of data in memory.

Including datalog into the language as first-class values mean that you can access the power of datalog and actually compose it in practice.

[Note: I've never used Flix – just a datalog fan.]

The imperative design matches the hardware too well to just dispense with. Rust's abstractions are probably the closest we've gotten to a composable design that fits closely to the hardware while mechanically preventing writing the most common bugs at that level.

That said I agree that we've barely scratched the surface of the space of good paradigms; I'm partial to logic programming but most are underexplored. Perhaps other approaches can use Rust or its IR (MIR?) as a compilation target. As an example, this strategy is being used by DDlog ( https://github.com/vmware/differential-datalog ).