Edward Z. Yang, a PyTorch developer, writes about Haskell, compilers, and machine learning framework internals.
Commenters recommend his PyTorch Internals post as a learning resource and cite his posts on dynamic programming, databases as categories, and Haskell's character.
You might want to start with: http://blog.ezyang.com/2010/10/ocaml-for-haskellers/ and explore the languages for what they are yourself.
I haven't tried Haskell apart from the very basic stuff, but if you have tried your hand at it for too long, and aren't able to make any headway, then you might as well invest time in learning OCaml/F# or Erlang or Idris or Rust or Elm instead. I hear Rust and Elm are pretty good too.
OCaml doesn't do mutli-core, I think [0], whilst Haskell has great support parallelism, concurrency [1]. Erlang, of course, is absolutely amazing at that too.
I primarily learn languages to expand my understanding of various programming constructs. It feels liberating to know that things are much easier in certain languages due to presence of certain constructs absent in other languages. For instance, OCaml is insanely good for compiler design and/or static analysis primarily due to 'variants' and the type system; Go (channels)/Erlang (actor-based programming, hot-plug code)/JVM-based languages (Clojure/Scala et al running on vastly optimized vm) for building massively concurrent systems; Ruby for being expressive, powerful, and simply awesome; JavaScript for... well... getting a taste of event-driven programming.
The challenges faced when using some of these languages are fascinating and at some point, it all comes together, as you try searching for a language in another language (like trying to mimic functional/reactive paradigms in Java 7 or below when…
The point is a little more subtle than this, or how the article made it out to be.
Global coherence and confluence (which GHC attempts to enforce unless told otherwise) is great for refactoring and equational reasoning and (yes) mathematics and programming at large, as Ed Kmett's fantastic "Typeclasses v. the World" talk covers:
https://www.youtube.com/watch?v=hIZxTQP1ifo
Global uniqueness of instances (which GHC does NOT enforce) is bad for modular programming, or programming at large, which is a point some of the commenters here are making.
http://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/
The submitted HN link here has a terrible title. What the author is proposing is enforcing typeclass laws, which is a great idea (but difficult in practice to implement). Practice and time has shown that lawless classes are the ones that people hate, the ones that don't add any benefit and in fact make it harder to reason about large Haskell programs.
I hope people don't take away from this link that classes in Haskell are bad. Haskell is three things: pure, functional, and typeclasses. They're part of the identity of Haskell; they're the reason we set off on this wonderful journey into the uncharted oceans of functional programming back in 1990. Typeclasses are AWESOME. And they can be improved.
Postscript: Kmett also has a package that persuades the compiler to let you have dynamically generates instances. It has the same user experience as…
Here are a bunch of blogs from my RSS reader that I think are worth reading. Some of them haven't updated in a while, but the archives may be worth a look anyway.
* Blogs with a math focus:
http://blog.sigfpe.com
http://bit-player.org
http://mathr.co.uk/blog/
https://www.johndcook.com/blog/
* Blogs with a programming languages focus:
https://existentialtype.wordpress.com
https://bluishcoder.co.nz
http://blog.ezyang.com
http://akkartik.name
http://lambda-the-ultimate.org
http://mrale.ph
* Blogs with a UI design focus:
http://www.brandonwalkin.com/blog/
http://ignorethecode.net/blog/
http://interuserface.net
* Blogs with a graphics / 3D rendering focus:
http://c0de517e.blogspot.com
http://diaryofagraphicsprogrammer.blogspot.com
https://directtovideo.wordpress.com
http://graphicrants.blogspot.com
http://www.reedbeta.com
http://www.realtimerendering.com/blog/
https://blog.demofox.org
http://eelpi.gotdns.org/blog.wiki.html
* Other interesting / more general programming blogs (many of these have a "systems" focus):
http://danluu.com
http://ewontfix.com
http://chneukirchen.org/blog/
http://neverworkintheory.org
http://apenwarr.ca/log/
https://www.snellman.net/blog/
https://www.pvk.ca
http://psy-lob-saw.blogspot.com
https://randomascii.wordpress.com
http://fastcompression.blogspot.com
https://fgiesen.wordpress.com
http://blog.plover.com
http://chneukirchen.org/trivium/
http://rachelbythebay.com/w/
I must respectfully disagree that Haskell's memory footprint is simply 'low'. This is because the memory footprint of a given Haskell program is not at all transparent, and Haskell is notorious for leaking memory in a maddeningly opaque fashion [1, 2, 3, 4]. Space leaks might be relatively straightforward to diagnose and fix for a true domain expert, but I would not want to have to rely on someone having such abstruse knowledge in a production application. It goes without saying that a space leak in a production app is a really, really bad thing.
Although, I suppose one's choice of Haskell is a function of one's own risk/reward profile. Haskell and its failure modes are hard to understand. That induces extra risk that some people (myself included) might be uncomfortable with. That said, I am now enthusiastically following you guys and hope to see the proverbial averages get sorely beaten.
[1] http://neilmitchell.blogspot.com/2013/02/chasing-space-leak-in-shake.html
[2] http://blog.ezyang.com/2011/05/calling-all-space-leaks/
[3] http://blog.ezyang.com/2011/05/space-leak-zoo/
[4] http://blog.ezyang.com/2011/05/anatomy-of-a-thunk-leak/
I see a lot of comments in here about the v2+ rule’s reason for existing being to allow importing multiple major versions of a module. That’s not it at all. As the blog post (which was easily Googled by me and explains things quite well IMO) states: “If an old package and a new package have the same import path,
the new package must be backwards compatible with the old package.”
They’re trying not to break compatibility until a downstream developer explicitly opts in to that breakage. The simplest way to do that is to give the module a new name. And the simplest way to do that is append the major version to the name.
Here is the post: https://blog.golang.org/v2-go-modules
For more background on this principle, I recommend Rich Hickey’s Clojure/conj keynote “Spec-ulation” from 2016: http://blog.ezyang.com/2016/12/thoughts-about-spec-ulation-rich-hickey/
Not quite, there were a bunch of other persistent data structures. Finger trees, PATRICIA tries, etc. And the perf was competitive. See http://blog.ezyang.com/2010/03/the-case-of-the-hash-array-mapped-trie/ for example. In there Haskell's IntMap (powered by a PATRICIA trie) just beats out Clojure's HAMT without transients. In practice they're probably more or less equal, because in order to make IntMap usable for arbitrary keys and not just ints, you need to have a hashing step first that generates an int from an arbitrary key, so you have the overhead of a single hash.
Ah you're totally right RE transients. I don't know why I had the notion they were tied to HAMTs... Nonetheless I view it as one of the big improvements that Clojure brought to the scene.