Comment by daxfohl

2 days ago

The logic programming / datalog feels a bit gimmicky on top of everything else. All the other features, I can see exactly how they'd improve the type soundedness of a codebase. But logic programming is really niche and I'd almost rather it be independent of the language.

The counter-point is the following: Functional programming is great for working with lists and trees. But functional programming (and imperative programming) struggle with succinctly, correctly, and efficiently expressing queries on graphs. Datalog, on the other hand, is excellent for working with graphs. It is simple, expressive, and (can be) very fast. It is a power tool. Most of the time it should not be used, but when it fits the problem domain its benefit can be 10x or 100x. It is also worth pointing out that Datalog is strictly more powerful than SQL (modulo various extensions).

The goal of Flix -- and typically of any high-level programming language -- is to provide powerful abstractions and constructs that make programming simple, concise, and (often) less error-prone. Here Datalog fits perfectly.

Now that said -- looking through the Flix documentation -- I think we need to do a better job at selling the use case for Datalog. Partly by adding arguments such as the above and partly by adding better examples.

  • But lists and trees aren't really "built into" languages. They're part of the standard library, not the language itself. Maybe one could say "foreach" syntax builds lists into a language, but in many languages you can foreach non-lists, others have foreach as a method instead of syntax, and it still doesn't say anything about trees.

    I do see your point, I'm just not so sure I think it'd be the right thing to do. It feels like too big and arbitrary to be a core language feature, better left to a library. If there are some core features that would make building such a library easier, I'd focus on those rather than the logic programming itself. Something like how Rust did async. (Though contrarily, I think Rust should have built async into the language, since it's pervasive and hard to interop different implementations. Unlike async, logic programming is typically self-contained, and there would rarely be a need to interop multiple implementations).

    Anyway, great work so far. I look forward to seeing it progress.

    • Going a little further, what I'd really like to see is the core concepts implemented in a way that allows a standard implementation to follow straightforwardly from the type system, but also allow for doing nonstandard things. Like, "here's a logic language built in" is kind of boring. What's more enticing is "Here are the components. Here's a nominal implementation based on these components. Here's a weird thing you can do that we hadn't actually designed for, but could fit certain use cases."

      I remember Jon Skeet did a whole series of blog posts on reimplementing C# async, which was possible because C#'s async syntax isn't bolted to the implementation, and added features like coroutines that weren't part of C# at all. https://codeblog.jonskeet.uk/2011/06/22/eduasync-part-13-fir.... Similarly Daniel Earwicker had a series where he implemented async/await using iterator syntax instead https://smellegantcode.wordpress.com/2010/12/14/unification-....

      And sure, now I know it's all kind of fancy but fairly trivial stuff you can do with monads (and I guess free monads in the Linq-to-SQL case), but it was fascinating to me at the time.

      So yeah, for "selling" purposes, I think rather than selling datalog built into the language as a front-page feature, a series of "how to build a datalog" posts would go further in showing off the power of the components of the language that it's built from.

      (And FWIW I do like the way C# has built-in support for "important" monads like iterators (foreach), generators (yield), async (await), optional (null propagation operators), etc., even though a language purist would argue against it. I think it provides an easier on-ramp for newer developers, and helps make common things more concise and readable. So it'd be interesting to see where that line would best get drawn for logic programming, what gets special-but-extensible syntax support, and what is purely implementation and functions).

Right, it feels like a standard example of a Lispy library (Datalog), and a Prolog monad is standard teaching material. I am of the opinion that Flix is strictly worse than Idris2

  • > I am of the opinion that Flix is strictly worse than Idris2

    That seems irrelevant to my original comment. Idris is a fully dependently-typed language that compiles to native code, and seems to be in maintenance mode. Flix is built on JVM, uses effects rather than dependent types, which I think makes an 80/20-rule sacrifice of type safety for ease-of-use, and seems to have a more active community (for now).

    But yeah, the datalog thing feels unnecessary. Like the SQL built into Linq/C#, cute, but doesn't really scale for real-world use cases, so there's still a need for independent ORMs. I see a similar thing here. No need for building this into the language. There are plenty of logic libraries, services, persistent stores, etc that can do datalog, so let users use them the way they want. Building it in just feels gimmicky at best, potentially troublesome at worst.

    It gives me a similar feeling as the old language / web platform, Opa. It was a really cool language for the time, and had client-server functionality (similar to meteor) built into the language itself. But as web client-server frameworks fell out of favor, so went the language itself.

    Here, I think the built-in datalog makes it seem like a language that's hinging too much on a gimmick, and takes away from the impression it gives as a serious language.