Love this, I've long considered that this should've been made as Prolog and SQL are ternary logic and basically SQL derives from Datalog and it itself from Prolog. A table record can be taught as of as a Prolog fact, so this makes the WHERE clauses the predicates in the conjunction on the right-hand side of a rule. And then exhausting the goal is actually returning the result-set.
Hope to see this develop even further, as Prolog has its place with relational databases.
Prolog's evaluation semantics are order-dependent, though. I've always thought this was the reason why the two language paradigms didn't see more merging than they did. There are some datalog+RDBMS hybrids but, as much as I'm not a fan of .NET, I think LINQ has seen the most success in this space.
For me, I just haven't enjoyed the developer experience. It's been a few years so take my opinions with a dash of salt but I find the language itself verbose, I should be freed of having to think about its memory layout because of garbage collection but I still end up thinking about it because of type boxing and enumerator-wrappers, the garbage collection routine itself is not as mature as other environments that I'm familiar with (perhaps that has improved?)... and, I know some of my characterization is unfair. Among the .NET/CLR languages I really only have in-depth experience with C# and perhaps I should give one of the others a chance. I also carry baggage from a few years on a Unity project that twists what C# actually is (like how async/await is mangled and the way some library routines are only available from the main thread). I also probably allow my experience on a Java project (a few years of rather high stress) to bias me w.r.t. C# but I know that's also unfair, but these make me less likely to approach the language. It wouldn't be a deal-breaker for me to join a team but it would step down my enthusiasm some.
I will say, though, that the .NET authors did seem to learn some lessons from Java's worse API decisions and the .NET API is more uniform and reasonable overall.
To clarify, Unity case is a massive night and day difference to what is expected to be "normal" language experience e.g. using ASP.NET Core/EF Core, AvaloniaUI, writing a CLI app or a systemd service, or GtkSharp even, or using Godot/Stride. This is due to GC being much slower and more punishing, very often completely different way of doing basic operations and it also (ab)using IEnumerators as coroutines which may make it seem that average usage of them is just as difficult (it's not). Performance is also significantly different, sometimes by an order of magnitude, even including Burst-compiled code.
Boxing is rarely something you have to think about if ever in general purpose code, nor is garbage collection outside of not insisting on doing things less efficient and often more painful way (doing int.Parse(text.Substring(0, 4)) over int.Parse(text.AsSpan(0..4)), something the analyzer prompts you to fix).
If you care about performance as indicated by message content, then any JVM language is a very big downgrade as many patterns are simply not expressible with it the way they are with C#/C++/Rust.
There are also significant differences in tooling as .NET one is much more aligned with what you expect from using Rust/Go/even Node interacting via CLI (dotnet build/run/publish).
WHy do you say that Prolog is ternary? It ssemantics are roughly those of predicate logic that is bivalent. In Prolog a "query" can either succeed or fail, i.e. be true or false, or raise an error- are you counting errors as a third truth value?
well the ternary thing about SQL is that it has this NULL/unknown, and it can be demonstrated with the outer joins.
Then SQL being a slang of DataLog, which comes from Prolog implies Prolog is ternary, no? Indeed Prolog's handling of "unknown" is more procedural than a true ternary logic.
So it has slightly different notion. Even though I'm more a Prolog amateur (s.o. who loves it), a a failed query in Prolog implies the unknown state. It's about the provability within the system, not about a third truth value.
Yes, I see what you mean and it's a good observation and, funnily enough, you're both right and wrong.
What you're saying is that Negation as Failure (NAF) introduces a concept of uncertainty, that we can consider a third truth value. Prolog doesn't have classical negation, where negating a logical atom (a "fact") makes it false, unconditionally and with certainty; it only has NAF, where an atom is true only if it cannot be disproved (since we prove by refutation).
Intuitively speaking, that is right. NAF is the simplest way to treat uncertainty, or in any case there is no simpler way: just set aside what you cannot know with certainty, and proceed based on what you can (dis)prove with certainty. There's even a name for that: non-monotonic reasoning, and it's a powerful technique. There's an argument that's it's a good model of how humans reason about uncertainty. I'm agnostic on that front [1].
Formally speaking, thinking of Prolog as a ternary logic because of NAF is not right. NAF is just one way to assign truth values to atoms, but there are still only two truth values to assign, true or false. We might have uncertainty about the assignment, but that's still uncertainty about assignment of one of two values [2].
A bit more precisely, there are only two possible outcomes to a query: either it succeeds (one or more times, nondeterministically), or it fails. If the query succeeds we say that it was "true", for some values of the variables in the query, and if it fails we say it was "false", or there are no values of its variables that make it true.
In other words, Prolog will never return a NULL, like SQL. The uncertainty is baked-in to the success or failure of a query.
But that's a really cool subject and you are on the right track thinking of NAF in terms of uncertainty.
__________________
[1] Answer Set Programming (ASP) is a different logic programming language where the difference between classical negation and NAF is part of the semantics of the language, and for the purpose of non-monotonic reasoning. I don't really know that literature very well so I can't recommend specific texts.
[2] Also keep in mind that uncertainty exists only about the result of a query. Anything we declare as part of a Prolog program, "facts" and "rules", are axiomatically true. Since queries are proved by refutation that means that only falsehood is uncertain. We can know truth with certainty and un-truth with uncertainty.
Hope to see this develop even further, as Prolog has its place with relational databases.