5 ms·
You're sort of doing the same thing, right? Totally - my knowledge of Haskell is probably more superficial than most Haskell fans knowledge of category theory,
by ewjordan 17y ago
You're sort of doing the same thing, right?
Totally - my knowledge of Haskell is probably more superficial than most Haskell fans knowledge of category theory, so I'm in no position to fairly poke fun. Consider the jab retracted. :)
I think I'm just seething from a recent argument about Haskell's superiority where I was accused of not understanding the almighty Power Of The Monad...really, I just think that the necessary pervasiveness of the pattern indicates that the language is not as powerful as it could be (I raise an eyebrow when I see any pattern used very often anywhere), whereas fanboys sometimes take it as evidence that the language is beautiful - witness the number of Java programmers that think design patterns are proof of Java's perfection. I personally don't like it so much when languages make too many choices for me, and Haskell seems to have that same "protect us from ourselves" philosophy that makes Java so irritating to work with, just with a different enforced paradigm.
And in reality, the people that actually use Haskell are not like this. Don't let someone that read about Haskell on Reddit yesterday, opened ghci, and typed "let fibs = 1 : 1 : (zipWith (+) fibs $ tail fibs)" put you off. People like to be excited about things, and people that read too many programming blogs get themselves unnecessarily excited about simple things. Then when they sort of understand that simple thing, they feel the need to tell everyone.
Yeah, this is what I pretty much assume, that it's a vocal minority creating most of the noise. I should probably give it a fairer chance, given that a lot of people find it the perfect language for a lot of stuff.
Unfortunately at the moment, the only "stuff" I can afford to work on involves DOM manipulation, so it's Javascript or bust for the foreseeable future...
- plinkplonk 17y ago" I just think that the necessary pervasiveness of the pattern indicates that the language is not as powerful as it could be (I raise an eyebrow when I see any pattern used very often anywhere), whereas fanboys sometimes take it as evidence that the language is beautiful " Very interesting observation! Generally recurring patterns in one language "disappear" in more advanced languages (as Peter Norvig's slides point out), either by new syntax or changes to the runtime . How could Monads or (by extension type classes) disappear in a new language? Something to think about.
- jerf 17y agoActually, the problem with Monads in other languages is that they do disappear behind the statement separator (semi-colon in many languages). In Haskell terms, you're stuck in the IO Monad and can never, ever get out of it. An analogy: C has the array-dereference operator []. But that pattern is locked into the language, you can't do _anything_ but dereference C arrays in exactly the way the operator does. C++, Python, C#, and a wide variety of other languages unlock the array dereferencer by permitting the operator to be overloaded, and thereby permitting things other than a straight-up C array deference, ranging from dereferencing into something that presents the interface an array does (like some sort of ordered tree) but is not literally laid out as a contiguous block of memory, to things that aren't arrays at all, like keying into hash tables. Accusing Haskell of being "less advanced" because it actually exposes Monads to you and permits you to use them is very much like accusing C++ of lacking power vs. C because it permits you to overload the square brackets. If you put aside the question of whether it's a good thing to have the power (a separate debate in both cases), it's not a very sensible accusation to level against Haskell. The Monad pattern appears everywhere in every language whether you know it or not, Haskell merely exposes to the user something that is already there. Calling a monad a "programmable semicolon" is not necessarily the best way to understand them, but it has more truth to it than some of the other metaphors tossed about.
- plinkplonk 17y ago"Actually, the problem with Monads in other languages is that they do disappear behind the statement separator (semi-colon in many languages)... The Monad pattern appears everywhere in every language whether you know it or not, Haskell merely exposes to the user something that is already there. " Yes I agree (haskeller myself). The "disappearance" I meant was addressing the original point of view that the repetition of the pattern was a weakness in the language, something like Visitor pattern disppearing in Common LIsp. (an intriguing idea to play with and a valid point of view). Your interpretation of disappearance goes the other way - something like continuations being hidden in fortran and explcit in Scheme. "Accusing Haskell of being "less advanced" because it actually exposes Monads to you and permits you to use them is very much like accusing C++ of lacking power vs. C because it permits you to overload the square brackets. If you put aside the question of whether it's a good thing to have the power (a separate debate in both cases), it's not a very sensible accusation to level against Haskell." A better analogy would be an argument about exposing call/cc in scheme. Is call/cc good language design? There are arguments on both sides. Haskell does continuations differently than Scheme. Which is "better"? And come on, no one is really "accusing" Haskell of anything. I for one, like the language a lot. If you will, think of this as a speculation about a successor language. 15 years from now (say) there will be a better language than Haskell in the statically typed lazy functional languages space, which absorbs the key positives of Haskell, has a few new ideas, and possibly treats Monads differently (or does away with them altogether). Clean (the language) deals with IO with uniqueness types with nary a monad in sight. Is that design "better"? Worth thinking about.
- jrockway 17y agoreally, I just think that the necessary pervasiveness of the pattern indicates that the language is not as powerful as it could be I think you're wrong, but I don't know how to explain it. The pattern is "running a procedure, and then running another one". Let me know when you "work around" that.
- jrockway 17y agoReally? Do I really have to cut-n-paste the same 10 page essay about this every time the subject comes up?
- ewjordan 17y ago(I'm not really sure why you were downmodded...I don't think that's an unreasonable response to my objection.) Sorry if this is a bit long: I've been trying to figure out precisely what it is that bothers me about the monad "pattern" as it shows up in Haskell, and I've mostly put my finger on it. It's mainly the use of the State monad that smells to me, by the way, some of the others are quite powerful and merely indicate flexibility - note that when I said "necessary pervasiveness" is a problem, it's "necessary" that bothers me, not "pervasiveness". Some patterns, even if they show up all over the place, are not alarming at all, because they are there to facilitate good design no matter what paradigm you work in - I think of these as "style patterns", because they're usually not enforced, and sometimes you're tempted to break from them, but without a real good reason you should usually resist the urge. MVC is a perfect example - it's not there to enable you to do something, it's there to restrict what you do so that you write better, more maintainable code. This, to me, is the signature of a good design pattern: it tells you what not to do, and it lays out a way to avoid doing it. But others are "power patterns", if we're being charitable, and "power" is not a good word in this context. Things like the adapter, decorator, iterator, and strategy patterns (not an exhaustive list, of course) are mostly around to enable behaviors and flexibilities that the language (Java or C++, usually) makes very inconvenient. Not that the patterns necessarily make them easy, but they do make them possible, usually with the minimum friction that the language will allow - if you have to use Java, you have to know and use these patterns, because otherwise you're going to end up reinventing them anyways to get your work done. Sometimes I think of these sorts of patterns as "patterns of delusion" rather than "power patterns." By which I mean, they spring from the fact that the systems we're trying to model don't map very well onto the models that the language at hand imposes (the "delusion"), and we end up having to shoehorn concepts into each other to make them fit. This is always uncomfortable, and when we find ourselves doing it, it's a language smell. In the case of Java, the core delusion is obvious: everything is a noun with properties (which may be other nouns) and abilities (which may not). In order to work with abilities (verbs), we have to "noun" them first, but before they can do anything we need to re-verb them, and God forbid we want to work with verbs that act on verbs... ...thus we end up with several patterns pretty much exclusively devoted to working around the inconveniences of treating verbs as nouns. Some of the other power patterns in Java are caused by other delusions (maybe I should be less critical and say "overly specific model assumptions"? Bah, screw it...), but this is the most consistently painful. Pure functional programming's core delusion is pretty clear as well: all state is immutable. Trivially, state is not immutable in many problems (at least under the natural description of the problem), and whenever we thread state or use state monads we're employing a power pattern to work around a restriction imposed by our language/paradigm. Now, context can determine whether a pattern is employed for power or style: I'm fine (thrilled, even) with threading state or using state monads when they are employed as style patterns - if you're working in Scala, Clojure, Lisp, etc., and you have a chunk of code that you've decided really needs to be purely functional for whatever reason, awesome. The pattern is a restriction, not an enabler, and that makes it good. I can't offer any argument against benefits of state-free programming, I fully agree that it is incredibly useful and can make life easier, to the point that it should probably be the default in any language. But far too often I see Haskell code where state-simulation is done solely because the problem under consideration is naturally expressed with mutable state, and the only benefits that accrue by wedging the mutable state into an immutable framework are that you can write the program at all, usually at a healthy loss to clarity. Every time I see this, it's like seeing bits of Java code written in functional style: it's ugly, it's inconvenient, and you've lost most of the benefits of the paradigm that you're mocking. I've yet to be convinced that Haskell actually gains very much from its stateless-ness; I understand that in principle there are nice optimizations that it can enable, and parallelization becomes rather simple, but I'm not seeing it beat the pants off of impure functional languages in speed or clarity. More than anything, I think what Haskell has going for it is all the other nice syntax and power that it has (a lot of which has been mimicked in other languages because it's so nice), and I'm not sure I believe that any of that would be degraded one bit if "normal" stateful programming was added in as an option. Agree or disagree (either way is fine, I realize there are arguments in the other direction), I think that's at least a better explanation of what I was complaining about before. I realize I'm stepping into holy war territory here, maybe I should have just kept my mouth shut. :)