Используют ли все функциональные языки сбор мусора?

Существует ли функциональный язык, который позволяет использовать стеатовую семантику - автоматическое детерминированное разрушение в конце области?

30 голосов | спросил user467799 10 MarpmSat, 10 Mar 2012 23:38:43 +04002012-03-10T23:38:43+04:0011 2012, 23:38:43

3 ответа


10

Не то, что я знаю, хотя я не специалист по функциональному программированию.

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

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

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

В какой-то момент (справа от цепи ассоциативной композиции) вам нужен какой-то терминатор, чтобы положить конец гнездованию - что-то, чтобы заполнить отверстие посередине. Потребность в терминаторе - это то, что, вероятно, означает, что оператор композиции вложенности не является монадическим, но опять же, я не совсем уверен, поскольку я не работал с деталями. Поскольку все применение терминатора делает, оно преобразует действие вложенности в эффективно составленное нормальное монадическое действие, возможно, нет - оно не обязательно влияет на оператор композиции вложенности.

Многие из этих специальных действий будут иметь нулевой шаг «end-tag» и будут приравнивать шаг «begin-tag» к некоторым простым монадическим действиям. Но некоторые из них будут представлять объявления переменных. Они будут представлять конструктор с началом-тегом и деструктор с конечным тегом. Итак, вы получаете что-то вроде ...

act = terminate ((def-var "hello" ) >>>= \h ->
                 (def-var " world") >>>= \w ->
                 (use-val ((get h) ++ (get w)))
                )

Перевод в монадическую композицию со следующим порядком выполнения, каждый тег (не элемент) становится нормальным монадическим действием ...

<def-var val="hello">  --  construction
  <def-var val=" world>  --  construction
    <use-val ...>
      <terminator/>
    </use-val>  --  do nothing
  </def-val>  --  destruction
</def-val>  --  destruction

Правила, подобные этому, могут позволить реализовать RAII в стиле C ++. Ссылки, подобные IOREF, не могут избежать их масштаба, по тем же причинам, почему обычные IORefs не могут избежать монады - правила ассоциативной композиции не дают возможности для обращения к ссылке.

EDIT - Я почти забыл сказать - есть определенная область, о которой я не знаю. Важно убедиться, что внешняя переменная не может ссылаться на внутреннюю, в основном, поэтому должны быть ограничения, которые вы можете сделать с этими IOREF-подобными ссылками. Опять же, я не обработал все детали.

Следовательно, конструкция может, например, откройте файл, разрушение которого закрывается. Конструкция может открыть разъем, разрушение которого закрывается. В основном, как и в C ++, переменные становятся менеджерами ресурсов. Но, в отличие от C ++, нет объектов, выделенных кучей, которые невозможно автоматически уничтожить.

Хотя эта структура поддерживает RAII, вам все равно нужен сборщик мусора. Хотя действие вложенности может выделять и освобождать память, рассматривая ее как ресурс, все еще есть ссылки на (потенциально разделяемые) функциональные значения внутри этой части памяти и в других местах. Учитывая, что память может быть просто выделена в стеке, избегая необходимости свободной кучи, реальное значение (если оно есть) относится к другим видам управления ресурсами.

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

ответил Steve314 11 MaramSun, 11 Mar 2012 01:04:34 +04002012-03-11T01:04:34+04:0001 2012, 01:04:34
2

Если вы считаете, что C ++ является функциональным языком (он имеет lambdas), то это пример языка, который не использует сборку мусора.

ответил BЈовић 11 MaramSun, 11 Mar 2012 00:30:22 +04002012-03-11T00:30:22+04:0012 2012, 00:30:22
2

Я должен сказать, что вопрос немного не определен, потому что он предполагает, что существует стандартная коллекция «функциональных языков». Почти каждый язык программирования поддерживает некоторое количество функциональных программ. И почти каждый язык программирования поддерживает некоторое количество императивного программирования. Где вы рисуете линию, чтобы сказать, что является функциональным языком, и который является императивным языком, кроме как руководствуясь культурными предрассудками и популярной догмой?

Лучше всего сформулировать вопрос: «возможно ли поддерживать функциональное программирование в выделенной памяти стека». Ответ, как уже упоминалось, очень сложный. Стиль функционального программирования способствует распределению рекурсивных структур данных по желанию, что требует кучной памяти (независимо от того, собрана ли мусор или подсчитана ссылка). Тем не менее, существует довольно сложный метод анализа компилятора под названием анализ памяти на основе регионов , с помощью которого компилятор может разделить кучу на большие блоки, которые могут быть выделены и освобождены автоматически, аналогично распределению стека. На странице Википедии перечислены различные реализации этой техники как для «функциональных», так и «императивных» языков.

ответил Uday Reddy 12 MaramMon, 12 Mar 2012 02:09:27 +04002012-03-12T02:09:27+04:0002 2012, 02:09:27

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132