Live data from Hacker News

Reflecting on Haskell in 2016

stephendiehl.com

41–50 of 107 posts

Re: Reflecting on Haskell in 2016

#41
post #36
post #19

Earlier quoted context omitted.

Most people use Lenses for heavily record-oriented programming. They work quite well. They are less convenient than built-in structural syntax like in Javascript, but once you get past the initial inconvenience they are vastly more powerful.

On the contrary, lenses are far more powerful than what's available in JavaScript and all other OO languages. Traversals and Prisms give so much power that's lacking in OO

I don't see how that's contrary to what the parent said.

Re: Reflecting on Haskell in 2016

#42
post #32
post #6

Earlier quoted context omitted.

Note that it's a contentious issue. Lots of people think there's plenty of documentation. I'm one of them. The people who think documentation is lacking seem to be people who need worked examples of things to understand them. I'm of the opinion that worked examples are often worse than no documentation.

> I'm of the opinion that worked examples are often worse than no documentation. I'm not, especially for the many more-abstract-concepts. I have yet to see a followable code case demonstrating the use of custom monads (not IO or Maybe or lists etc) that show why (when) I should ever write my own, to understand even just using them better generally.. A lot of explanations in the Haskell ecosystem are super-abstract an…

> I have yet to see a followable code case demonstrating the use of custom monads (not IO or Maybe or lists etc) that show why (when) I should ever write my own, to understand even just using them better generally.

For an interpreter I'm working on I have an "Eval" type, implemented as a newtype wrapper around a transformer stack. This gives me a context to work in where I can access variables in scope (carried in a ReaderT) and fail with error (handled by an ExceptT). The code (simplified) looks a little like this:

    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE LambdaExpr #-}
    newtype Eval a = Eval (Reader EvalContext (ExceptT String m) a)
        deriving (Functor, Applicative, Monad, MonadReader EvalContext, MonadError String)

    lookupVariable :: Variable -> Eval Value
    lookupVariable v = asks (findVarInContext v) >>= \case
        Nothing -> throwError ("unbound variable: " ++ show v)
        Just result -> pure result

    lookupFunction :: FunctionName -> Eval ([Value] -> Value)
    lookupFunction f = asks (findFuncInContext f) >>= \case
        Nothing -> throwError ("unknown function: " ++ show f)
        Just f' -> pure f'

    evaluateFunction :: Function -> Eval Value
    evaluateFunction (Function name args) =
        lookupFunction function  mapM evaluateExpr args

Re: Reflecting on Haskell in 2016

#43
post #6
post #5

The Haskell community identifies "no documentation" as a key flaw of their own community? I was going to ask why there hasn't been more uptake of Haskell for all of the apparently cool ideas that are there, but nevermind, I don't think I need to ask now.

Note that it's a contentious issue. Lots of people think there's plenty of documentation. I'm one of them. The people who think documentation is lacking seem to be people who need worked examples of things to understand them. I'm of the opinion that worked examples are often worse than no documentation.

I'm one of those who need examples. Fortunately, haddock has this "source" link on each function, so I typically find something usable by browsing through the source of the library I'm using. This takes a lot more time than it would to just have an example in the docs themselves, of course (and isn't always even fruitful).

I do notice that after a while, I can get more and more from types alone, but I would never get to that point without examples first.

----

I don't see why examples couldn't be type-checked though, so they never become out-dated – is there no way to do that with haddock?

Re: Reflecting on Haskell in 2016

#44

The Haskell community is incredibly blessed to have Stephen Diehl around. This is an excellent write up on so many of the things that have happened in the Haskell community this year, not to speak of his other written guides and in-depth explanations which are amazing.

I came here after reading the article to say something like this. I try to follow the Haskell community, reading articles etc, but I had missed a lot of this stuff.

Re: Reflecting on Haskell in 2016

#45

I started learning Haskell this year. One of the small bumps I had was getting my environment setup. Based on my experiences with Ruby and Node, I knew I'd want to have a tool for managing the language's version and dependencies per-project, so I ended up going with stack [0]. Arriving at that decision required a bit more reading than with other languages. Additionally, while setting up stack, I thought their docs we…

I'm in the same boat as you. I learning Haskell earlier this year, and while I really really want to like it (if nothing else, I'm a sucker for type systems) and even start using it for projects I can't when, IMO, there are languages out there that feel so much more productive to me. A few key concerns I have with the language and community:

1. I feel like there is a really strong push towards writing concise code, which make it really hard to approach for me. I've seen a lot of code which substitues words as function names for 2 or 3 character symbols. I'm okay with learning `>>=` and the like, but when every library want to invent its own symbol-functions, I feel like the barrier to entry for me becomes much higher. This occours in just about every high profile library I've seen, from parsers to web frameworks; everyone wants to invent their own DSL.

2. For as much as Haskell seems to pride it self on function composition I don't think `.` is the best way to do so; Clojure's threading macros are much more readable to me. Comparing the thread-last macro ``` (->> (range 10) (filter odd?) (map #(* % %)) (reduce) ``` to Haskell's composition operator `(sum . (map (\x -> x * x)) . (filter odd)) [1..10]`. (Please correct me if there is a clearer way to write this.) The former is much more readable from and LTR English language PoV. In Haskell I need to start from the right and work my way left; and this become even more harder for me to decipher when function operator precedence starts coming into play. It's small quality of life things life this which makes all the difference IMO.

3. The millions of syntax extensions in ghci, some of which are incompatible with each other. This means ProjectA and ProjectB can be written in completely different, possible incompatible, 'dialects' of Haskell. Now I have to learn the base Haskell languge and whatever language extensions that project has dedcided to use just so I can start reading and understanding the code.

