6 ms·
> We want to build a structure that is essentially a syntax tree of the operations we want to perform. A-a-and so we went from programming in Haskell to creati
by Joker_vD 1y ago
> We want to build a structure that is essentially a syntax tree of the operations we want to perform.
A-a-and so we went from programming in Haskell to creating a new DSL, with an interpreter for it in Haskell, and programming in that DSL. Which kinda begs a question: you already have a perfectly serviceable programming language (i.e. Haskell) at hand; why not just use it?
- kqr 1y agoThat's what I also don't quite get. I would build it as the parsing step mapped directly over the query. I suppose their approach lets them build a tree of operations but I'm skeptical it provides all that much benefit.
- _jackdk_ 1y agoThat would work if the API we were querying could return results of different types in response to a single query. But we might have a single operation that needs to know a couple of FooIds, a BarId, and a BazId, and they all need to be at least three requests against the remote system.
- lkey 1y agoCreating specialized and constrained DSLs is a common and useful pattern for folks that write Haskell (or really any FP lang that has ADTs).
- cryptonector 1y agojq was originally a Haskell-coded, in-Haskell DSL.
- marcosdumay 1y agoI don't understand your complain. Haskell is entirely aimed at creating those small languages and interpreting them. While at the same time the compiler they have in hand implements a DSL for describing imperative programs that do not allow the kind of analysis the author is doing. What exactly you expected them do write?
- cryptonector 1y agoEh, Haskell is not "entirely" aimed at creating DSLs.
- marcosdumay 1y agoOk, it's not entirely. It's just its main differentiator. But there's way more to the language.
- _jackdk_ 1y agoThis is a really good question. If you write all the queries directly in Haskell, you get an IO action which you can't inspect: all you can do is execute it and see what it does. It might make requests, it might repeat requests it didn't need to make, it could do literally anything else. Other programming traditions also have this pattern of inventing minilanguages and interpreters for them; regular expressions are by far the most successful example. You could hand-roll string matching by writing your matching functions by hand, but it's often much easier to ask a regex library to run an interpreter over a string describing the pattern to match. In Haskell, it's really cheap to invent data structures, so using the same language to describe the work is quite convenient. Laziness also means you almost never materialise the entire intermediate "work to be done" structure - you build little bits as the interpreter demands them. So it doesn't feel as heavyweight as an eDSL in some other language.
- Joker_vD 1y ago> If you write all the queries directly in Haskell, you get an IO action which you can't inspect. Of course you can inspect it: open the source code you wrote and read it. Also, don't write the code you don't want to be executed? > but it's often much easier to ask a regex library to run an interpreter over a string describing the pattern to match. Which, I might notice, you never inspect. You execute it blindly and look at the outputs of the match() method falling out of it. In fact, most regex libraries compile your regex into an opaque data structure which you can't inspect — and nobody complain about it.
- tinyspacewizard 1y ago> Of course you can inspect it: open the source code you wrote and read it. Also, don't write the code you don't want to be executed? This is not what they meant by inspection. What they mean is that you can write a function, in Haskell, that given a value in the DSL, it returns the list of all requests it will perform on execution. This can be useful for tests, security, caching, performance, debugging...
- throwthrow0987 1y ago> is quite convenient It's not principally about convenience though is it? It's about defining the semantics of your program through the DSL. Then you can verify the program logic, prove properties about it if you wish. It is denotative.