7 ms·
> Too bad Haskell is such an impractical language. When does this nonsense ever stop?
by sfvisser 12y ago
> Too bad Haskell is such an impractical language.
When does this nonsense ever stop?
- tormeh 12y agoIt's not nonsense, though. But IMO it's not the language itself, but the libraries that are impractical. The naming is the worst. If Haskell's authors really wished to create a practical language, they would never have allowed things like ">>=", "\", "." or "!!" into the standard libraries. It's not the first programming language to use lots of arbitrary signs, but it's certainly the worst I've ever seen. The only conclusion I can draw from all this is that Haskell's written by people who love memorization and don't care much about explaining to others.
- wz1000 12y agoMany confusing operators certainly exist(especially in Control.Arrow), but the ones you have mentioned are the worst possible examples you could give. All of those have a clear meaning, and are extremely useful f . g y . h z a . f' is certainly much clearer than f `compose` g y `compose` h z a `compose` f' The same goes for (>>=)
- tormeh 12y agoIt's clearer to me, but I still have no idea what's going on. This, on the other hand, is a syntax made by people who thought it through: with Ada.Text_IO; use Ada.Text_IO; procedure Hello is begin Put_Line ("Hello, world!"); end Hello; Not that it's at comparable complexity, but I know what the following code does, but I still can't understand it. It's basically obfuscated: module Main where import Control.Monad import Control.Concurrent import Control.Concurrent.STM main = do shared <- atomically $ newTVar 0 before <- atomRead shared putStrLn $ "Before: " ++ show before forkIO $ 25 `timesDo` (dispVar shared >> milliSleep 20) forkIO $ 10 `timesDo` (appV ((+) 2) shared >> milliSleep 50) forkIO $ 20 `timesDo` (appV pred shared >> milliSleep 25) milliSleep 800 after <- atomRead shared putStrLn $ "After: " ++ show after where timesDo = replicateM_ milliSleep = threadDelay . (*) 1000 atomRead = atomically . readTVar dispVar x = atomRead x >>= print appV fn x = atomically $ readTVar x >>= writeTVar x . fn
- Peaker 12y agoWhat exactly do you feel is obfuscated? There's $, backticks, >>=, >>, ++, ., and <-. All of these are very frequent things you use in Haskell, and deserve short notation. Besides >>, they're all learned in day 0-1 of Haskell.
- wz1000 12y agoPersonally, I believe Haskell syntax is a work of art. Learning how it fits together with currying is extremely satisfying. Also, the meaning of all the operators you mention, with the exception of (>>=), is immediately clear from their types. (.) :: (b -> c) -> (a -> b) -> (a -> c) It is clear that it takes two functions, and chains them together to create a new function f . g = \x -> f (g x) So double (addOne 3) is equivalent to (double . addOne) 3 Similarly, (!!) has type (!!) :: [a] -> Int -> a It is immediately obvious from the type that it acceses the object at a particular index in a list, so ['a', 'b', 'c'] !! 1 == 'b' Also, the syntax complements currying extremely well f g h x is equivalent to (((f g) h) x) This allows for some very neat things. addOne :: Int -> Int -- addOne 3 == 4 map :: (a -> b) -> ([a] -> [b]) -- which is equivalent to '(a -> b) -> [a] -> [b]' map is an extremely neat function, and is used in many languages. It applies a function to every element of a list, producing a new list. Now, there are two ways to use map map addOne [1, 2, 3, 4] == [2, 3, 4, 5] However, the above is equivalent to (map addOne) [1, 2, 3, 4] From this we see there is another way to use map addOneList :: [Int] -> [Int] addOneList = map addOne -- addOneList [1, 2, 3, 4] = [2, 3, 4, 5] Note how map was partially applied. In Haskell, map can be seen as doing two things. One is taking a function and a list, and applying the function to every element in it to produce a new list. However, you can also see map as a function transformer, taking an ordinary function, and converting it into a function that works on lists! map :: (a -> b) -> ([a] -> [b]) -- which is equivalent to '(a -> b) -> [a] -> [b]'
- okasaki 12y agoThe Haskell's record/struct syntax is probably the worst of any language. C style: a.b.c = 1; Haskell: let b' = b a c' = 1 + c b' b'' = b' { c = c' } in c' { b = b'' }
- nbouscal 12y agoHave you ever tried doing any non-trivial work in Haskell? I've used it professionally, and spoken with a lot of other people who have, and exactly zero people have expressed an experience that the naming of operators has caused the language to be less practical for them. Some think it's less aesthetically pleasing than it could be, but that's not a practical concern. Furthermore, the specific operators you cite are confusing examples, given that ">>=" can be elided using do notation, "\" looks enough like a lambda that it took me a while to remember what you were referring to, and "!!" is rarely used. A slightly more reasonable argument for your case would be to cite the operators used in the lens library, but those are all aliases for regularly-named functions. There are some arguments against Haskell in terms of practicality, but this is not one of them.
- coolsunglasses 12y ago>"!!" is rarely used We just finished the lists chapter in Haskell Programming and we never even mentioned that operator. It's a silly function ^_^
- jdminhbg 12y ago> I've used it professionally, and spoken with a lot of other people who have, and exactly zero people have expressed an experience that the naming of operators has caused the language to be less practical for them. This is a pretty self-selecting set. One of the reasons I don't use Haskell professionally is that I hate its operator-naming culture, and Haskell isn't big enough in industry yet that it has lots of involuntary users (like C++ or PHP or Java does).
- nbouscal 12y agoAs I said, you can definitely raise aesthetic objections. You're free to hate operators all you want, though it does strike me as a peculiar basis on which to decide what tool to use. My point was whether there are actual practical implications, though, and I don't think the self-selected nature of Haskell professionals has any bearing on that. I frequently hear many other objections from people working in the language, so it's not a case of rose-colored glasses in which we think everything about the language is fine. It's simply a case of operator naming not being very important, from a practical perspective. To the extent that it is important, most people who actually use the language think it's a benefit, not a detriment.
- Peaker 12y agoIn C or C++, there are even more unfamiliar operators: >>= += <<= -= *= ... ?: ! ~ ^ % ...
- tormeh 12y agoPreaching to the choir. I hate those languages. If I had to choose between coding C or Haskell for the rest of my life I would definitely choose Haskell.
- Peaker 12y agoWould you say these languages are impractical because of their stylistic choice to use operators? I think people have a preconception that "Haskell is not practical" -- and then anything that they do not find appealing becomes a source of its impracticality. Despite the fact that the same traits are shared with vastly practical languages.
- tormeh 12y agoYes, I do find their use of operators impractical. In particular the pointer syntax drives me up the wall. I never seem to get it right. As does the printf syntax, come to think of it. Why is integers refered to with "%d"? Can't come up with a reason. And dynamically allocating function pointers on the heap (calloc) requires completely batshit insane keyboard manoeuvres. It would have been a lot better if it was typechecked, which is why I would prefer Haskell. I can vaguely sense somewhere in my memory that <<= and it's ilk are bit shift operators. How am I supposed to know that? Fuck it. It's bad library design. I like Python. How do you append to aList? Answer: aList.append(anElement). Scala, on the other hand, seems to believe that ":+" is an acceptable append syntax. The compiler won't let me do stupid stuff with it, which is good, but I would prefer it if errors was caught by English-proficiency instead of rote knowledge/the compiler. I think that's a very powerful distinction.
- nbouscal 12y agoYou would prefer errors to be caught by a human needing to exercise their English-proficiency over errors being caught by the compiler? Seriously? That can't actually be what you mean.
- qubitcoder 12y agoThere's a nice writeup describing the simplicity of Haskell syntax. [0] Haskell has 21 reserved keywords that cannot be used as names for values or types. This is a relatively low number (Erlang has 28, OCaml has 48, Java has 50, C++ has 63. In particular, some of the operators you mention represent such fundamental and common tasks that it makes sense to have a shortened form. I'm in agreement that descriptive names are preferable in general, but not always. Haskell syntax is quite simple and predictable (I say that as a former Rubyist); it only appears strange in the beginning because there are so many new concepts to learn. [0] https://github.com/kqr/gists/blob/master/articles/simple-syntax-of-haskell.hs https://github.com/kqr/gists/blob/master/articles/simple-syn...
- rifung 12y agoI'm learning Haskell right now for fun and don't personally have any opinions on the naming of operators. However, I will say that "." is as far as I can tell a practically named one, because it is just composition which in mathematical notation is also a dot.
- burke 12y agoIt's easy to believe. Haskell has a much steeper learning curve than... well, really any other (even remotely practical) language. I put in a fairly concerted effort a few years back and didn't make it over the first productivity hump. That's never happened to me with any other language, and I think I'm not alone in that experience. Regardless of its practicality or lack thereof, Haskell is definitely at least hard to get started with.
- wz1000 12y agoI've heard claims that it is only so because you come from an established imperative mindset, and that it would be as easy(or difficult) for a person with no programming experience to learn Haskell as a traditional imperative language. It is an interesting point, though I've seen no actual examples that verify it.
- coolsunglasses 12y agoMy coauthor for http://haskellbook.com/ http://haskellbook.com/ had never programmed before, so I have some experience teaching people Haskell that have used imperative languages and some experience teaching people that have no prior programming experience. 1. It's not a panacea 2. It's still more work overall to teach Haskell (or any language) to somebody that has never programmed before 3. It's more fun teaching them because they don't argue with you or waste time trying to apply nouns/verbs they already know to Haskell.
- vezzy-fnord 12y agoThere is certainly some truth to this, but I don't think it captures the entire situation all that well. Given that we're largely speaking from anecdotal evidence anyway, I'll share mine. The first non-ALGOL language I learned was Smalltalk, using Pharo. Its relative lack of syntax pretty much meant I could dive right in, with most practical programming involving the class libraries and navigating the Smalltalk environment with the integration intricacies of the binary image. I never really felt it as all that difficult though, even though imperative mindsets are allegedly supposed to make it that way. The first functional language I learned (and the one I'm most proficient in) was Erlang. Despite being infamous for its unconventional Prolog-esque syntax, it took me only about 2-3 days to get comfortable with it and I breezed through Programming Erlang relatively quickly. I have since found it quite enjoyable to work with. On the other hand, I never did manage to learn Haskell to any notable degree. I've always given up eventually, and haven't retried in a while. It's just a more complicated language.