4. AFAIK, there is now easy way to get function documentation in the repl. Sometimes types aren't enough for me and I would like to have some human written documentation guide me when I'm trying to use a library.

Re: Reflecting on Haskell in 2016

#46
post #40
post #9

Earlier quoted context omitted.

I'm also in the "I think there is plenty of documentation" camp, so this topic tends to confuse me when it comes up. I suppose what people who are curious about Haskell find lacking are definitive language guides like the Rust Book, Effective Go, and the like?

I am one of the people who are interested in Haskell and find its documentation lacking. I don’t miss comprehensive language books, I miss module documentation. It almost looks as the Haskell community has something against examples in documentation. I stress that the types are not enough . Contrast that with Elm, where I was able to write a working app in a day or so. But Elm is written off quite harshly in the post…

Elm was written off because it still does an incredibly bad job at implementing polymorphism. It has a hardcoded "Show" class for turning things into strings and only certain privileged entities can be turned into strings using it.

It's all in all a very bad way to do polymorphism and that's what the article points out. It's especially odd in a language like Elm, that obviously is supposed to be like other ML-like languages.

Re: Reflecting on Haskell in 2016

#47
post #46
post #40

Earlier quoted context omitted.

I am one of the people who are interested in Haskell and find its documentation lacking. I don’t miss comprehensive language books, I miss module documentation. It almost looks as the Haskell community has something against examples in documentation. I stress that the types are not enough . Contrast that with Elm, where I was able to write a working app in a day or so. But Elm is written off quite harshly in the post…

Elm was written off because it still does an incredibly bad job at implementing polymorphism. It has a hardcoded "Show" class for turning things into strings and only certain privileged entities can be turned into strings using it. It's all in all a very bad way to do polymorphism and that's what the article points out. It's especially odd in a language like Elm, that obviously is supposed to be like other ML-like la…

My point is: I tried several times to write something in Haskell, I really want to like the language. But each time I felt too stupid for it, it just feels like too much work. In Elm I got a working app in a day and enjoyed the experience. Isn’t there a lesson for the Haskell community other than “Elm does polymorphism wrong, meh”?

Re: Reflecting on Haskell in 2016

#48

I started learning Haskell this year. One of the small bumps I had was getting my environment setup. Based on my experiences with Ruby and Node, I knew I'd want to have a tool for managing the language's version and dependencies per-project, so I ended up going with stack [0]. Arriving at that decision required a bit more reading than with other languages. Additionally, while setting up stack, I thought their docs we…

I'm in the same boat as you. I learning Haskell earlier this year, and while I really really want to like it (if nothing else, I'm a sucker for type systems) and even start using it for projects I can't when, IMO, there are languages out there that feel so much more productive to me. A few key concerns I have with the language and community: 1. I feel like there is a really strong push towards writing concise code, w…

Your example can be written more clearly (IMO) in Haskell like this:

  sum $ map (^2) $ filter odd [1..10]
Or, defined as a function:

  > let foo = sum . map (^2) . filter odd
  > foo [1..10]
  165
You can write it without using the composition operator at all, if you prefer:

  > let bar xs = sum (map (^2) (filter odd xs))
  > bar [1..10]
  165
In general, you can write out your programs as crazy sequences of operators (whose precedence may not be obvious to the reader):

  > take 5 . unfoldr (Just . next)  getStdGen >>= putStrLn . show
  [1336079013,234736121,108049288,410228860,1573295749]
But you don't have to:

  > let infiniteRandoms = unfoldr (Just . next) :: StdGen -> [Int]
  > gen  let fiveRandoms = take 5 (infiniteRandoms gen)
  > putStrLn (show fiveRandoms)
  [1336079013,234736121,108049288,410228860,1573295749]
People seem to think Haskell is all about writing your whole program in a single hideous line of code with incomprehensible sequences of arcane operators glued together by a glut of anonymous functions, but that's just bad code.

As for left-to-right vs right-to-left, I have never had a problem with the way Haskell does it. I think if you're coming from a language that does it differently, it makes sense that Haskell would trip you up in that regard. Haskell's composition operator matches the way it's usually written in mathematics, but there's nothing special about it and you could change it to go the other way if you really wanted to (but please don't):

  > let g . f = \x -> f (g x)
  > let foo = filter odd . map (^2) . sum
  > foo [1..10]
  165
`(>>>)` from `Control.Arrow` is a more reasonable way to get that sweet left-to-right action but using it might still throw people off:

  > let foo = filter odd >>> map (^2) >>> sum
  > foo [1..10]
  165

Re: Reflecting on Haskell in 2016

#49
post #40
post #9

Earlier quoted context omitted.

I'm also in the "I think there is plenty of documentation" camp, so this topic tends to confuse me when it comes up. I suppose what people who are curious about Haskell find lacking are definitive language guides like the Rust Book, Effective Go, and the like?

I am one of the people who are interested in Haskell and find its documentation lacking. I don’t miss comprehensive language books, I miss module documentation. It almost looks as the Haskell community has something against examples in documentation. I stress that the types are not enough . Contrast that with Elm, where I was able to write a working app in a day or so. But Elm is written off quite harshly in the post…

To be fair this thread is an example of the Haskell community agreeing with you: https://www.reddit.com/r/haskell/comments/2ory86/there_is_a_... (2014)

After using the language for two years I find that the types are actually enough to understand a new library, however, am taking for granted that it's an acquired skill.

Looking back I do recall being in the same position as you, someone who just wanted to wrap their head around something and get an example working. I was stubborn and plowed through things I didn't understand until it clicked, but do realize that not everyone is as hard headed as myself.

Post reply on HN