stevensonmt

stevensonmt

OO or FP easier for beginners

MOD NOTE: These were extracted from https://forum.elixirforum.com/t/elixir-should-focus-on-newbie-adoption

I’m going to push back on some of the posts above suggesting Elixir is not a good language for learning “programming” in general. I didn’t really solidify many basic concepts of recursion, data structures, and state management until I started working with Elixir and the associated docs and tutorials.
Recursion is an obvious functional programming basic concept, so it makes sense that more OO or imperative languages might not highlight this concept as well. For me, recursion really clicked with Elixir in a way that helped me go back to other languages and suddenly be able to apply that technique effectively.
Data structure design becomes so obviously critical with pattern matching. Other languages might be able to highlight performance characteristics of this or that structure over another. In terms of conceptualizing the problem space and the logic flow, however, I found the pattern matching paradigm of Elixir really drove home the importance of how you model the data in your application in ways that OO and imperative languages had not. Perhaps a personal failing or just an obvious lack of formal education on my part, but I think it really is an intrinsic benefit of the language design.
State management becomes such an obvious thing with immutable data structures, but in “pure” languages you end up wondering how anything gets done. Elixir really makes this obvious with the use of GenServers and the like to illustrate how to manage and update global state in a way that (mostly) prevents data races and the like. Again, a concept that more formal education may make clear to students, but something that the fundamental design of BEAM languages makes more obvious to the neophyte, imo.

Most Liked

sodapopcan

sodapopcan

I strongly believe that functional programming is more “natural”. As someone with zero compsci background and taught themselves to program by flailing around with PHP 3 and 4 with no framework for guidance, I found myself creating different nested data structures to describe my state and, without knowing their names, wanting recursion and even some simple types of meta programming (I quickly discovered PHP allowed recursion and some very limited “metaprogramming” with “variable variables”). I already mentioned but after developing and thinking in these concepts, it took me an embarrassingly long time to understand OO (I don’t even wanna say, lol). So I believe that if functional concepts are the first thing you learn, there is absolutely nothing strange or hard about them—they are only strange and hard if you are used to a different way of doing things.

I’m assuming that functional didn’t prevail because for the longest time because it wasn’t that efficient as it would require literal copying of entire data structures in order to change them which was untenable for larger systems. I don’t know my language history that well, though.

12
Post #2
adw632

adw632

Many of the efficiency issues of immutability were manageable as functional programming dates from the 1950’s.

I think OO was seen as something different offering some kind of promise of better software faster because it offered new concepts of “encapsulation”, “inheritence”, and “polymorphism” which were seen as a potential saviour to the industry.

This left “functional” most likely being seen as academic, mathematical, and potentially also conflated with the problems of that “evil” procedural “spaghetti code”, as superficially that a makes use of “functions” too right?

In the end, the “OO languages” created the “ravioli code” we have today and did not implement the actual definition of OO as described (or hoped) by Alan Kay.

The “OO languages” we have are non determinisitc (there is no guarantee to get the same output with the same inputs), and much harder to test.

One is left with a complex global graph of mutable object state tucked behind “methods”, with that state scattered to the wind in a single address space, with the execution model almost an afterthought.

With concurrency grafted on, you have a mess of threads, critical sections, mutex locks, semaphores and condition variables with many opportunities for deadlocks, no ability to actually clean up for every eventuality, as well as dealing with thundering herds of threads queuing up in the oddest of places (every mutex lock or critical section is actually an unintended queue).

How do you program defensively or even reason about it when the whole graph is a buzz with parallel changes and any thread could at any moment do a rug pull from under your feet? You use locks, and now any read on that graph of objects creates a stop work meeting and often results in a cascade of object interactions, more locks and even more deadlock potential. When considering exceptions none of the threads can actually cleanup properly in all circumstances, leaving a debris field and odd state in that global graph. It is all about coding the sad defensive path in this OO world, writing more code and doing less, but gee with static types you might catch some typos in the many times more code you must write but can’t adequately test.

There is also a runtime cost, shared data and locks actually lock the bus across CPU cores, and hurt cache effectiveness. We all know about “stop the world” GC and how that impacts the 99th percentile.

The BEAM avoids this hell.

As a recent prominent example of what “OO languages” beget, the Java crowd inflicted the log4j security vulnerability on the world which has cost companies in aggregate billions of dollars. What was the root cause you ask? A thread race condition due to fundamentally bad language design, a problem which goes like this:

