| > This is an explainabrag My goal here was to show that standard Haskell boils down to a small set of features, therefore it's a simple language. Surely, "simple" does not imply "good" (Brainfuck is also simple), so I then assert that the combination of features that Haskell consists is fertile soil for writing maintainable and performant code. > languages without these features can also have "clean, maintainable code" Some people may prefer ML modules to type classes, sure. As to the other features, I have a hard time imagining a clean codebase in a language without some form of polymorphism, first class functions, and algebraic data types. (And lazy evaluation is a great addition to the list). Perhaps there are other sweet spots in the language design space, but I have not seen them yet. > and nothing about this list implies "runs fast." GHC is good at optimising this kind of code. https://stackoverflow.com/a/35038374 > Is a memory leak meant to be the "worst sort of bug" or a "security vulnerability?" It's often hard to debug, and it means that the program can't be running for a long period of time. I suppose I should've used a better example, e.g. "use-after-free", to highlight the dangers of manual memory management. > Haskell is particularly prone to "space leaks" due to its laziness. Space leaks are benign compared to memory leaks in that the memory is eventually freed. That said, I'd be happy to have some sort of static analysis to prevent them. > Why bring up Cyclone and not, say, Swift? Or is Swift meant to be included in "garbage collected languages?" Swift relies on automatic reference counting, which is similar to garbage collection in that it isn't done by the programmer and has a runtime performance cost. Remarkably, it seems to be worse on both accounts: the cost of decrementing/incrementing these counters is very real, and handling reference cycles is not automatic (you need to carefully use weak references). Here's an interesting discussion of RC vs GC in context of .NET https://blogs.msdn.microsoft.com/brada/2005/02/11/resource-m... Rust, on the other hand, offers a static analysis with no runtime performance overhead to manage memory safely. > dynamically typed languages with static type checking You're talking about gradually typed languages. Sure, these are not unityped, but they also not purely dynamically typed (you said it yourself – they have static type checking). Perhaps that's just a difference between our uses of the term "dynamically typed" and we don't have a true disagreement here? By the way, Haskell can do that too, we have the `Dynamic` type right in the `base` package. > This read like a troll piece. I'm sorry. |
Only true if you use pervasive reference counting, with atomic updates. Swift essentially does this, but other languages don't.
One of the reasons why it makes sense to single out tracing GC (as opposed to RC) is that it's essentially a package deal; your whole program needs to be structured to use memory as essentially an in-RAM database, where every single object or reference can be traced after the fact at some arbitrary time in the future. (There are reasons to do this in some cases, even in 'low-level' languages which are not ordinarily garbage collected - see e.g. the use of "entity component systems" in such languages - but it's obviously not a generally-appropriate solution in any real sense!). RC is self-contained, and it need not even be locally inefficient.
> You're talking about gradually typed languages.
Interestingly, gradual typing does seem to end up with a "worst of both worlds"-type situation - the dynamic tag checks and conversions that have to be inserted at every boundary between statically- and dynamically-typed parts of the program introduce pervasive inefficiency, which is only resolved when static typing is used essentially throughout.