#PureScript is almost the perfect #Haskell replacement. Not only for the things it brings to the table, but also for the things it does *not*.
I mean actual *features* missing from PureScript and not gotchas like *no historical baggage*!
Some examples below. All of them are good for simplicity and newbie friendliness!
1. No laziness.
Laziness makes it harder to reason about performance. There are easy workarounds for most common usecases for laziness, and employing clever laziness tricks is usually not worth the cost of complicating the codebase.
Also, you can approximate thunks with functions when needed. Typeclass trickery even allows call-by-name evaluation (see https://github.com/natefaubion/purescript-call-by-name).
2. Manual recursion is discouraged.
PureScript's TCO only works in special cases. Normally you wouldn't even need to deal with this because existing implementations of functions like map, foldr etc. are already tail recursion safe. For the rare cases when you need to manually recurse, you can use `tailRec` and `tailRecM` to ensure stack safety.
3. No special syntax or support for linked lists. Strings are not simply lists of chars.
This could potentially be put in the "no historical baggage" category. But I feel that a lot of people, especially newbies, view the special treatment of lists and strings as a plus for Haskell.
However, the focus on lists causes massive confusion for newbies when they are encouraged to use types like Vector and Text in production instead. The special inbuilt syntax also is an active impediment for learning (for example, how do you refer to the higher kinded List type when deriving an instance? It's a mental leap to get to `[]` in `instance Foo [] where`).
4. No special syntax for Tuples.
Much of what was said for lists also applies to tuples. The special syntax is confusing to newbies and causes code complications. For example, each length of tuple is a separate type, and typeclasses in Haskell need to derive instances for each separately. They usually derive instances for tuples only up to length 7.
In addition, it's rarely needed. I am yet to find a usecase for tuples where PureScript's wonderful support for records doesn't suffice. I thought one such usecase was case matching on multiple values (`case (v1, v2) of ...`), but PureScript supports multi case match for this exact usecase and avoids unnecessary boxing (In PureScript you would write `case v1, v2 of ...`).
@haskman
Strict-by-default is just asking users do to what a compiler should do.
For the same reason we don’t want to use manual memory management (even with the borrow checker assistance) all the time.
Let me focus on what’s important and let the compiler find a best way to do it.
@monad_cat @haskman sure! I recently wrote a lib for working with streams in Lean. Frankly, compared to writing one in Haskell, it was error prone pain in the ass. Exactly what @dpwiz is talking about. But yeah, it's a tradeoff, but it's not like one is more natural or easier to code with than the other. I do a lot of streaming so for me first class lazieness is something that I miss.
@monad_cat @jonn @dpwiz You only have to handle the complexity once and then push it into a module/library for everyone to use.
For example, you can use the free monad to stream in PureScript just the same way you would use the free monad in Haskell. The magic of implementing a stack safe eagerly evaluated free monad is buried inside the purescript-free library.
@jonn @haskman you can still get lazy behavior in strict languages though with a little but of tactical thunking, different tradeoffs.