Ну вот я пишу на питоне тоже, там есть родные (лаконичные) кортежи. Пользуюсь ими все равно не очень часто (хотя пишу в обсуждаемом стиле - все инициализируется чем-то осмысленным).
Основной недостаток - если такой кортеж пошел гулять за пределы двух/трех функций, то понять смысл того, что там лежит становится трудно.
Именованная структура все же лучше. Опять же - ваш оригинальный пример довольно экстремальный. Так что острой необходимости в кортежах я не вижу.
Нет ничего экстремального в инициализации по одному условию нескольких переменных и по смыслу не объединяемых в одну сущность. Ну, строго говоря, острой необходимости нет не только в кортежах, но и в...
Как минимум нужно и объявление типа по месту.
В смысле рядом с функцией? Ну да, желательно. Но тоже не то, чтобы принципиально, если модули человеческих размеров.
Модули даже человеческих размеров всё-таки велики. Вспомните как сишники жалуются, что в Паскале до переменных в функции долго добираться, а Вы аж про модули. Впрочем, записи,
нужные лишь в одной процедуре, можно объявить в ней самой, это давно есть.
статически объявленные экземпляры структур
Ну так - инициализировать при объявлении. Что не так?
Как, что? Для функций, возвращающих большие структуры, возникают большие накладные расходы на копирование. То же касается и массивов. Это можно обойти, но неизбежно вылезут другие шутки.
Точно ничего? А выделять память отдельной операцией будете? Чем поможет вспомогательная функция-конструктор, если инициализировать всё равно одной командой нужно? Как инициализировать расширенные записи при желании использовать код для базовых записей?
Ну, допустим у нас есть такой синтаксис для инициализации:...
И опять-таки, большие накладные расходы, особенно для инициализации больших структур с серией маленьких расширений. Если это устраивает, то можно и без конструкторов.
Хотя смысл статически выделенных данных по большей части в скорости работы с ними. Если она не нужна, то и статические данные не нужны, о чём я и писал. Понятное дело, что в
задачах, где хватает Питона, разработчика такое может не волновать.
И это не единственные последствия, но лень писать, ибо длинно.
Да, и всё-таки, как поможет функция-конструктор для большой структуры, если инициализировать всё-равно одной операцией?
Просто данные модуля инициализируются так же как и локальные переменные - при объявлении. Инициализация таких данных происходит до вызова секции инициализации модуля.
Нет, я имел ввиду ситуацию, когда нужно инициализировать именно в секции модуля, но мы знаем точно, что она там происходит, тем не менее везде нужно будет использовать проверку об инициализации.
Про вред размазывания инициализации по тексту модуля я уже писал когда-то, сейчас лениво, да и тогда Вам не показалось это чем-то важным.
К примеру, транспонирование матрицы - штука быстрая. А если это массив структур, содержащих массивы?
Не, хочется реального примера Мне больше видятся всякие низкоуровневые штуки, когда надо скормить кусок памяти драйверу и т.п. Но для таких случае всегда есть SYSTEM Улыбающийся
Во первых, инициализация - это за исключением наиболее простых случаев, не забитие одним и тем же значеним всего массива. Ну а возможность в оригинальном Обероне объявить большой массив записей вместе с потенциальной необходимостью тут же инициализировать эти записи вообще порождает курьёзную ситуацию.
Как пример, представьте себе большой массив, который заполняется по мере надобности и который нужно получить с минимальной задержкой, чтобы без промедлений отреагировать на действия пользователя.
Давать что-то более конкретно - лень.
... а вот функции по нескольку тысяч строк, плохо поддающиеся пониманию и переработке из-за усеянности на самом деле ненужными return-ами мне встречаются регулярно.
Дык, согласитесь, что оригинальная проблема в функциях на 1000 строк, а не в RETURN. Думаю вы бы скорее согласились сопровождать функции на 10 строк с RETURN, чем на 1000 строк без RETURN?
Проблема именно во множественных return, а также break, continue, goto, ну и головах программистах, естественно. Дело в сопровождении. Сначала функция хоть и с несколькими выходами, но небольшая, ничего криминального. Со временем функция разрастается и пора бы её разбить на множество функций, да в общем случае сделать это не так просто, поскольку return в подфункцию не засунешь, а использование механизма исключений(там где он вообще есть) только закрепит кашу, пусть и разбитую на порции. Заодно это требует от исключений быть гибкими (переносить что угодно) и быстрыми(поскольку в переходы часто закладывается нормальная логика, а не только маловероятные исключения). Легко такое сделать? Что нам об этом говорит опыт С++, Java, C#?
Человеком ваш код тоже воспринимается непросто. Лично мне понятнее переделанный вариант.
А мне - мой, что тут поделать.
Вспомнил о ещё одной неудобности. В Обероне значение переменных можно менять, передавая их через параметры в процедуры. Легко представить ситуацию, когда такими процедурами можно также инциализировать, но при таком подходе получится это только с накладными расходами.