The barman asks what they want.
Two threads walk into a bar.

The “OO languages” really are what Joe said, touch the banana and this sets off a cascade of side effects where the entire jungle moves.

The attack surface in the log4j vulnerability is vast and easy to exploit. Attacks like this essentially attack the fundamental issues at the core of most language designs that never considered the interplay of the language and processing model for concurrency together. I expect to see many more of these programming model attacks based on exploiting race conditions.

So how do you not end up with race conditions and deadlocks?

You avoid concurrency altogether in most languages and use heavy weight OS processes (often disguised as containers) to keep that state isolated within an OS process boundary and turn it into an operations problem.

Ultimately the truth of Erlang process model of concurrency and isolation prevails, albiet an impoverished analogue of it with many times the operational cost, recovery impact and recovery time when you do have a failure.

In my view the “OO languages” have proven to be a programming and operations tarpit. They looked like a nice shimmering sea of opportunity for a desperate software community, but like all tarpits once you’re deep in it, it’s hard to see a way out. Once you’re in the pit and “failing about”, the solution looks like “better tools”, and this attracts “investment” by tool vendors as there is good money prolonging a problem, which in turn attracts even more victims.

The “tools problem” compensates and hides bad language design which has increasingly been pushed into an operations domain with increased complexity though things like Kubernetes clusters for scalability and resilience of “OO language” programs. The burden of resilience and recovery disappears from the programmer and reappears in operations with orders of magnitude more cost. Those that don’t get Elixir, Erlang or the BEAM probably don’t understand the real problem. They don’t even perceive the problem to exist because of “best practices”, but the vendors and hosting provider do understand, and are waiting there smiling and ready to “help” ensure you consume as much as possible using “all of the best practice complexity you can afford” to retrospectively “solve it”.

Soon one needs to resource an ops team capable of maintaining the “cloud on cloud” cluster “service mesh”, etc, more technologies which no-one can all be experts in, but hey it’s all hipster and well “all the [OO] guys are doing it, Google loves Kubernetes, and RedHat loves OpenShift too”.

One of the red flags of a language/ecosystem that never solved the hard fundamental problems is that it ends up requiring a large set of disparate technology tools (footprint), and lots of people (layers of managers) to compensate for the operational problems it creates. These are usually “mainstream” technologies that generate a lot of revenue, and like lemmings corporates walk to their death willingly, because everyone else is doing it too.

This is where the significant competitive advantage of BEAM languages comes from to those that are savvy enough to understand and do actual risk management.
Less code, better testability, higher quality, low operational complexity and smaller technology footprint = less vendors and fewer SME’s needed to build understand and manage it.

Many decades on, some people are beginning to question their assumptions. This is why there are some significant examples that demonstrate success was no accident with services like, “WhatsApp”, “Discord”, “Pinterest”, and the UK health spine all using BEAM languages for competitive advantage.

I can posit that Jose probably reached a point working with Rails, that something had to change, there just had to be a better way… and thankfully he identified and built a solution and has been a huge mover in bringing the functional language paradigm and the true intent of OO into the mainstream, all by building on the shoulders of giants like Joe Armstrong who reasoned about and solved the fundamental problems that needed solving.

Alan Kay has said “Erlang might be the only object oriented language”. Coming from the person who defined “object oriented” I think that says it all, we have the best of both.

sodapopcan

sodapopcan

While this is all 100% true, when people say “OO” they almost always mean “classes and methods” which is certainly what I mean in this context!

Thanks for moving over the discussion, @benwilson512!

Where Next?

Popular in Discussions Top

vans163
So useless benchmarks aside, Its possible to write a webserver that can serve 300k requests per second (perhaps more with optimizations)....
New
PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
sashaafm
I’m trying to evaluate the best combo/stack for a BEAM Web app. Right now I’m exploring Yaws a bit, after having dealt with Phoenix for a...
New
arcanemachine
https://nitter.net/josevalim/status/1744395345872683471 https://twitter.com/josevalim/status/1744395345872683471
New
crabonature
I’m still quite new to Elixir. As I understand we got in Elixir “multi guards” as convention to simplify one large guard with or’s?: de...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31142 143
New
New
jer
I’ve been using umbrellas for a while, and generally started off (on greenfield projects at least) by isolating subapps based on clearly ...
New
hazardfn
I suppose this question is effectively hackney vs. ibrowse but we are at a point in our project where we have to make a choice between th...
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement