5 ms·
This is a rather frightening article. Why is it considered a good thing to not know anything about the components that make up your program? This seems like bla
by tree_of_item 13y ago
This is a rather frightening article. Why is it considered a good thing to not know anything about the components that make up your program? This seems like blackbox abstraction taken to its absurd conclusion, where programmers simply wire together type compatible components without any idea of what they're actually doing.
What does the example program even do?
I think this article is one of the best explanations of the visceral reaction some programmers have to Haskell. There's a lot of theory behind Haskell's semantics and libraries, and some people just do not enjoy using something without having any clue of how it works or how it's implemented. Even a hand-wavy naturalistic explanation is better than a dismissive "you don't have to worry about that".
- wting 13y agoAre you implying developers should know the inner details of every library used? Realistically most devs read documentation or Google to get something done. They only dive into the library if the documentation is unclear or something is broken. Reading well written libraries is a good learning experience, but not a requisite to use one. In Haskell a function's type signature is expressive enough to exist as rudimentary API documentation.
- cgibbard 13y agoThe library described in the article gives you a way to take an arbitrary data type, and treat its values as the primitive actions of an embedded domain-specific language (that's what singleton does), and then write interpreters for that language by saying how those primitives should be interpreted (which is what interpret does). All (or at least most of) the control structures for the language come for free, because there's an instance of Monad. This tends to be quite helpful especially in the case where there are multiple interpretations you might be interested in. For example, a graphics library might provide an interpreter that executes drawing primitives using OpenGL to put stuff on the screen directly, as well as one which interprets the same data by manipulating arrays of pixels. Perhaps another could construct an SVG. To do that, you'd provide a data type whose constructors would encode whatever drawing primitives your library supported, things like circles and lines and Bézier splines, and then use the interpret function to define each interpreter by supplying a function which takes a given primitive and says how to carry out whatever actions are needed to be taken to display or render it. (Note: this example is likely a little simplistic, because most of the operations in a drawing library won't have return values, but this set-up allows for such things. You could also make a version where the things drawn also continuously produce values by reacting to user input, allowing for some sort of optional interactivity.) You'd also likely define a bunch of user-facing versions of the primitives which would amount to singleton applied to each of the constructors of your data type, just for the sake of convenience and implementation-hiding. Then you have a library where people can define complex drawings in terms of the primitives you provided, and supply any one of those to any one of the interpreters you defined in order to put it on the screen, or write it out to an SVG file, or whatever. For no additional work, you get operations like sequence :: [Drawing a] -> Drawing [a] from the monad library, for taking a list of drawings and producing a drawing which carries them out in sequence (whatever you've decided that ought to mean via your interpretations, probably stacking them on top of each other), as well as many others. A more interesting example (in that it would involve input as well as output) might be a library for coordinated communication of some sort over different types of underlying network protocols (necessitating different interpreters for the primitive communication operations). Again, you'd get lots of control structures for free, things like for-each loops, and ways to define new bits of a protocol by applying a function to the results of a bunch of smaller pieces of communication.