Почему чисто функциональные языки не используют подсчет ссылок?

Чтобы получить все атрибуты свойства в словаре, используйте это:

typeof(Book)
  .GetProperty("Name")
  .GetCustomAttributes(false)
  .ToDictionary(a => a.GetType().Name, a => a);

не забудьте изменить значение false на true, если вы хотите также включать в себя наследуемые атрибуты.

43
задан T. Bergemann 3 August 2016 в 10:05
поделиться

5 ответов

Ваш вопрос основан на ошибочном предположении. Вполне возможно иметь круговые ссылки и неизменные данные. Рассмотрим следующий пример C #, который использует неизменяемые данные для создания циклической ссылки.

class Node { 
  public readonly Node other;
  public Node() { 
    other = new Node(this);
  }
  public Node(Node node) {
    other = node;
  }
}

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

Редактировать с помощью ephemient

. В ответ на комментарий ... в Хаскеле

data Node a = Node { other :: Node a }
recursiveNode = Node { other = recursiveNode }

это тривиально и едва ли нужно больше усилий в SML.

datatype 'a node = NODE of unit -> 'a node
val recursiveNode : unit node =
    let fun mkRecursiveNode () = NODE mkRecursiveNode
    in mkRecursiveNode () end

Не требуется мутация.

19
ответ дан 26 November 2019 в 22:59
поделиться

По сравнению с другими управляемыми языками, такими как Java и C #, чисто функциональные языки выделяются как сумасшедшие . Они также выделяют объекты разных размеров. Самая быстрая из известных стратегий распределения заключается в выделении из смежного свободного пространства (иногда называемого «детской») и резервировании аппаратного регистра для указания следующего доступного свободного пространства. Распределение из кучи становится таким же быстрым, как и выделение из стека.

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

Подсчет ссылок имеет тенденцию действительно хорошо работать в таких ситуациях:

26
ответ дан 26 November 2019 в 22:59
поделиться

Я думаю, есть несколько вещей.

  • Существует циклов : «let rec» во многих языках позволяет создавать «круговые» структуры. Помимо этого, неизменность обычно не подразумевает циклов, но это нарушает правило.
  • Подсчет ссылок плох в списках : я не знаю, что коллекция с подсчетом ссылок хорошо работает, например, с длинными односвязными список структур, которые вы часто найдете в FP (например, медленный, необходимо обеспечить хвостовую рекурсию, ...)
  • Другие стратегии имеют преимущества :
10
ответ дан 26 November 2019 в 22:59
поделиться

Reference counting is MUCH slower than GC because it's not good for CPU. And GC most of the time can wait for idle time and also GC can be concurrent (on another thread). So that's the problem - GC is least evil and lots of tries shown that.

-4
ответ дан 26 November 2019 в 22:59
поделиться

Рассмотрим эту аллегорию , рассказанную о Дэвиде Муне , изобретателе Лисп-машины :

Однажды студент пришел к Муну и сказал: «Я понимаю, как сделать лучше сборщик мусора. Мы должны вести счетчик ссылок на указатели на каждую минус».

Мун терпеливо рассказал студенту следующую историю:

«Однажды студент пришел к Муну и сказал: «Я понимаю, как сделать сборщик мусора лучше ...

8
ответ дан 26 November 2019 в 22:59
поделиться
Другие вопросы по тегам:

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