Most nontrivial algorithms are just a bunch of nested for loops with array indexing and ifs mixed in. There were no advances in computer science that made this kind of stuff less confusing as far as I am aware. We made a lot of advances to make simple boring business code do 30 nested method calls, but at the end of the day the basic algorithm is still a bunch of loops and ifs.
It's actually funny how all the focus in CS seems to be on modeling the business part in more natural ways, while the "solving problems" part is still done like it's 1970s.
You can make the algorithms clearer with good variable names and extracting some parts to well named methods (and you should, usually) but it's often not enough.
Example taken straight from Wikipedia:
function BellmanFord(list vertices, list edges, vertex source) is
// This implementation takes in a graph, represented as
// lists of vertices (represented as integers [0..n-1]) and edges,
// and fills two arrays (distance and predecessor) holding
// the shortest path from the source to each vertex
distance := list of size n
predecessor := list of size n
// Step 1: initialize graph
for each vertex v in vertices do
distance[v] := inf // Initialize the distance to all vertices to infinity
predecessor[v] := null // And having a null predecessor
distance[source] := 0 // The distance from the source to itself is, of course, zero
// Step 2: relax edges repeatedly
repeat |V|−1 times:
for each edge (u, v) with weight w in edges do
if distance[u] + w < distance[v] then
distance[v] := distance[u] + w
predecessor[v] := u
// Step 3: check for negative-weight cycles
for each edge (u, v) with weight w in edges do
if distance[u] + w < distance[v] then
error "Graph contains a negative-weight cycle"
return distance, predecessor
This is pseudocode with some stuff abstracted away, yet they still added "what" comments. You can remove some of them and split it into several methods but for Step 2 I still kinda feel it's not enough information to make it obvious what is happening. What does it mean to "relax an edge"? Why do we need to do it V-1 times? Does order matter?
I don't think fancy programming language features help here. You can change iteration into tail recursion or point-free functional code or whatever is fashionable but the underlying complexity remains.
And there are algorithms out there that are much trickier.
Source: https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm...