PSV100 писал(а):
Однако, в любом случае возникает потребность иметь ссылку на "агрегат", следовательно, типы-"агрегаты" обречены быть только объектами в куче, создаваемыми через NEW с необходимостью получения указателя. Что влечёт соответствующие последствия (напр., организация коллекций объектов вынужденно через косвенный доступ и т.д.).
Тут весь вопрос во взаимодействии между сложностью и производителностью. Наличие записей или массивов с полями, не являющимися указателями, как общего явления, усложняет язык, но увеличивает производительность. Разбить, допустим, какую-нибудь матрицу 100х100 на 10000 указателей - и получим 10000 новых объектов в куче совершенно на ровном месте. Я смотрел на Mezzano и на A2OS. Первая ползает, вторая летает. Динамическая типизация вроде бы даёт замедление только в O(1). А вот дробление объектов на мелкие... Т.е. тут у меня нет чутья, полученного из опыта, чтобы сказать, нужно ли заморачиваться с "записями" за пределом драйверов устройств, где нужно конкретное размещение битиков в памяти. Так-то увеличение громоздкости оберона после лиспа из-за одних только пар запись-указатель на запись выглядит весьма ощутимым. С другой стороны, когда у нас есть объекты переменного размера (те же объекты в смысле ООП или массивы неизвестной длины), то мы начинаем испытывать большие трудности при попытке сложить эти объекты друг за другом. Т.е. такая низкоуровневая вещь, как фиксированность размера объекта, оказывается важной для решения о том, будет ли поле встроено в запись или вынесено за указатель. И дальше опять же копирование записи с встроенным объектом копирует и встроенный объект. Т.е. такая невинная вещь, как попытка оптимизировать программу, слепливая объекты между собой, сразу ограничивает возможные виды копирования, вторгаясь на уровень семантики. Как-то это плохо.
Цитата:
Альтернативные принципы типизации в виде понятия пересечений и объединений типов в своей основе, особо то, не сложнее понятия наследования/расширения (изложения выше в теме, конечно же, напрашиваются причесаться и в целом адекватно быть сформулированными).
Пересечения и объединения типов, а особенно при добавлении операции "не", легко выходят на комбинаторную сложность компиляции. В SBCL есть константа 4. Компилятор делает 4 прохода оптимизации и дальше оставляет код в том состоянии, до которого удалось дооптимизировать. Ввиду сложности компилятора и отсутствия диагностики очень тяжело, глядя на конкретный код, заранее предсказать, где он остановится и можно ли рассчитывать на применение той или иной оптимизации. Это - ещё хуже, чем SQL, который всё же довольно прост и показывает план запроса, а и SQL - не сахар. Это была одна из причин, по которой я сбежал от SBCL. Тут, кстати, и скорость компиляции получается не очень предсказуемой.
Причём эта константа 4 не является особенностью SBCL, а, как я понял, вообще стандартным является подход "сколько-нибудь пооптимизируем и хватит".