Info21 писал(а):
Ещё раз:
так же, как нуль даёт возможность "регуляризовать" алгоритмы арифметики,
так же, как цикл why оказывается в целом самым удобным ровно потому, что допускает повторение нуль раз,
так же, как рекурсивные процедуры, обрабатывающие "нулевой случай", приводят к более компактным и ясным программам, чем в противном случае,
-- совершенно в той же струе лежат наблюдавшиеся ситуации, где допущение массивов нулевой длины "регуляризовало" бы код.
По умолчанию программа должна корректно обрабатывать "нулевой случай".
Правило базовой техники программирования.
Вопрос о том, почему оно не распространено на массивы.
Валерий Лаптев писал(а):
С научной точки зрения - все правильно.
Вопросы - в реализации.
Статический массив нулевой длины должен иметь какой-то адрес.
Проверка индексов, на мой взгляд, очевидно, для такого массива должна быть при компиляции.
...
Возможно, ключевое в том, что есть "массив нулевой длины", и что есть тогда "правильно с научной точки зрения".
Кстати, в основных императивных языках программирования по историческим причинам в итоге получился какой-то казус в массивах. Использовать формы декларации динамических/открытых массивов не получится в тех случаях, когда применяют статические массивы (а точнее -- псевдомассивы) нулевой длины (не должно быть никаких скрытых структур-дескрипторов, содержащих длину и прочие возможные метаданные и т.п., контекст управления условными метаданными находится вовне таких объектов). Ведь, что Си-шная форма аля:
my_data_t data[0]
, что ещё более загадочная FreePascal/Delphi-форма аля:
data: array[0..0] of TMyData
по сути "с научной точки зрения" некорректны. Указание нуля для измерения массива есть декларация отсутствия этого измерения. Нуль-мерный массив по определению есть скаляр (фактически, не есть массив).
Илья Ермаков писал(а):
У динамических массивов в их заголовке блока может стоять длина 0, корректно работало (создать нельзя нулевой длины, потом поставить можно - мы делали SetLength для дин. массивов - который многие на этом форуме используют - и там допускается и 0).
Видимо, может быть и были какие-то идеологические заморочки с тем, что нельзя создавать массив нулевой длины через new. Мол нельзя задать нуль-мерный массив (или "отменить" (т.е. не указать) какое-то измерение из возможных). А установка длины для одномерного массива-вектора (иными словами, с уже предварительно определенным/введённым измерением, т.е. абстрактный "программистский" массив с неопределенными измерениями до new "превратился" в вектор после new) есть мол декларация нуль-вектора (хотя, скорее, хрень какая-то в итоге).
Со стороны "математической научности" показательны языки ML-семейства, где массивы выражаются через форму степени. Массив как кортеж, например, из трёх элементов типа "a" структурно задаётся через произведение (логическое "и"): "a * a * a", что эквивалентно: "a^3". Если указать нулевую степень (для любого типа), то "по-научному" уже нет никакого массива и возникает универсальный тип unit (единица), что эквивалентно пустым скобкам "()". Аналогично введены пустые скобки для списков "[]", для векторов "[| |]" и пр. Именно такие "пустые" константные объекты (с возможностью сопоставления объектов с ними) соответствуют "научным" выражениям пустого множества, нуль-вектора и т.д. (где-то возможны непосредственно юникод-символы пустого множества и пр.).
Видимо, всё-таки, в рамках вопросов реализации для поддержки "научной точки зрения" желательны константные выражения для массивов, где пустая форма аля "[]" задаёт частный случай нуль-вектора в явном виде.
А реализация в языке "правильных" динамических массивов, которые не содержат ничего лишнего, не требуют никакой памяти при нулевых размерах, и нет никаких скрытых вспомогательных структур, плюс контроль доступа (отключаемый при необходимости) со стороны компилятора -- вопрос непростой, однако. Видимо, нужны техники аля "регионов" в стиле некоторых ML-диалектов (и некоторых приёмов из Rust, пришедших из ML), может быть потребуются аля "дискриминанты" записей как в Ada, и пр. Путь не для Оберонов, видимо.