Про прозрачность и чистоту функций

Простой вопрос: допустим, у нас есть вызов функции

 

concatenate( s1[i], s2[j] )

 

(на C#), где s1 и s2 — строки.

 

Какое выделение символа выполнится первым: s1[i] или s2[j] ?

 

В документации это наверняка определено; думаю, что скорее всего самое левое выражение s1[i].

 

Но самое интересное, что данный порядок не имеет никакого значения, программисты это обычно понимают интуитивно, и каждый день десятки раз пишут подобный код автоматически. Если бы в доках была ошибка, и на самом деле первым вычислялось бы самое правое выражение, ничего бы не изменилось, никто бы этот баг и не заметил.

 

Почему? В чём тут соль, относится ли этот принцип абсолютно ко всем функциям и операциям? Нет, он применим только к ограниченному множеству функций, которые обладают свойством так называемой прозрачности ссылок (Referential Transparency). Это один из базовых принципов функционального программирования, и заключается он в том, что всегда для конкретного значения аргументов мы получим одно и то же значение. В нашем случае, мы можем быть уверены, что если s1 — это «12345», и i — это 3, то при обращении s1[i] мы всегда получим символ ‘4’. Это настолько естественно, что в подобных случаях мы даже не задумываемся над порядком вычисления аргументов функции, а просто пишем код.

Прозрачность ссылок хороша ещё тем, что при явно заданных параметрах мы всегда по сути можем подставить вместо такой функции её значение (в нашем случае, символ ‘4’).

 

Но в реальных проектах функций с прозрачностью ссылок не так и много. Например, если функция обращается к базе, что-то вводит с клавиатуры, обращается, о ужас, к глобальным переменным, и т. д.

 

Давайте теперь помечтаем. Хорошо бы иметь такую языковую фичу, типа декоратора, которая бы объявляла функцию с прозрачностью ссылок. Компилятор сказал бы нам «огромное спасибо» и сразу выдал бы кучу очень полезных предупреждений по поводу рефанкторинга кода.

 

А теперь представим новый язык, в котором ссылочная прозрачность неотъемлемо присуща каждой функции. И тогда сразу же, по сути, явно задаваемый порядок вызова становится вообще неважен!

 

Хорошая новость, что ссылочная прозрачность и так называемые чистые функции — это одна из самых элементарных фич функционального программирования. И в нашем повседневном кодинге рассыпано множество таких потенциальных жемчужин, о которых мы подчас и не подозреваем.

Поделиться статьей ...Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0Share on VKPrint this page

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *