5 ms·
I agree. You master monads and IO, but then you want to use a web framework and there a bunch of other category theoretical concepts and/or Haskell advanced fea
by quickthrower2 7y ago
I agree. You master monads and IO, but then you want to use a web framework and there a bunch of other category theoretical concepts and/or Haskell advanced features you need to understand to serve up "Hello World". Compare that to expressjs. I love functional programming, but given the free choice of what to use to knock up a side project, I chose JS at home. Nothing like grabbing some data from a server, and it being an object you can use immediately in your code and access using indexers, properties etc (rather than some strange lens operator like ~~!!#).
Typescript cures most of the JS ills. Sure TS is more akin to Java/C# and not the much better Haskell type system. But it is good enough and catches 99% of the real world problems of naked JS.
To me Haskell is training for your brain. Once trained you are a better JS/C#/Java/C++ programmer.
I could go on about the economics of getting a Haskell job:. Haskell and Elm developers are taking a paycut compared to what they would earn if they used any language. Even if they are paid well they could get paid more. Supply/demand at work there.
- karmakaze 7y agoHow far can you go without monads and category theory? I was looking at Clean which developed in parallel with Haskell and uses uniqueness typing instead of IO/mutation monads. Seems like it would be less offputting for a newcomer. Clean lacks community and a package manager, I believe which makes it less attractive. The language itself seems like a sweet spot for me.
- quickthrower2 7y agoNot used Clean, but it sounds interesting. What i'd love is an imperative language where you declare what effects a method can have and the compiler enforces them. E.g. if it promises not to mutate any parameters, it can only call functions that make the same promise etc.
- malvosenior 7y agoThat sounds very similar to Rust. Mutations and even memory lifetime are specified in the type system.
- brabel 7y agoThis is how Pony does it, basically. See [Reference Capabilities](https://tutorial.ponylang.io/reference-capabilities.html https://tutorial.ponylang.io/reference-capabilities.html).
- cinnamonheart 7y agoIdris isn't imperative (Haskell-like with dependent types), but offers features like those: http://docs.idris-lang.org/en/latest/effects/depeff.html http://docs.idris-lang.org/en/latest/effects/depeff.html readInt : Eff Bool [STATE (Vect n Int), STDIO] [STATE (Vect (S n) Int), STDIO] http://docs.idris-lang.org/en/latest/st/machines.html http://docs.idris-lang.org/en/latest/st/machines.html logout : (store : Var) -> ST m () [store ::: Store LoggedIn :-> Store LoggedOut] They're both implemented within Idris, as libraries/modules, rather than being compiler magic: - https://github.com/idris-lang/Idris-dev/blob/master/libs/contrib/Control/ST.idr https://github.com/idris-lang/Idris-dev/blob/master/libs/con... - https://github.com/idris-lang/Idris-dev/blob/master/libs/effects/Effects.idr https://github.com/idris-lang/Idris-dev/blob/master/libs/eff... I think it'd be possible to write similar effect systems in other dependently typed languages like ATS, which is a relatively imperative language (C+ML-like).
- chas 7y agoIf you want to be productive in Haskell, the Monad typeclass is an important tool to familiarize yourself with. That said, unless you are working on the internals of a few libraries, you don't really ever need to know serious category theory in order to be very productive. If you don't already have a background in abstract algebra or category theory, I think a better approach to learning these abstractions is slowly work through the typeclassopedia[0] while solving problems the naive or clunky way and then start to use the fancy-name abstractions (e.g. Functor, Applicative) as you see how they could be useful. On that front, the Monad typeclass is far more general and useful than just for IO and State, so if you are thinking of it as primarily a hack to deal with those, you probably won't get the hype. In addition, it's really useful to work with a large number of examples of different Monad instances (IO, State, Maybe, List, STM[1] if want to get a bit further into the deep end) instead of just staring at the methods in the typeclass and hoping it make sense. It's a pretty broad abstraction, so it will only make sense if you are familiar with what it's abstracting. [0] https://wiki.haskell.org/Typeclassopedia https://wiki.haskell.org/Typeclassopedia [1] http://book.realworldhaskell.org/read/software-transactional-memory.html http://book.realworldhaskell.org/read/software-transactional...
- karmakaze 7y agoThanks for this info. What I really want to know is the value prop for learning/using monads etc. The examples of IO, State, Maybe, List, STM given seem like they'd be dealt with just fine in Clean.
- chas 7y agoI think it's important to be precise about how the monad abstraction and type system features interact in order to combine pure and impure code. I wrote a comment elsewhere in the thread (https://news.ycombinator.com/item?id=20112333 https://news.ycombinator.com/item?id=20112333) where I conclude that while the monad abstraction is useful for making a usable interface and writing programs which are agnostic to how their state is implemented, the fundamental work of distinguishing pure and impure computations is accomplished with a combination of type system features and compiler magic. The case is exactly the same for the Clean language as for Haskell and indeed Clean has Monad instances for all of the types I mentioned aside from STM, so there are no concerns with dealing with those monadic abstractions in Clean. (https://imgur.com/a/sjsDiZq https://imgur.com/a/sjsDiZq, https://cloogle.org/#using%20Monad https://cloogle.org/#using%20Monad) Since IO is Haskell's type that marks impure computations, we can compare Haskell's implementation to the equivalent one in Clean (interface: https://cloogle.org/src/#Platform/System/IO;line=10 https://cloogle.org/src/#Platform/System/IO;line=10, implementation: https://cloogle.org/src/#Platform/System/IO;icl https://cloogle.org/src/#Platform/System/IO;icl) In Clean, IO is implemented as follows: :: IO a = IO .(*World -> *(a, !*World)) In Haskell, it is: newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #)) (for full context see: http://hackage.haskell.org/package/ghc-prim-0.5.3/docs/src/GHC.Types.html#IO http://hackage.haskell.org/package/ghc-prim-0.5.3/docs/src/G..., the related monad instance is here: http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#line-1363 http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GH...) These both implement IO as a function which takes the state of the world as its input and returns a new state of the world as it's output. This is encoded using the state transformation that I mention in the other post (https://acm.wustl.edu/functional/state-monad.php https://acm.wustl.edu/functional/state-monad.php) Both implementations also go on to define Monad instances for their new IO type. The major difference is that the Haskell standard library only exposes bindIO and returnIO to the user and hides the internals of IO from the user and Clean allows the implementation to be a normal library. That difference is Clean's uniqueness types showing their strength. Clean can explicitly expose it's predefined World type (https://cloogle.org/doc/#CleanRep.2.2_6.htm;jump=_Toc311798037 https://cloogle.org/doc/#CleanRep.2.2_6.htm;jump=_Toc3117980...) to the user with the guarantee that you can't write a function of type IO a -> a because it would violate the uniqueness properties and thus be a compilation error. Haskell instead uses the module system to keep State# RealWorld from being exposed to the user. This means that if you as a user want a different set of abstractions for impurity in Clean, you can build from the World level rather than needing to construct it out of what can be done with bindIO and returnIO. For details on what's going on with State# see https://www.fpcomplete.com/blog/2015/02/primitive-haskell https://www.fpcomplete.com/blog/2015/02/primitive-haskell From the perspective of "the value prop for learning/using monads", this discussion leaves us in a worse place than where we started because the conclusion is that uniqueness types aren't a get out of monads free card and that Clean uses the many of the same Monad-related abstractions as Haskell does and uses them for the same purposes. In order to not leave you out in the cold as to the value prop for the monad abstraction, you can see how it works for a number of different Monad instances in Tikhon's answer on Quora (https://www.quora.com/What-are-monads-in-functional-programming-and-why-are-they-useful-Are-they-a-generic-solution-to-the-problem-of-state-in-FP-or-Haskell-specific-Are-they-specific-to-Haskell-or-are-they-encountered-in-other-FP-languages https://www.quora.com/What-are-monads-in-functional-programm...), though he chooses to use join, fmap, and return as the fundamental parts of a Monad, rather than bind and return, as I have here. As he touches on in his discussion, it's common and straightforward to implement one definition in terms of the other, so anything you learn from about that definition can be ported the definition I use without much fuss, so don't worry if it doesn't match at first. What this means is that if you have a tools in the standard library that only depend on features of Monad, you can use the same small collection of functions to solve a ton of problems.
- merijnv 7y ago> How far can you go without monads and category theory? Without monads? Not pretty far, but they're far simpler than the wide web would have you believe. Without category theory? Sky's the limit. I say this as experienced Haskell programmer occasionally dabbling in category theory for funsies. The practical impact on "how easy is it to program Haskell" of category theory is basically zero.
- karmakaze 7y agoI didn't mean how far in Haskell without monads. I meant how far in something else like Clean that uses uniqueness typing to handle some of the same aspects where monads would be used with Haskell.
- almostdeadguy 7y ago> I agree. You master monads and IO, but then you want to use a web framework and there a bunch of other category theoretical concepts and/or Haskell advanced features you need to understand to serve up "Hello World". Compare that to expressjs. I started using haskell at my last job after having done a couple years of functional programming in scala, but I honestly never found it required that much knowledge of category theory. The FAM trio of classes (functor, applicative, monad) are the most common ideas used from category theory in an explicit way, and they're frankly so prevalent at this point in the industry at large that they're in basically every language in extremely common libraries. Most programmers are pretty familiar w/ map and bind (which is also sometimes called flatMap, then, and_then, or chain). Applicative functors might be a little more exotic, but they're easy to pick up if you understand the other two. And I don't think you really need to understand what a morphism is or how to read arrow diagrams to really use any of these things. If you can use arrays in javascript, you can use the IO monad. Most of the challenge in haskell for me was figuring out stuff like how I should structure my code to enable mocking out effects for testing (there's multiple answers to this w/ different tradeoffs), or how to get good editor support without ghc-mod breaking. I haven't used haskell in industry in about the past two years, but I imagine these are still some of the biggest challenges w/ using it.
- dmix 7y ago+1 everything you said. Do you think it would be dramatically improved if Haskell had a bigger community of people contributing user-friendly libraries and tutorials? That was something that made Ruby the perfect newbie language for me. And something I feel is downplayed in Haskell given it's more advanced user base who is a little too obsessed with it's power and demonstrating their knowledge as such, rather than help make it accessible to others. I can't count the amount of times I came across a popular Haskell library with very little documentation rather than it's type/function API and general blurb about what it does. This is very different that most popular JS/Ruby/Python/etc libraries which include quick-start/getting started/usage examples/etc etc.
- pas 7y agoErgonomics is probably the number one thing that matters on the long run for computer languages. Make the frequent things easy and safe. And this means syntax should be easy to read and write, documentation should be plentiful and easy to read, easy to start using, even if you are not expert in the area that that particular library covers, etc. Rust also suffers a bit from this, as more and more libraries are just the generated docs. Here are these 30 structs and 100 impls, godspeed. Yeah, but what is this library, when I would use it? What's the most 100 common use cases? And a 100 might seem like a lot, but people will chose that instantly works for them. And there are a lot of strange stacks out there. Sometimes people just want the low-level bits of your library. No docs/API for that? Damn. Sometimes people just want to use it as a one-liner, no config files, no import-server-deploy, no binary? Damn.