В некоторых языках программирования применяется концепция типа, гарантирующего уникальность. Такие типы обеспечивают гарантию, что объект используется однопоточным способом, при этом ссылок на него — не более одной. Если значение имеет тип, гарантирующий уникальность, то применимая к нему функция в объектном коде может быть оптимизирована для обновления значения на месте. Такие обновления на месте повышают эффективность функциональных языков, сохраняя при этом ссылочную прозрачность. Типы с гарантией уникальности могут также использоваться для интеграции функционального и императивного программирования.
Введение
правитьТипы с гарантией уникальности лучше всего объяснить с помощью примера. Рассмотрим функцию readLine
, которая читает следующую строку текста из данного файла:
function readLine(File f) returns String return line where String line = doImperativeReadLineSystemCall(f) end end
Теперь doImperativeReadLineSystemCall
считывает следующую строку из файла с использованием системного вызова на уровне ОС, который имеет побочный эффект из-за изменения текущей позиции в файле. Но это нарушает ссылочную прозрачность, потому что вызов этой функции несколько раз с одним и тем же аргументом будет всякий раз возвращать разные результаты при перемещении текущей позиции в файле. Это, в свою очередь, делает readLine
нарушающей ссылочную прозрачность, потому что она вызывает doImperativeReadLineSystemCall
.
Однако, используя типы, которые гарантируют уникальность, мы можем построить новую версию readLine
, которая является ссылочно прозрачной, даже если она построена поверх функции, которая не является ссылочно прозрачной:
function readLine2(unique File f) returns (unique File, String) return (differentF, line) where String line = doImperativeReadLineSystemCall(f) File differentF = newFileFromExistingFile(f) end end
Объявление unique
указывает, что объект f
имеет тип, гарантирующий уникальность; то есть f
никогда не может ссылаться на вызывающую функцию readLine2
после возвращения из readLine2
, и это ограничение применяется системой типов. И поскольку readLine2
не возвращает f
сам, а представляет собой новый, другой файловый объект differentF
, это означает, что readLine2
не может быть снова вызвана с аргументом f
. Тем самым сохраняется ссылочная прозрачность и допускается возникновение побочных эффектов.
В чистом языке программирования нет изменяемых переменных, а есть только именуемые неизменные значения. Если x
имеет гарантированную уникальность, то при вычислении
x' = f(x)
компилятор гарантирует, что на х
больше нигде нет ссылок. Значит в этом месте х
использован последний раз, занимаемую им память можно после вычисления f(x)
освободить. Если x'
и x
имеют один тип и размер, то вместо объявления х
мусором и выделения памяти для x'
можно разместить x'
там, где ранее был x
. Таким образом получается изменение по месту без нарушения чистоты[1].
Языки программирования
правитьТипы, гарантирующие уникальность, реализованы в языках функционального программирования Clean, Mercury и Idris. Иногда они используются для выполнения операций ввода-вывода в функциональных языках вместо монад.
Было разработано расширение компилятора для языка программирования Scala, который использует аннотации для обработки уникальности в контексте передачи сообщений между объектами[2].
Связь с линейной типизацией
правитьТип, гарантирующий уникальность, очень похож на линейный тип[англ.], до такой степени, что используемые термины часто взаимозаменяемы. Но на самом деле существует различие: по факту линейная типизация позволяет привести линейное значение к линейной форме, сохраняя при этом несколько ссылок на него. Уникальность гарантирует, что значение не имеет других ссылок на себя[3].
Примечания
править- ↑ «Haskell's evil twin (Злой близнец Хаскелла)» . Дата обращения: 1 апреля 2018. Архивировано 27 декабря 2018 года.
- ↑ Haller, P.; Odersky, M. (2010), "Capabilities for uniqueness and borrowing", ECOOP 2010—Object-Oriented Programming (PDF), pp. 354—378, Архивировано из оригинала (PDF) 20 августа 2018, Дата обращения: 1 апреля 2018
- ↑ Wadler, Philip (17-19 June 1991). Is there a use for linear logic?. ACM SIGPLAN symposium on partial evaluation and semantics-based program manipulation (PEPM '91). pp. 255—273. CiteSeerX 10.1.1.26.4202. doi:10.1145/115865.115894. ISBN 0-89791-433-3. Архивировано 22 марта 2018. Дата обращения: 1 апреля 2018.
{{cite conference}}
: Википедия:Обслуживание CS1 (формат даты) (ссылка)