10 ms·
> Still, I wish I could see more info on this. At what point does the additional cognitive burden of advanced type system features become a worthwhile tradeoff
by danharaj 9y ago
> Still, I wish I could see more info on this. At what point does the additional cognitive burden of advanced type system features become a worthwhile tradeoff for program correctness?
As a professional Haskell programmer, I find the cognitive burden to be lower in Haskell than in, say, Java, where I have to do a lot more bookkeeping about design patterns and how they're glued together than in standardish Haskell where compositional forms fall into a compact set of powerful concepts amenable to reasoning.
I say standardish Haskell because the sweet spot in my experience is a few lightweight GHC extensions but mostly shunning some of the seriously experimental stuff in the language. For example, i agree with your doubt when it comes to dependent types and in particular singletons, a halfway house implementation that can be used in Haskell today.
Some of my coworkers had unsuccessfully attempted to write mobile games in Haskell. That was 10 or so years ago and many of the technical hurdles that impeded them then are no longer there.
The only major one I know of at the moment that prevents Haskell from being used in a AAA game engine is a guaranteed low latency garbage collector. I expect someone to implement such a thing for Haskell in the next 10 years.
The space is moving fast, our understanding of how to write big Haskell apps has advanced drastically since when I first started using the language! I expect big things to come in the next couple of years.
This is not to say that the space is getting rewritten all the time, it's just that more useful concepts are being discovered and matured. For example, Applicative only 11 years ago and scalable FRP like 4 years ago or so.
I should say what type concepts compose my compact tool set:
* higher order functions with syntax optimized for using them.
* algebraic data types (sparingly generalized algebraic data types)
* type classes + higher kinds (The synergy is far greater than the individual features)
* monad transformers (the promise of aspect oriented programming actually realized)
- delhanty 9y agoThank you - very useful summary. >I say standardish Haskell because the sweet spot in my experience is a few lightweight GHC extensions but mostly shunning some of the seriously experimental stuff in the language. Are you able to say which GHC extensions you use and why?
- danharaj 9y agoI grepped a typical project and saw these. I think they can be divided into a few different kinds of extensions. This extension fixes a defect in the spec as far as I'm concerned: * ScopedTypeVariables Syntactic extensions that make certain code forms lighter: * LambdaCase * MultiWayIf * OverloadedStrings * RecursiveDo * TypeApplications * PatternGuards * KindSignatures Code Generation: * DeriveFunctor * DeriveTraversable * DeriveFoldable * DeriveGeneric * StandaloneDeriving * GeneralizedNewtypeDeriving Extensions to the type system. These can be misused so they should be respected. * MultiParamTypeClasses (Can weaken type inference) * FunctionalDependencies (Helps type inference with MultiParamTypeClasses, these two together compete with TypeFamilies for functionality) * FlexibleInstances (Can be a bit sketch, actually) * FlexibleContexts * UndecidableInstances (Surprisingly mostly benign) * TypeFamilies (Type level programming should be kept to a minimum. Can kill type inference) * GADTs (Very powerful, sparingly appropriate) * RankNTypes (Higher rank types are very expressive but have much worse type inference) Unpleasant extensions that cope with the realities of serious engineering: * TemplateHaskell * CPP Very Spicy extensions that I avoid unless they're really really appropriate: * PolyKinds * TypeInType I am mostly neutral or unfamiliar with the others. The only extension I vehemently oppose is RecordWildCards because it is a binding form that doesn't mention the names it binds. It can get really confusing!
- delhanty 9y agoHey thank you! I really appreciate it that you took the time to write that out.
- danharaj 9y agoI want to see this programmer who doesn't jump at the opportunity to give their opinion on programming :p you're welcome
- jeremyjh 9y agoSo I've developed a medium-large Haskell project that used nearly - but not quite all - of those same extensions. I would never think to describe this as "a few lightweight GHC extensions". To me - and I think most others - it's just normal Haskell, but why even bring up "standardish" if this is what you do?
- fredsir 9y agoWhat type of problems/specific problems do you work on?
- danharaj 9y agoI'm part of a general software consultancy. I've worked primarily on web applications, some of the bigger ones are around the same complexity as something like Slack or some chunk of google docs. Some other projects I've been involved in are blockchain tech, and software as a service tools.
- jstimpfle 9y ago> I find the cognitive burden to be lower in Haskell than in, say, Java I don't think Java is a meaningful competitor. It's a language completely based on 90's hopes that OOP was a good idea. Turns out it is mostly good to program simple things as complex "ravioli code". Better compare against languages that games, kernels, and compilers are typically implemented in. > monad transformers (the promise of aspect oriented programming actually realized) How do monad transformers realize aspect oriented programming? In my experience they lead to pretty verbose code and lots of boilerplate. I think the way to achieve "aspect-orientedness" (I think this name is based on the same insight that lead to names like "separation of concerns", "cohesion", or "cross-cutting concerns") is simply to draw modules boundaries by shape of data, not in an OOP style where most objects do a million different things (etc. cat must eat, walk, sleep, meow...)
- hota_mazi 9y ago> It's a language completely based on 90's hopes that OOP was a good idea. I find the dismissive tone rather amusing. A large majority of the code running on our planet today is OOP. You could argue that there might be better ideas out there, but OOP is certainly an idea that has not only proven itself to be tremendously useful, but that has also been able to adjust and adapt through decades of changing requirements. It's pretty much the only software paradigm that's survived for that long.
- jstimpfle 9y agoEvery objects-first codebase I've seen was terrible. OOP survived mostly because people push hard for it, because they think there must be value in overly taxonomic code, but in the end they never seem to get value out of it, only more and more incompatible objects (when I hear "mock object" it's time to run). In OOP >50% of the LOC is just stupid bureaucrazy, setting up object graphs in the name of "isolation" (the irony), half-initializing fields, conforming to the right interfaces etc. This is completely meaningless, do-nothing code. Worse, it gives the illusion to remove some contextual dependencies this way, but the code never seems to work outside of the context it was created in. It's only much harder to read because the context is files away. OOP is the wrong-minded idea that a program should be a bundle of many "self-contained" objects. But that's wrong, we're writing ONE program here, not thousands. It tries to repair this wrong idea with inheritance (which is at least as bad an idea). And it makes it really hard to cope for "cross-cutting concerns", which are actually 90% of all we care for, not just a side concern. The complexity is in the edges (i.e. how is information moved/transformed), not in the objects! OOP mostly survived where performance / architectural scalability is not super important (e.g. Python or similar scripting languages, where it enables dynamic typing). And it survived where the big money is, but not necessarily technical competence (where it enables Object-verb type code completion). That relates to OOP as in languages like Java - not Alan Kay's idea of OOP, which he emphasizes was very different, but I still don't get what's the idea :p > A large majority of the code running on our planet today is OOP. Good example code base? > It's pretty much the only software paradigm that's survived for that long. Maybe check on your history? Many people are totally happy with procedural programming.
- hota_mazi 9y ago> monad transformers (the promise of aspect oriented programming actually realized) I hardly see any overlap between these two concepts. AOP is about cross cutting concerns and being able easily insert similar functionalities in unrelated areas of the code. Monad transformers are the hack you need to use to make monads compose.
- danharaj 9y agoMonad transformers are distinct from monad composition, it just seems like they're the same because a monad transformer takes the Identity monad to some other monad. The correct conceptualization of monad composition is a distributive law called as such because it generalizes distributive laws from algebra. Of course the two are related. Monad transformers allow one to slice up the functionality and concerns of a program in a dimension different from slicing of a program into components that are then composed together; e.g. a bunch of functions that call each other or a bunch of objects that pass messages between themselves. Each monad transformer in a transformer stack adds functionality and concerns that the other parts of the stack don't need to care about. Components can then be written polymorphically in the concerns they care about allowing them to be instantiated wherever the capabilities they need are present. Ultimately a program is instantiated to a particular transformer stack and then it is supplied effect handlers that reduce it to the base monad (often IO). The ability to modify functionality in a cross-cutting way is concentrated in the effect handler which is at the discretion of the call site, not the implementation site. This is not quite AOP but it's in the same space. It's hard to see in small apps but quickly emerges as the scale of a Haskell application grows.
- tathougies 9y agoHow are monad transformers a hack? They have a solid theory behind them. i'm not sure where you got the idea that they 'make monads compose'. Monads don't compose. It's nonsensical to talk about monad composition in general, because there is nothing about the structure of a monad that allows it to compose (quite the opposite, really). Some things which may form some monads do compose with certain other things that form monads, but this is like saying 'Abelian groups' are the 'hack' you need to make groups commutative -- it's a meaningless statement.