Автор | Сообщение |
metadeus
89 сообщений |
#6239 2012-06-29 21:31 GMT+3 часа(ов) |
В общем суть такова: почему в качестве основного типа данных используются cons-ячейки? На мой взгляд более правильным было бы использовать массив, в таком случае cons-ячейка это просто массив с двумя значениями, а весь код прекрасно представляется в виде массива, элементами которого в свою очередь могут быть тоже массивы.
Какие я вижу преимущества: 1. -1 тип данных -- cons-ячейка. Проще в реализации, чище в теории. 2. Не нужно вносить иметь отдельный тип данных "массив", когда весь AST представлен в списке. 3. Массив имеет константную сложность для выборки элемента по индексу, таким образом (nth 3 '(0 1 2 3)) будет работать быстрее. 4. Массив занимает меньше места, чем список на cons-ячейках. 5. Массив определенной длины быстрее выделить в памяти, чем список на cons-ячейках. 6. Массив с константным временем доступа на cons-ячейках реализовать сложно/ресурсовемко/невозможно, поэтому в лиспах делают массив отдельным типом встроенным в Лисп-машину, реализовать же cons-ячейку на массивах тривиально. Жду ваших комментариев почему я "***баёп" и мой Лисп "не нужын". Спасибо! |
|
minobull
8 сообщений |
#6240 2012-06-30 00:15 GMT+3 часа(ов) |
Теперь подумай над кодогенерацией и раскрытием макросов. Проще вставить в указанную часть списка подсписок или создать новый массив?
|
|
metadeus
89 сообщений |
#6241 2012-07-02 00:52 GMT+3 часа(ов) |
Ну, хорошо я сделаю подтип типа массив -- "веревочный массив" (по типу "веревочных строк" http://habrahabr.ru/post/144736/), который в любой момент можно будет (flatten! rope-array) -> array.
|
|
minobull
8 сообщений |
#6242 2012-07-02 02:59 GMT+3 часа(ов) |
Отлично, убрали одну сущность - cons-ячейки, добавили другую - rope-array.
Профит-то в чем? |
|
misha![]()
1275 сообщений |
#6243 2012-07-02 04:47 GMT+3 часа(ов) |
ЦитатаОтказ от cons в пользу массивов повлечет за собой увеличение нагрузки на gc. В теории может и просто, а на практике - нехилый оверхед. ЦитатаAST, состоящее из cons, проще(дешевле) модифицировать. ЦитатаЗависит от реализации gc. |
|
misha![]()
1275 сообщений |
#6244 2012-07-02 05:09 GMT+3 часа(ов) |
ЦитатаПроще реализовать подходящий тип данных, например, VList, и использовать его в своих программах, чем создавать свою реализацию из-за такой фигни. отредактировал(а) misha: 2012-07-02 05:16 GMT+3 часа(ов) |
|
metadeus
89 сообщений |
#6247 2012-07-04 15:37 GMT+3 часа(ов) |
Цитата Хотя бы в том, что rope-array is array, то есть интерфейс будет един. Да и это не единственный пункт профита (см. первый пост). Цитата "Зависит от реализации gc." (c) misha Цитата Если с операциями вставки и доступа по индексу это не так (как мы выяснили), то в каких случаях это ещё проще/дешевле? Цитата Да, хороший тип, но все эти надстройки в виде rope-array и vlist можно реализовать поверх на самом языке с массивами. На мой взгляд, не очень удачный подход "любой задаче один тип", да и не всегда такой оверхед приемлем. Массивы не единственное отличие реализации, просто одно из, которое я хотел обсудить. |
|
misha![]()
1275 сообщений |
#6248 2012-07-04 20:52 GMT+3 часа(ов) |
ЦитатаНо это разные типы. ЦитатаЭто для rope-array еще как-то можно оптимизировать операции удаления/вставки. Кстати, после многочисленных операций удаления/вставки как время выборки, так и время вставки для rope-array может превысить аналогичный показатель для списка(cons). Т.е. нет ни константной, ни линейной зависимости. Да и добавление возможности создания циклических структур внесет свой оверхед. ЦитатаА разве вы не этого хотите? Лично я не вижу необходимости в избавлении от cons. Пусть пользователь выбирает какой ему тип больше подходит. |
|
metadeus
89 сообщений |
#6249 2012-07-04 21:44 GMT+3 часа(ов) |
Цитата Ну в данном случае rope-array это оптимизация, которая может быть, а может и не быть. Надо смотреть по результатам замеров нужна ли она в принципе. Цитата Вообще говоря, да. Но использование более умных типов типа того же vlist будет усложнять возможности переиспользования данных (то есть -- часть массива A, является так же массивом B). Действительно, не всё так очевидно тут, надо подумать. Цитата Нет. Я хочу чтобы в основе системы был минимальный базис/ядро, такой, чтобы не было ограничений на его расширение. Причем важно, чтобы можно было реализовать типы и операции над ними с наилучшей сложностью. Таким образом, т.к. cons-ячейки в принципе реализуемы через массивы (в теории с операциями той же сложности), а обратное неверно, то cons-ячейки получаются лишние в ядре. А для пользователя я как раз за максимальное количество типов -- должны быть и cons-ячейки, и массивы, и веревочные массивы, и списки, и vlist и пр. Но в качестве стандартной библиотеки. Подход не правильный с теоретической точки зрения или у вас только к практической части вопросы? |
|
misha![]()
1275 сообщений |
#6250 2012-07-05 03:39 GMT+3 часа(ов) |
ЦитатаС практической точки зрения, rope-array лучше реализовать как отдельный тип данных. Пусть пользователь сам выбирает, что ему лучше использовать. ЦитатаЕще не стоит забывать про то, что неиспользуемые части(куски) массивов(векторов) будут приводить к скрытой фрагментации памяти. ЦитатаТак уж завелось, что cons является базовым типом для любой лисп системы. И на практике он используется довольно часто, например, для создания сложных структур данных, разрешения коллизий при хешировании. Поэтому желательно оптимизировать процесс создания cons (и сборки мусора). ЦитатаВообще-то в этом случае вам придется реализовывать через структуры. Вам также придется учитывать, что наличие огромного количества неиспользуемых малых фрагментов(мусор) может вызвать нехилую фрагментацию памяти. В итоге вам необходимо будет реализовывать сжимающий(или копирующий) сборщик мусора. отредактировал(а) misha: 2012-07-05 03:46 GMT+3 часа(ов) |
|
Kergan
300 сообщений |
#6251 2012-07-05 11:47 GMT+3 часа(ов) |
> Нет. Я хочу чтобы в основе системы был минимальный базис/ядро
Ну так с конс-ячейками (массивами длины 2) мы и имеем минимальное ядро. Твой вариант получается расширением этого ядра при помощи добавления массивов произвольной размерности. Естественно, нет никакой сложности в увеличении производительности ценой усложнения ядра. И, кстати, консы на массивах потребуют в полтора раза больше памяти, чем обычные консы. |
|
Kergan
300 сообщений |
#6252 2012-07-05 11:50 GMT+3 часа(ов) |
> В итоге вам необходимо будет реализовывать сжимающий(или копирующий) сборщик мусора.
Перемещающий сборщик мусора в любом случае необходимо использовать, т.к. только с таким сборщиком память может быть выделена эффективно (за несколько инструкций процессора). К слову, есть вариант простого и эффективного перемещающего сборщика с константным потреблением памяти (требуется несколько десятков байт на весь процесс сборки) и отсутствием дополнительных полей для маркировки при условии unidirectional heap. |
|
metadeus
89 сообщений |
#6253 2012-07-05 14:11 GMT+3 часа(ов) |
Цитата Если с конс-ячейками минимальное ядро, то как на таком ядре реализовать массивы? Я рассматриваю массив просто как отношение "лежит рядом в памяти", конс-ячейка реализует отношение "пара" или "пара лежащая рядом в памяти", здесь массив выражает более общее отношение, а конс-ячейка лишь его проекция для двух элементов. То, что консы на массивах потребуют больше ресурсов это, конечно, плохо, но не так страшно, если конс перестанет быть типом на все случаи жизни. Если пытаться решить и проблему с консами, то нужно признать, что и массив в качестве основания тоже подходит слабо. Но в этом случае остаются только совсем уже базовые "машинные" типы: указатель, структура и простые типы. Тогда мой МассивныйЛисп становится уже СишнымЛиспом или ЛисповымСи, в который и сборку мусора-то без танцев с бубном не встроишь, не говоря уже о макросах =). В общем, насколько я понял особого смысла менять консы на массивы нет, т.к. упрощение в одном станет усложнением в другом. Оффтоп: ещё интересен с данной точки зрения язык Lua, насколько я понимаю в нем единственный тип это таблица (она же массив, она же хеш-таблица), только там код не на S-выражениях и AST не на этих таблицах (не Лисп, в общем). |
|
Kergan
300 сообщений |
#6254 2012-07-07 11:17 GMT+3 часа(ов) |
Цитата Никак, очевидно. Это ядро недостаточно велико, чтобы можно было выразить масивы длины отличной от двух. Ты и предлагаешь это ядро расширить массивами любой длины - не только двойки. Цитата То, что массивы на консах потребуют больше ресурсов это, конечно, плохо, но не так страшно, если массив перестанет быть типом на все случаи жизни. Цитата По-этому во всех нормальных диалектах есть и массивы и консы, очевидно. |
|
misha![]()
1275 сообщений |
#6255 2012-07-08 01:45 GMT+3 часа(ов) |
ЦитатаА почему нельзя? ЦитатаВ принципе, можно реализовать относительно компактные массивы на gc изначально ориентированном на cons. |
|
Kergan
300 сообщений |
#6256 2012-07-08 14:09 GMT+3 часа(ов) |
Цитата Ятп под массивом подразумевалась структура данных с константным временем доступа. через консы, понятное дело, не реализуешь. Цитата это к чему? |
|
misha![]()
1275 сообщений |
#6257 2012-07-08 14:50 GMT+3 часа(ов) |
ЦитатаРечь шла не о cons, а о gc изначально ориентированном на cons. ЦитатаЗависит от конкретной реализации gc. |
|
metadeus
89 сообщений |
#6259 2012-07-08 22:32 GMT+3 часа(ов) |
Цитата Было бы так, если бы не: "Никак, очевидно. Это ядро недостаточно велико, чтобы можно было выразить масивы длины отличной от двух." Цитата Да, только ценность консов в качестве отдельного типа данных я и пытаюсь поставить под сомнение. На мой взгляд, гораздо чище в концептуальном плане иметь один тип - массив и, например, его оптимизированную реализацию (подтип) для представления AST, которая может быть даже не доступна разработчику (для него всё будет массив), чем иметь два типа в ядре, которые так же имеют различный интерфейс, да ещё и не ортогональны друг-другу (консы через массивы). |
|
misha![]()
1275 сообщений |
#6261 2012-07-09 02:45 GMT+3 часа(ов) |
ЦитатаТ.е. вы ставите под сомнение целесообразность использования s-выражений? ЦитатаНу, тогда это будет не Лисп, а диалект АПЛ. |
|
metadeus
89 сообщений |
#6262 2012-07-09 15:07 GMT+3 часа(ов) |
Цитата Нет, конечно. S-выражения не на консах построены, а на списках, а списки не обязательно должны быть на консах (более того, во всех языках кроме Лиспа списки не на консах). Цитата Судя по определению "array programming language" это все таки другое. И на мой взгляд это будет все таки Лисп, т.к. представление AST в виде объектов языка в качестве s-expr сохранится. |
|
misha![]()
1275 сообщений |
#6263 2012-07-09 16:48 GMT+3 часа(ов) |
ЦитатаS-выражения построены на связанных списках. Вот, например, список (1 . 2), состоящий из одной cons, и при этом он является полноценным списком. ЦитатаТак там рассматривается массив как список, ведь список - это абстрактный тип данных. Кстати, в Прологе связанные списки. ЦитатаА кто вас заставляет использовать синтаксис АПЛ? Вы можете свободно использовать массивы для представления АСД. |
|
metadeus
89 сообщений |
#6266 2012-07-10 16:17 GMT+3 часа(ов) |
Цитата Оп-па, а ведь действительно. У меня в голове было неправильное представление о типах CL сформированное на основе PCL, где было явно сказано, что "списков нет, есть cons-ячейки". А на практике получается что cons is list, что несколько меняет смысл. Но деление тогда идет proper/improper list: (1 . 2) is list (improper list) (1 . (2 . nil)) is list (proper list) S-выражение обязано быть proper list'ом? Мы же не можем (#'(lambda (x) (* x x)) . 10)? Цитата Ну значит s-expr в виде списков на массивах или на связанных списках или vlist вполне себе возможны. Цитата Я про синтаксис и не говорю ничего, я лишь о том, что "array programming language" это: "In computer science, array programming languages (also known as vector or multidimensional languages) generalize operations on scalars to apply transparently to vectors, matrices, and higher dimensional arrays." по Педивикии, а я ничего подобного не замышлял. То есть я считаю если заменить основу list с cons на array, а представление AST как было на основе list, так и оставить, то получится Лисп, т.к. семантика останется нетронутой. |
|
misha![]()
1275 сообщений |
#6267 2012-07-10 17:47 GMT+3 часа(ов) |
ЦитатаВсе эти "ускоренные курсы" рассчитаны на то, что прочитав их вы затем возьметесь за что-нибудь более солидное. ЦитатаНе обязано ![]() Цитата"#'(lambda ..." не является синтаксически грамотным вызовом функции. Но мы можем записать, например, так ((lambda (x) (* x x)) . (10))или так ((lambda . ((x . nil) . ((* x . (x)) . nil))) . (10 . nil)) |
|
misha![]()
1275 сообщений |
#6268 2012-07-10 18:04 GMT+3 часа(ов) |
ЦитатаТогда я не вижу никакой существенной выгоды от замены. ЦитатаЕсли вы понимаете как происходит макроэкспанд, то вы должны уже были понять, что подобная замена приведет лишь к дополнительному расходу памяти, и в большинстве случаев замедлит экспанд в несколько раз. |
|
Kergan
300 сообщений |
#6273 2012-07-13 03:05 GMT+3 часа(ов) |
Цитата Нет, это не список. Список обязан заканчиваться на nil. |
|
Kergan
300 сообщений |
#6274 2012-07-13 03:07 GMT+3 часа(ов) |
Цитата s-выражение может быть любым readable-объектом лисп-системы. То есть это может быть, например, произвольный текст или запись 9 симфонии Бетховена, которая принимается с микрофона. Или ваще смотрящее в веб-камеру лицо. Цитата Но только он будет тормознее и жрать больше памяти. А так да - никакой разницы не будет. |
|
metadeus
89 сообщений |
#6275 2012-07-13 14:54 GMT+3 часа(ов) |
Цитата То есть M-выражение может быть S-выражением? Цитата Ладно, я посчитал и согласен. отредактировал(а) metadeus: 2012-07-13 16:37 GMT+3 часа(ов) |
|
metadeus
89 сообщений |
#6276 2012-07-13 14:55 GMT+3 часа(ов) |
Цитата Это противоречит тому, что cons это наследник list. |
|
metadeus
89 сообщений |
#6277 2012-07-13 16:36 GMT+3 часа(ов) |
Цитата Ну скорее да, вы правы. |
|
misha![]()
1275 сообщений |
#6283 2012-07-16 02:32 GMT+3 часа(ов) |
ЦитатаСписок - это абстрактный тип данных. В Лиспе список это nil (empty proper list), либо cons. Условно связанные списки можно разделить на proper, dotted, и circular. |
|