3 ms·
This 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
by _jackdk_ 1y ago
This 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.