Unifying the Technical Interview
aphyr.com
aphyr.com
Maybe you can't even call it fantasy since it is real code & logic with no magic involved.
In Neal Stephenson's Anathem there are monks that turn mathematical proofs into songs and other art, and it reminds me of that.
I just about lost it with that one. Started laughing so hard I woke up my wife...
> ... balancing a binary tree was an interview question which I personally bombed in 2010 ...
Thank you, Kyle. That first snippet gave me joy. That second snippet, though... that gave me _hope_.
“One more thing,” you request. “Some kind of product type.”
“Ma'am, this is a Wendy’s.”
If anyone is interested in practical applications, Will Byrd (mentioned in the story) went on to work with Matt Might (HN's favorite CS-prof-turned-doctor). One of the products of that was mediKanren[0] which operates over medical research. There was some publicity around mediKanren last year.[1]
[0] https://github.com/webyrd/mediKanren [1] https://www.uab.edu/news/health/item/10703-diagnosis-in-2-12...
I've taken a couple of stabs at writing a mini/micro-kanren in a language which _isn't_ a lisp, often following along closely with some paper from Hemann, Friedman and/or Byrd -- and if the language _doesn't_ have macros it really does get awkward. As mentioned at the PS, for a good long stretch, this post is pretty directly transcribing the 'microkanren' paper, and without macros at some point Vidrun would have had to invent some of her own idioms.
The other trick to having the embedded kanren really work with the host language, which is swept a bit under the rug, is that `walk*` / `walkr` in this post implicitly assumes that everything in your universe is a variable, an atomic value, or a cons. In that sense, it's a little funny that (I think) her kanren can't really solve "inside" of the structs that she asked to be provided.
If you take a look at the "full" version of this program, which uses more struct types, it involves a good deal more explicit recursion: https://gist.github.com/aphyr/4d41e7655b10a68e753f729bdc1c5a...
her kanren can't really solve "inside" of the structs that she asked to be provided.
Ahhhh, so this is true, and actually a feature: uKanren exploits scheme vectors as lvars, and initially my language was just lists. I wound up adding structs precisely so that I'd have an analogous non-list compound type!
Of course, once you understand logic programming you still have most of this essay left to go through. Even if you've used lisp you've probably never had to implement one! And of course, after you've gotten through all that, now you need to read code written in this strange lisp. A microKanren. almost Prolog, but different in some key ways; it uses a different execution strategy which prevents those infinite loops. The Reasoned Schemer is the second half of this essay but expanded out to book form, it would make a great explanation if you're down for a nice read and you have a free Saturday.
Once you've gotten through all that the syntax has become completely unrecognizable but the final solution is fun, and makes all the ceremony worth it:
balanceo, [lambda, [tree, balanced],
[conde, [[rotso, tree, balanced],
[balancedo, balanced]]]]
`balanceo` is a relation which is only satisfied if `tree` is a tree and `balanced` is the balanced form. If you pass in `tree` it returns the correct `balanced`. I'm not sure, but it looks like it probably also works if you only pass in `balanced`, in which case it will return the unbalanced `trees` which correspond to that balanced tree. You might even be able to pass in nothing, in which case it will return a bunch of pairs of unbalanced trees and their balanced forms.The definition of `balanceo`, essentially, says that "[balanceo tree balanced] is only true if balanced can be formed by performing rotations on tree, and balanced is balanced." MicroKanren figures out the rest. That's declarative programming! Pretty great! Though, it only works for small trees, which does tarnish the magic a little.
Well, yes, that's one good reason to know Prolog.
Now make everything run backwards! :)
I had thought that the non-logical features at the Prolog-implementation-of-Lisp level would lose relationality. And it does, at the level of the Lisp implementation. But you gain relationality at the microKanren level!
I love it!
Level 0: PROLOG
Level 1: (non-relational implementation of) LISP
Level 2: (purely functional? implementation of) microKanren
Level 3: (purely relational implementation of) tree balancing
In [0] we invert this approach, also arriving at code that behaves relationally:
Level 0: LISP
Level 1: (purely functional implementation of) miniKanren
Level 2: (purely relational implementation of) LISP
Level 3: (purely functional implementation of) tree balancing (or whatever)
At first glance it may seem goofy to implement LISP-within-miniKanren-within-LISP. After all, we started with LISP! However, the LISP we end up with inherits the relationality of its miniKanren implementation, which means we can encode our problem in LISP, but have miniKanren apply the search and constraint solving under the hood.
The last example in [0] goes further:
Level 0: LISP
Level 1: (purely functional implementation of) miniKanren
Level 2: (purely relational implementation of) LISP
Level 3: (purely functional implementation of) LISP
The extra level of LISP interpretation allows us to put logic variables representing unknown values in new positions, giving us increased expressivity, at a significant performance cost.
If we can figure out how to apply staged evaluation/partial evaluation/supercompilation/etc. effectively to these towers of interpreters to reduce the interpretive overhead, these "jokes" may turn out to be surprisingly useful.
[0] https://dl.acm.org/doi/10.1145/3110252 and http://io.livecode.ch/learn/gregr/icfp2017-artifact-auas7pp
there's also a 'Report abuse' link nearby...
How is this even remotely fair?
He takes what should be a simple problem and solves it with the entirely the wrong tools. There's some comedy, the tools are comically wrong and overpowered for the task at hand. There's also the sheer thrill of seeing such tools used at all, we don't generally write this kind of stuff at work.