Существует ли функциональный язык, который позволяет использовать семантику стека - автоматическое детерминированное уничтожение в конце области?
32
Существует ли функциональный язык, который позволяет использовать семантику стека - автоматическое детерминированное уничтожение в конце области?
Ответы:
Не то, чтобы я знал, хотя я не эксперт по функциональному программированию.
В принципе это кажется довольно сложным, потому что значения, возвращаемые из функций, могут содержать ссылки на другие значения, которые были созданы (в стеке) внутри той же функции, или могли бы с такой же легкостью быть переданы в качестве параметра или на которые ссылается что-то, переданное в в качестве параметра. В C эта проблема решается путем допущения, что висячие указатели (или, точнее, неопределенное поведение) могут возникать, если программист не понимает все правильно. Это не то решение, которое одобряют разработчики функционального языка.
Есть потенциальные решения, хотя. Одна идея состоит в том, чтобы сделать время жизни значения частью типа значения вместе со ссылками на него и определить основанные на типе правила, которые предотвращают возвращение выделенных в стек значений или обращение к ним с помощью чего-либо, возвращаемого из функция. Я не работал с последствиями, но я подозреваю, что это было бы ужасно.
Для монадического кода есть другое решение, которое (на самом деле или почти) тоже монадическое, и может дать своего рода автоматически детерминированно разрушенный IORef. Принцип состоит в том, чтобы определить «вложенные» действия. При объединении (с использованием ассоциативного оператора) они определяют поток управления вложением - я думаю, «XML-элемент», причем крайние левые значения обеспечивают внешнюю пару начала и конца тега. Эти «теги XML» просто определяют порядок монадических действий на другом уровне абстракции.
В какой-то момент (справа от цепочки ассоциативной композиции) вам нужен какой-то терминатор, чтобы закончить вложение - что-то, чтобы заполнить дыру в середине. Необходимость в терминаторе - это то, что, вероятно, означает, что оператор композиции вложенности не является монадическим, хотя, опять же, я не совсем уверен, так как я не проработал детали. Поскольку все, что применяет терминатор, это преобразование вложенного действия в эффективно составленное нормальное монадическое действие, а может и нет - оно не обязательно влияет на оператор композиции вложенности.
Многие из этих специальных действий будут иметь нулевой шаг «конечный тег» и будут приравнивать шаг «начальный тег» к некоторому простому монадическому действию. Но некоторые будут представлять объявления переменных. Они будут представлять конструктор с тегом begin, а деструктор с тегом end. Таким образом, вы получите что-то вроде ...
Переводя в монадическую композицию со следующим порядком выполнения, каждый тег (не элемент) становится обычным монадическим действием ...
Подобные правила могут позволить реализовать CII в стиле C ++. Подобные IORef ссылки не могут выходить из своей области, по тем же причинам, по которым обычные IORef не могут выходить из монады - правила ассоциативной композиции не дают пути для ссылки бежать.
РЕДАКТИРОВАТЬ - я почти забыл сказать - есть определенная область, я не уверен в этом здесь. В принципе, важно убедиться, что внешняя переменная не может ссылаться на внутреннюю, поэтому должны быть ограничения, которые вы можете делать с этими IORef-подобными ссылками. Опять же, я не проработал все детали.
Следовательно, конструкция может, например, открыть файл, уничтожение которого завершается. Конструкция может открыть розетку, разрушение которой закрывается. По сути, как и в C ++, переменные становятся менеджерами ресурсов. Но в отличие от C ++, нет объектов, выделенных кучей, которые не могут быть автоматически уничтожены.
Хотя эта структура поддерживает RAII, вам все равно нужен сборщик мусора. Хотя вложенное действие может выделить и освободить память, рассматривая ее как ресурс, все еще есть все ссылки на (потенциально совместно используемые) функциональные значения в этом фрагменте памяти и в других местах. Учитывая, что память может быть просто размещена в стеке, избегая необходимости свободной кучи, реальное значение (если таковое имеется) для других видов управления ресурсами.
Таким образом, это позволяет отделить управление ресурсами в стиле RAII от управления памятью, по крайней мере, в случае, когда RAII основан на простой области вложенности. Вам все еще нужен сборщик мусора для управления памятью, но вы получаете безопасную и своевременную автоматическую детерминированную очистку других ресурсов.
источник
shared_ptr<>
), вы все еще сохраняете детерминированное разрушение. Единственное, что сложно для RAII - это циклические ссылки; RAII работает чисто, если граф владения является направленным ациклическим графом.Если вы считаете C ++ функциональным языком (в нем есть лямбды), то это пример языка, который не использует сборку мусора.
источник
Я должен сказать, что этот вопрос немного плохо определен, потому что он предполагает наличие стандартного набора «функциональных языков». Почти каждый язык программирования поддерживает некоторое количество функционального программирования. И почти каждый язык программирования поддерживает некоторое количество императивного программирования. Где можно провести черту, чтобы сказать, какой язык является функциональным, а какой - императивным, если не руководствоваться культурными предрассудками и популярной догмой?
Лучший способ сформулировать вопрос: «возможно ли поддерживать функциональное программирование в выделенной памяти стека». Ответ, как уже упоминалось, очень сложный. Стиль функционального программирования способствует выделению рекурсивных структур данных по желанию, для чего требуется куча памяти (будь то сборка мусора или подсчет ссылок). Однако существует довольно сложная методика анализа компилятора, называемая анализом памяти на основе областей, с помощью которой компилятор может разделять кучу на большие блоки, которые можно распределять и освобождать автоматически, аналогично распределению в стеке. На странице Википедии перечислены различные реализации этой техники как для «функциональных», так и для «императивных» языков.
источник