No, multithreading is easy, just not with the typical, imperative style of programming.
Functional programming can be a great help. However, to gain the safety benefits, you need to use a hardcore language where anything imperative is banned, rather than a more fun functional language like Scheme that lets you lapse into imperative style when you really want to.
And there are still optimization issues. Consider the following pseudocode for the main loop of a DF-style game. The pseudocode looks like C++, but it is authentically functional since each variable is only assigned once.
generate_next_frame(frame old_frame)
{
tempdata temperature_data = calc_temperature(old_frame);
pathdata pathing_data = calc_pathing(old_frame);
frame f1 = freeze_and_burn_stuff(old_frame,temperature_data);
frame f2 = move_monsters(f1,pathing_data);
generate_next_frame(f2);
}
That code would work well on a single core system. Now consider the following:
generate_next_frame(frame old_frame, tempdata old_temp, pathdata old_path)
{
tempdata temperature_data = calc_temperature(old_frame);
pathdata pathing_data = calc_pathing(old_frame);
frame f1 = freeze_and_burn_stuff(old_frame,old_temp);
frame f2 = move_monsters(f2,old_path);
generate_next_frame(f2,temperature_data,pathing_data);
}
On a single core system, the second code represents a significant pessimization. It wastes memory, since old temperature and pathing data is not discarded as soon as in the first code. It's also less "correct" than the first, since pathing and temperature information will be "stale" by one frame when it is used.
But it will be much faster on a multicore, because by using slightly-stale temperature and pathing, it can run the movement and burnfreeze passes simultaneously with the generation of the current temperature and pathing information which will be used next frame. Basically, it creates a pipeline system.