Reazon – miniKanren for Emacs
github.com
github.com
I was reading TRS and wanted to run the code, but I didn't have (and didn't feel like getting) Clojure or Racket. At the same time, I wanted to try my hand at some serious Elisp programming. The obvious answer was to put miniKanren into Emacs, and that's what this is.
It's really a fun presentation and does a great job introducing logic programming and miniKanren to lay programmers.
What are your experience? Any successful uses?
I still think logic programming has untapped potential for use in "regular" programs, but we haven't invented the best way to integrate it yet. In order to take advantage of bi-directional nature of logic relations (every argument can be input or output) you really need all the consituent pieces of that computation to be relational, as well. (To do what William Byrd calls "running backwards".) But to support this in an imperative language, where some of your relation is purely logical and some of it is implemented with user-defined callbacks, requires careful defensive programming in the C++ callback functions.
Moreover the inherently lazy/on-demand nature of logic programming does not fit well with the way debuggers for imperative programs work. This is not specific to logic programming (for example, debugging a regular expression that is inside a C++ program is a similar case). What is needed is a way to tell the debugger to display the file, line, and character position where the regex or logic relation or SQL statement was defined and not the position inside the engine which is interpreting that data.
I would contrast the "fully integrated, compute on-demand" way I was attempting to use a logic programming library with the way Sqlite natively works. With Sqlite, the steps of preparing a statement, looping over the rows, and finalizing the statement are all distinct steps (as called from C/C++ code). The Sqlite query planner can calculate the entire plan from the SQL string and the tables it manages internally. When Sqlite computes each next row as you step the prepared statement object, it is free to use whatever evaluation order was chosen by the query plan, because it all happens synchronously in the "step" call and then returns.
Of course the drawbacks of this approach (the famous impedance mismatch) are well-known to anyone who has used any kind of SQL database API from a C-family language. So I am not saying it is the best we can do. However I believe this API interaction strategy is one way (surmised - I haven't tried it yet) that logic programming could be integrated with an imperative program without it devolving into an un-traceable mess: treat it like using an SQL engine. Or like compiling a regex, stepping through, and reading the captures.
I find this answer ultimately disappointing, because I feel that such a powerful technique ought to transform how you think about and structure your whole program. And instead of solving the impedance-mismatch problem, it gives up on it. But having tried things the other way (coroutining logic and imperative code), if I were to try again, I would try this other way (treating the logic program like a database or query engine).
--
My first real gigs were CAD/CAM based. I really thought both constraint and parametric programming were the future.
Finally gave up on constraints for UI layout. My alternative was to hand code the heuristics, esthetics. I created DesignGridLayout (for Java), based on canonical grids (a graphic design notion). It's now defunct, but if I ever circle back to UI work, that's where I'll resume.
--
That impedance mismatch has tripped me up my entire career.
I forfeited in a different way. I inverted the work flow.
I now use working examples to generate the code.
In the case of databases: instead of an ORM to generate SQL, I use SQL to generate the JDBC/ODBC wrappers.
I can't speak to implementing a query planner (way beyond my intellect), or your notion of starting with a different mental model, but it's food for thought.
SQLAlchemy has an ORM but it has a neat feature to exactly this: it can take a DB connection and build ORM objects from the schéma metadata.
Another key idea was that the snaplines are completely independent from the logical (hierarchical, tree) structure of the "document" (aka form). So like if you wanted controls above and below something to be horizontally aligned with each other, but not affect content in the middle, you could do that by just only associating some controls with those snaplines; the fact that the snapline cuts across the middle content need not affect it because it's an abstract "membership" in a group not a physical barrier.
How I came to this design was I had done XAML layouts with WPF on Windows, and while I preferred to use the Grid tag to solve most layout problems, I was also frustrated with its limitations: you kind of have to plan ahead, if you discover you need another alignment line you have to renumber things, or maybe you need to fuse certain cells, etc. I realized that I was using the grid to get alignment lines, but didn't (necessarily) want all of the other behaviors which come with it.
I feel like this was a missed opportunity to say "predicate" instead of "test functions".
I don't have an interesting query to show you. My tests were done on synthetic data.
Today is a good day.
I have been seriously looking into a good APL (or deciding between A+ / J / etc.) for use in scripting. Right now I think AWK to massage the data and ${APL choice} to analyze it might be the right way to go.
AWK is highly specialized to interpret ad hoc data structures encoded in strings and spit out new similarly ad hoc strings, like all other unix utils. Personally I hope that's not the future. In fact I wish for the day our terminals and coreutils are replaced with utilities that speak JSON or something.
One of the coolest projects. Lumen is entirely self-hosted, so compiler.js is built from compiler.l which represents an algorithm that defines how to build compiler.js.