Говорят люди в интернете, мол используй функциональное программирование, отсутствие состояния, и никаких data race'ов не будет, и соответственно многопоточность будет достигаться легко.
Но тут я подумал о хаскелле и о его ленивости - а ведь ленивость приносит состояние. Допустим мы одну и ту же функцию вызываем из двух разных потоков. Вроде как в хаскелле ленивость кэшируется, и благодадря этому если вызвать одну и ту же функцию 2 раза, результат 2 раза считаться не будет. Но как с этим в многопоточных приложениях? Вдруг функция уже считается в одном потоке, а я ее вызову из другого потока? Чтобы это работало нормально, уже нужны какие-то механизмы синхронизации. А механизмы синхронизации это уже состояние.
Вот например в плюсах я ведь такого без изменяемого состояния сделать не смогу - там механизм синхронизации будет включать в себя что-то с состоянием, а в хаскелле значит тоже состояние есть, просто оно спрятано языком, и к нему нельзя получить доступ вручную.