Functional programming, at its heart, is about using self-imposed constraints to avoid certain classes of programming mistakes.
If your application domain doesn't have big consequences for these classes of programming mistakes, then it can seem like functional purity can be a luxury or frivolous. However, if your application domain suffers greatly from those classes of programming mistakes, such as distributed systems, then it may be worth it to consider what functional programming might buy you.
So yes, just because you use a functional programming language won't help you sell your widgets or make a great product. And you can spend lots of time fucking around with it for its own sake and still not sell widgets or make a great product. However, if you understand what its constraints buys you, then you can make your job of building these things in certain domains much easier.
In this way, I rather like the tradeoff that the OP post shows: It's at least _possible_ to write Go code that's almost as defensive, safe and exhaustive as a safer language could provide, it's just a lot of manual work and discipline. For the small subset of code that needs these guarantees, it's possibly overall more consistent and efficient to take this route than splitting code into different languages with different strengths.
It comes down to trust. You're either fucking with your code in a powerful programming language that lets you do everything, or your fucking with the language restrictions to get your code to compile in the first place.
You can either go eat at McD's which sells pre-cooked burgers from minimum wage employees which kills the flavor and the taste of the meat being served but is extremely safe, or you can go to an upscale burger joint where artisans grind their meat in house and cook it to a perfect medium rare.
These days, I prefer the latter.
> ...or your fucking with the language restrictions to get your code to compile in the first place
I think that's a wrong and outdated view on strong type systems.
A good type system is also an ergonomic one. What people start to experience is that the compiler is actually a friend that helps you write code and keep yourself true to your own promises. When new people start Elm, PureScript or Haskell (or another lang with ADTs and Type Inference), they might be a bit overwhelmed with the paradigm shift, if coming elsewhere, but if you are new to programming, there's nothing inherently more difficult in Haskell than in other languages—the cost of wrong code is just apparent earlier.
It doesn't come down to trust, it comes down to the realization that your mind can keep track of less information than a computer, and that you, as a programmer, are forgetful and make mistakes. The compiler is there to help you when you stumble over your own feet.
NOTE: I'm only including strongly, statically typed languages with type inference in the above. "FP langs" by itself is far too broad to be a useful categorization.
But I think the advantages that OP is lauding are also there, and "space shuttle code" might just be where it shines. Reading that comment in this post made me immediately think of Haskell. The Clojure components at my company fits the "space shuttle" description of importance, and its dependability is striking compared to the rest of our code. Part of it may be that being written in a different language allows its concerns to be separate from the rest of the application too, but I do think the FP paradigm is simply good in this domain.
I don't know. It seems like it would be easy enough to build an AST to make sure there were no unknown conditions that didn't lead to a return statement.
I wasn't really talking about type systems specifically, I was thinking along the lines of the Rust borrow checker here, and lower level programming like assembly and C.
> A good type system is also an ergonomic one. What people start to experience is that the compiler is actually a friend that helps you write code and keep yourself true to your own promises.
I see a lot of people make the mistake that type safe code is bug free code. "It compiles, therefore ship it."
> It doesn't come down to trust, it comes down to the realization that your mind can keep track of less information than a computer, and that you, as a programmer, are forgetful and make mistakes. The compiler is there to help you when you stumble over your own feet.
You trust the compiler to find bugs. Awesome. Luck be to you. I trust unit tests more than the compiler. Mostly because I wrote them. The compiler, I didn't.
By your logic, it's not enough to have faith in unit tests because you wrote them; you must also write the test framework and runner.
Now I want the powerful language and I can just slam it with generated tests to get the same level of confidence as the guardrail languages (in practice definitely, although I understand this is not true in theory, so unspit your coffee Haskell people).
Oh right and this is currently Clojure, so a functional language that definitely does help me make a great product. Less time implementing correctly means more time for product refinement.
Hopefully sometime soon I can share an example of this.
Badly chosen restrictions are not good, we can all agree. But what do good restrictions look like? Back in the day, programmers prided themselves on being able to do their own memory management, and bristled at the idea of a compiler or the runtime doing it for them. Now, that's the exception, as most of the time, we don't think about memory management in most languages we program in.
As time marches on, we'll find more of these restrictions that we all eventually agree are good practices, and the next generation of programmers will take it as a given in programming.
As a look beyond functional programming restrictions, I encourage you to check out Peter Alvaro's talk on Distributed Systems. Here, he talks about how queries over distributed systems is really hard to reason about, because time is now relative--there's no central clock to measure time. However, if we restrict ourselves to a language whose queries cannot express negation, a lot of the hard stuff about distributed systems go away.
Swift, rust, c#, reason
There is indeed a lesson here, but which one do you think it is? It's certainly not that McDonald's makes better (or "simpler") hamburgers: once you taste good hamburgers you can never go back to McDonald's (and yes, I make better hamburgers too, even though mine won't win any prizes!). To me, the lesson is that there's more to success than product quality. The established brand matters, the scale at which you can sell a (possibly inferior) product matters, how low you can get away with paying your employees matters, how well you can survive PR disasters matters, etc.
If you had to make burgers, would you rather make cheap and mediocre ones, or would you rather enjoy making premium burgers? :)
At the risk of derailing the thread, that would be the lesson I wish people would take away from that example.
Criticizing fast food like that is dumb signalling IMO; McDonald's!hamburger != homemade!hamburger. It's an entirely different product sharing the same name and some of the ingredients. It tastes different, and has a different form factor. People like this, even if many don't want to admit it to others (or themselves). When I go for a McD's hamburger instead of a foodtruck one, or when I say I prefer chain restaurant pizza over a home made one, it's because I want a different product. Treating the two as the same category is like treating tea and coffee as the same thing.
It's all about the brand, unfortunately.
People only like the cheapness and the convenience (and perhaps the no-surprise factor).
Everything else being the same (price and time to prepare), nobody would eat McDonalds vs a quality burger (except the kind of people who eat Hot Pockets for the taste, but that's a much smaller demographic than McDonalds buyers).
No-surprise factor isn't that big of an issue if you're buying; restaurants tend to have consistent food quality & taste too.
Where McD’s really shines, though, is their breakfast offerings. And with that said, I think I will head there now for a quick breakfast (I live ~5 blocks from McDs).
It seems many or even most people can't tell the difference and the ambience and service is as important as the food.
It surprises me in the case of frozen patties like McDonald's though. A frozen patty looks nothing at all like an actual burger made from ground meat. It tastes differently as well, of course, but what matters is that it looks completely different!
Kubernetes' reputation is just the opposite: that far from being a simple and useful thing, it's an overengineered, overcomplicated solution to a self-inflicted problem (deploying a distributed monolith).
> But the closest I ever came to using a functionally developed product was RabbitMQ (written in Erlang). That one was _such_ a pain to use and operate — must have been the developers still dreaming in the purity of its code instead of writing some installation docs. I moved on to Kafka later and didn't regret it a minute.
Erm, Kakfa was developed in Scala, whose advocates far more of a reputation for purist pontification than Erlang developers do. Maybe all that beauty and purity is actually good for something?
I would call the erlang system the "one white lie" category of purity on the FP purity scale. It is, by the way, a huge tradeoff that makes operating in EVM languages far easier than, say Haskell.
This is not what Kubernetes is for.
Take a step back and understand what you're criticising. You just look uninformed.
Thats why companies pay the buck to get 24/7 support. Because its that good!
This disparity in numbers is in turn is primarily because golang/Python/C is inherently much more approachable than Haskell because the average programmer has cut his/her teeth writing imperative code for a significant portion of their early programming career. The jump to functional way of thinking requires a certain leap of the mind, that most people don't want to take the trouble doing because they seem to be happy "getting things done" in golang or Python.
However, that is not to say that we shouldn't be striving for correctness in code that Haskell fosters, or the inherent simplicity that it forces on you because you are forced to separate your IO and effect-full code from the pure bits. These are things worth striving for. These are broad principles worth emulating even when you are coding in an imperative language.
To turn your McDonalds analogy around: sure, a McD will let you just get your food requirements out of the way quickly and cheaply (i.e. just "get stuff done"). But in the long run, it's bad for you.
Haskell is a healthy salad to an [insert favourite imperative language] burger.
I really, really want to use Haskell because it’s type system seems neat in general, but the type system doesn’t justify all of the tedium. Go definitely loses on type system, but it wins in many of these other areas and so the trade offs are just better.
Others were not so lucky: https://issues.apache.org/jira/browse/ZOOKEEPER-801
Err, RabbitMQ is one of the easiest to setup and stabler queues/messaging systems. And I'm no user/fan of Erlang...
That said, there do exist useful products written in Haskell. For example, Facebook writes a lot of spam fighting code in Haskell. https://code.fb.com/security/fighting-spam-with-haskell/
Go and Haskell are really at different ends of a spectrum. Haskell is a very high level language, which makes building and reasoning about very complex software much easier (at the expense of a learning curve and fine control of space usage).
Go is a low-level language with no learning curve and a very limited facility to abstract (by design it seems).
Personally I would have written something like Kubenetes in Haskell or OCaml, with perhaps the odd performance critical section in C or Rust.
That said, lots of things are functional: chunks of Facebook, Twitter, and Microsoft (and I assume Google) are written in OCaml, Haskell, Reason, and F#. Jet is built in F#. Jane Street famously uses OCaml, and Scala is becoming the standard language for hedge funds. Spark apps are usually written in Scala. Etc.
There's at least git-annex and pandoc
Furthermore, why are you using the user interface as a yard-stick to judge language paradigms with?
Because I'm not in the business of making hamburgers nor am I interested in doing so.
Struggling to see this business coach's point. Is he saying that McDonalds makes better burgers than me because I'm not selling a million burgers a day? Because that's a load of crap.
E.g. Low cost, made quickly, scalable (easy to train workers from any culture, uses ingredients that can be sourced at scale across the globe, etc), consistency (burger is always up to standard regardless of time or place).
Serving customers is not a contest of who can make the best burger.
- the Flow and Hack compilers
- Facebook's Messenger app
- Jane Street's entire trading infrastructure (and everything else they do)
- XenServer
- some parts of Docker, including the TCP/IP networking stack on OS X and Windows
Good examples of this translating to huge gains for the overall community are React + Redux.
I'm quick to admit that functional language ecosystems are not as mature, which might lead to lesser organizational productivity but no need to rat on functional programming in general.
The better burgers made by large commercial chains are more expensive though.
Much of theoretical physics is beautiful. Only when one takes it off the blackboard and into the real world does it turn ugly.
Haskell is a highly opinionated reasearch language. This makes it a great languages to talk about. People could make many of the same points with, say Scala or Ocaml, but because those languages arent as opinionated, it is harder to use them as a basis for discussion than a language which is heavily opinionated about the subject in question.
This:
#include<stdio.h>
main()
{
int sum; int x; sum=0;
for(x=1;x<=50;++x)
{
sum = sum + x;
}
printf(" 1+2+...+50=%d\n",sum);
}
Is more cognitive load and error prone than this: (println (reduce + (range 1 50)))
This is mostly what experienced FP advocates tell you. Btw. you can transpile the latter to the former.https://github.com/apache/kafka/tree/trunk/clients/src/main/...
Functional programming advocats, especially for the "pure" ones like Haskell, always strike me as odd. It seems that all the beauty of those languages make people obsess over that beauty and purity while keeping them from being productive.
Meanwhile, people with simpler languages like Go just get stuff done that is useful and makes people happy. Now if I _ever_ came across a useful Haskell product, I'd be happy to test drive it, shouldn't be a problem by now with all the container technology. But the closest I ever came to using a functionally developed product was RabbitMQ (written in Erlang). That one was _such_ a pain to use and operate — must have been the developers still dreaming in the purity of its code instead of writing some installation docs. I moved on to Kafka later and didn't regret it a minute.
Rant off.