Hacker News new | ask | show | jobs
by sksk 3767 days ago
I am not a professional developer (never gotten paid to write software) but now do some prototyping code in Haskell so real engineers can pick it up from me later.

For me, Haskell has been a huge productivity booster. It forces me to write good code and 90% of mistakes that I normally make are all caught at compile time. I use servant for creating my API server and it is pleasure to use (being able to create APIs declaratively is very easy for me to understand as a non professional). I recently had to write some front-end code in JavaScript and I noticed how simple mistakes can take 1/2 hour to debug (you pass in an array of objects instead of an object and you will wonder why `for (k in obj)` logic is not working.

I refactor huge parts of my code - can gut a particular API endpoint response and rewrite it without worrying about introducing more bugs. This allows me to start writing code without a lot of planning and refactor as I go instead of spending a lot of time upfront thinking through the implications.

Using Hoogle or Hayoo to search for functions based on types is just simply awesome. If you want a function that returns the index of a list that satisfies a predicate, you don't need to come up with search words instead you just look for it based on the types like so: http://hayoo.fh-wedel.de/?query=%28a+-%3E+Bool%29+-%3E+[a]+-.... This does not mean you can solve all problems this way but it is very quick to get easy answers than Googling or putting it on SO.

Most developers write their APIs and need to spend more time documenting it. With servant I just derive documentation directly from the types so my documentation moves in lock step with my code.

That said, using Haskell has its challenges (especially as a beginner).

* Compile-refresh cycle is frustrating. With Python or Go, you make a change and refresh the page, it is there. With Haskell, the 30s wait can become painful. My code is organized into modules but it is hard to avoid dependency related compile issues -- I tend to put most of my data records (mostly related by business logic) in a module and if you add anything to this module, you will end up recompiling everything that depends on it (which is most of the code). I am sure a pro-Haskeller would do it differently but whatever suggestions available online is not steering me in the right direction.

* Starting out with a fresh framework is not trivial for a beginner. servant is really nice because it came with very good documentation and also a tutorial by someone on how to use it with wai (http server) and persistent (an ORM). Without it, I would not have been able to get to where I am now.

* Not all libraries are created equal -- some of the common use cases are well documented or has enough documentation that you will be ok. But once you venture beyond common use cases, trying to use a library is not easy. Most of the time, types help and being able to test it in the REPL is nice but it can only take you so far. I recently looked at a library for creating a MIME string but got lost in some undocumented library.

* Haskell's community is great. You will always find someone to help you. However, as the author was saying, you want to get some work done and you cannot wait 2 days for an answer on Reddit or SO. IRC is great for specific libraries (say servant or Yesod) but general #haskell can be daunting -- 90% of the people seem to be discussing Lenses or Free Monads and your stupid type error is not going to get any attention.

* Easy parts of Haskell are very easy to pickup and the hard parts seem impossible to fully comprehend (I will think I understand Monad Transformers and will try to implement some logic but will get stuck in type check hell and quickly give up).

Btw, I did not know about fieldLabelModifier until now and it will cut down a lot of boiler plate. That said, I cannot wait for GHC 8 and its Duplicate Record Fields! Records are really annoying for writing business logic driven API servers.

4 comments

A workaround for long compile times is trying to stay withing GHCi whenever possible and reload from there.

http://chrisdone.com/posts/haskell-repl

http://chrisdone.com/posts/making-ghci-fast

The Haxl team seem to use this strategy:

"Haxl users at Facebook do a lot of development and testing inside GHCi. In fact, we’ve built a customized version of GHCi that runs code in our Haxl monad by default instead of the IO monad, and has a handful of extra commands to support common workflows needed by our developers."

http://simonmar.github.io/posts/2016-02-12-Stack-traces-in-G...

I find ghcid very useful. It reloads your code automatically when it detects a filechange.

https://github.com/ndmitchell/ghcid http://neilmitchell.blogspot.de/2014/09/ghcid-new-ghci-based...

#haskell has always helped me, provided that I did my homework first. If they don't tackle your question, wait a little while and break it down into smaller pieces. It makes life easier for everyone, and usually allows them to help you faster.
Fantastic response.

In regards to changing data records I've suffered the same problem as well. At best I've isolated what I can into separate modules so the impact is smaller after a small change, but obviously isn't universally applicable.

Note that there is also a #haskell-beginners IRC channel where it's sometimes easier to get a responses to certain questions than the much broader #haskell channel. Both channels are full of incredibly nice people for sure.

I too did not know about fieldLabelModifier and am excited about the GHC 8 changes as well!

Thank you. This is the reason I read HN.