I've had my side-eye on this community for a while because you guys seem to have a lot of the same problems with modern software development that I, and people I hang out with have: massive code bases for software that terrible speed and terrible correctness. The difference is I'm not coming from embedded/systems/game development, but instead functional programming. I think that there's this notion that functional programmers are the epitome of ivory tower abstraction BS, don't care about performance, and are can't sort in place. While I'm sure that's true for some of us, that is not all of us.
Anyway the main point:
there is a fantastic talk that I'm sure many of you have seen called There Are No Zero-cost Abstractions
. Here Carruth demonstrates the biggest drawback that most abstractions: they leak. Most people talk about the problem of leaky abstractions from the perspective of the fact that they obscure implementation details and therefore cause mistakes, and while that is certainly one problem with abstraction leaks, the other one is that because they provide the compiler with less information at compile time the compiler is not able to perform the same aggressive optimizations that it can perform with its handwritten counterpart. While this is certainly an issue for some kinds of abstractions, many of the abstractions that functional programmers are interested in don't remove compile-time information but add it allowing for aggressive optimizations that aren't possible in analogous C code. Still dubious of my so-called "negative cost abstractions," it turns out C already has some of these backed in. First of all: Types. Types aren't just a way of ensuring correctness, but also allow for compiler optimizations. A language which one can find documented instances of it outperforming C due to having more compile-time information provided is Zig. In Jonathan Blow's language being able to write code and have it switch between working with AOS to SOA representations just by changing some type, signatures is another form of these kinds of "negative cost abstractions." One big place where functional programming research in my opinion needs to be folded into mainstream high-performance languages is type-level enforced purity. Purity isn't just nice from a user perspective but also allows for aggressive optimizations that aren't possible otherwise.Futhark
is a great example of the work being done in the functional programming world to leverage these types of optimizations. Another opportunity for optimization from functional programming that has started to make its way into languages like rust is "pipe style programming" where instead of calling a bunch of functions sequentially you construct some chain of operations that the compiler can optimize more aggressively. this article
talk about that briefly. Generally, I like to divide abstractions into 2 categories: ones that obscure information and ones that add information. The latter category not only is often not only free but faster. This is also before we get to parallelism, but that deserves a post of its own.
Unfortunately, a lot of this stuff is far away from being usable in mainstream performance-critical contexts, so as of today C and Zig are still probably better than their functional counterparts as of now, but I think there should be a greater alliance between our two disparate factions of computer science to improve software quality.
People here are some of the few that understand the flaws of RAII. Personally, I'm not satisfied with settling with unsafety, I want to have my cake and eat it too. What I see as the future is linear types. If we can have initialized memory and uninitialized memory as separate types where one gets consumed on initialization that is ideal. ATS has this, Idris has this, and Haskell is adding this, but Haskell and Idris are not particularly high-performance languages (although in my opinion, Idris has the potential to be if more effort is put into it), and no one uses ATS.