Одна из основных проблем при программировании традиционных языков, таких как C, Java, C #, ассемблер и т. Д., Заключается в том, что у вас есть неуклюжая последовательность шагов, которые вы должны предпринять для выполнения данной задачи, потому что вам нужно сначала подготовить все зависимости ИХ Зависимости ранее
Пример: чтобы сделать A, у вас должны быть B и C, а B зависит от D и E, что приводит к чему-то вроде
потому что вы должны подготовить ингредиенты, прежде чем использовать их.
Функциональные языки, особенно ленивые, переворачивают этот с ног на голову. Позволяя A сказать, что ему нужны B и C, и позволить языковой среде выполнения выяснить, когда получить B и C (что, в свою очередь, требует D и E), все из которых оцениваются при необходимости для оценки A, вы можете создать очень маленький и лаконичный строительные блоки, которые приводят к небольшим и кратким программам. Ленивые языки также позволяют использовать бесконечные списки, так как вычисляются только фактически используемые элементы, и при этом не требуется сохранять всю структуру данных в памяти перед тем, как использовать ее.
Действительно хороший трюк заключается в том, что этот автоматический механизм «о, мне нужны B и C» является масштабируемым, потому что нет никаких ограничений - как в последовательной программе - относительно того, где и когда эта оценка может произойти, так что это может произойти на в то же время и даже на разных процессорах или компьютерах.
Вот почему функциональные языки интересны - потому что механизм «что делать, когда» переходит в среду выполнения, а не программист, вынужденный делать это вручную. Это столь же важное отличие, как автоматическая сборка мусора для Java на C, и одна из основных причин, по которой проще писать надежное, масштабируемое многопоточное программное обеспечение на Java, чем на C. Еще проще писать надежные, масштабируемое многопоточное программное обеспечение на функциональных языках ...