1
Общий раздел / Oberon-07/11: Замечания по результатам использования.
« : Ноябрь 29, 2016, 06:39:03 pm »
Итак, я написал несколько десятков тысяч строк некачественного, но работающего кода на этом языке. Кратко расскажу об этом опыте.
Сначала, надо уяснить, что Oberon-07, это язык, предназначенный для быстрой реализации с минимальными затратами и сравнительно эффективного применения в случае простейшей реализации. В связи с этим, все разговоры об умных компиляторах, современных средствах отладки, шаблонах, замыканиях и т. д. лишены смысла. Многие недостатки языка либо упрощают реализацию, либо упрощают отладку в условиях, когда есть только голый компилятор без каких-либо инструментов.
Перечислю некоторые особенности языка/реализации, которые можно считать недостатками:
- ран-тайм проверки (индексы, указатели). Замедляют и так небыстрые программы. Но оказывают неоценимую помощь, позволяют быстро выявить такие ошибки, которые бывает очень трудно найти без пошагового отладчика и прочих средств. Вряд ли я хоть что-нибудь написал бы на O7 без них. Конечно, люди разные, есть и такие, которые могут кодировать сразу без ошибок на любом языке, но я к таким не отношусь.
- сильная типизация. Тоже отлавливает очень много ошибок. И да, упрощает реализацию ).
- единственный выход из процедуры, отсутствие прерываний циклов. Спорная фича. Затрудняет кодинг, увеличивает размер и снижает эффективность кода, немного упрощает отладку.
- обязательная квалификация идентификаторов. На первый взгляд, избыточно. Раздувает и без того не очень компактный оберон-код. Но вот, как-то мне надо было просмотреть одну программу на паскале, так я задолбался искать процедуры по всем модулям. Конечно, эту проблему легко решает IDE, но ведь я говорю о простейшей реализации...
Операторы:
- CASE. Вероятно, использование этого оператора для проверки типа указателя (как в поздних ревизиях) вполне оправдано. Для проверки целочисленных значений позволяет сделать более эффективный и компактный машкод, чем серия IF. Без ELSE практически бесполезен.
- FOR. Лучше, если бы переменная-счетчик создавалась при входе в цикл и уничтожалась при выходе.
- WHILE ... DO ... ELSIF ... DO. "Цикл Дийкстры" - почти бесполезен, хотя и не мешает. Одно из немногих применений:
Типы:
- SET. Применяется нечасто, но бывает полезен, когда надо упаковать несколько булевских значений в одну переменную, чтобы не раздувать список параметров.
- Беззнаковое целое. Я ни разу не пожалел о его отсутствии. Конечно, бывают случаи, когда этот тип был бы полезен, но для 32-битной реализации это бывает нечасто. Для 64-бит, ИМХО, вообще "не стОит выделки".
- ANYREC, ANYPTR. Лучше бы были.
- Динамические массивы. Без них плохо.
- POINTER TO. Здесь желательно ослабить типизацию, как это сделано в КП.
- Псевдонимы типов. Лучше бы были. В поздних ревизия они есть.
Встроенные процедуры:
- ORD(BOOLEAN): INTEGER. Используется довольно часто, странно, что в AO ее нет.
- BITS(INTEGER): SET. Такой процедуры в O7 нет. Пришлось добавить в дополнение к ORD(SET): INTEGER.
- LSR. Такой процедуры нет, но она однозначно нужна. Тоже добавил в дополнение к LSL.
- LENGTH(ARRAY OF CHAR): INTEGER. Используется часто, лучше, когда она встроена в язык. Тоже добавил.
Сначала, надо уяснить, что Oberon-07, это язык, предназначенный для быстрой реализации с минимальными затратами и сравнительно эффективного применения в случае простейшей реализации. В связи с этим, все разговоры об умных компиляторах, современных средствах отладки, шаблонах, замыканиях и т. д. лишены смысла. Многие недостатки языка либо упрощают реализацию, либо упрощают отладку в условиях, когда есть только голый компилятор без каких-либо инструментов.
Перечислю некоторые особенности языка/реализации, которые можно считать недостатками:
- ран-тайм проверки (индексы, указатели). Замедляют и так небыстрые программы. Но оказывают неоценимую помощь, позволяют быстро выявить такие ошибки, которые бывает очень трудно найти без пошагового отладчика и прочих средств. Вряд ли я хоть что-нибудь написал бы на O7 без них. Конечно, люди разные, есть и такие, которые могут кодировать сразу без ошибок на любом языке, но я к таким не отношусь.
- сильная типизация. Тоже отлавливает очень много ошибок. И да, упрощает реализацию ).
- единственный выход из процедуры, отсутствие прерываний циклов. Спорная фича. Затрудняет кодинг, увеличивает размер и снижает эффективность кода, немного упрощает отладку.
- обязательная квалификация идентификаторов. На первый взгляд, избыточно. Раздувает и без того не очень компактный оберон-код. Но вот, как-то мне надо было просмотреть одну программу на паскале, так я задолбался искать процедуры по всем модулям. Конечно, эту проблему легко решает IDE, но ведь я говорю о простейшей реализации...
Операторы:
- CASE. Вероятно, использование этого оператора для проверки типа указателя (как в поздних ревизиях) вполне оправдано. Для проверки целочисленных значений позволяет сделать более эффективный и компактный машкод, чем серия IF. Без ELSE практически бесполезен.
- FOR. Лучше, если бы переменная-счетчик создавалась при входе в цикл и уничтожалась при выходе.
- WHILE ... DO ... ELSIF ... DO. "Цикл Дийкстры" - почти бесполезен, хотя и не мешает. Одно из немногих применений:
Код: [Выделить]
PROCEDURE Scroll (value: INTEGER);
BEGIN
value := 2 * value;
WHILE value > 0 DO
Down;
DEC(value)
ELSIF value < 0 DO
Up;
INC(value)
END
END Scroll;
Конечно, здесь можно сделать по-другому, но мне показалось, что "цикл Дийкстры" подходит лучше.Типы:
- SET. Применяется нечасто, но бывает полезен, когда надо упаковать несколько булевских значений в одну переменную, чтобы не раздувать список параметров.
- Беззнаковое целое. Я ни разу не пожалел о его отсутствии. Конечно, бывают случаи, когда этот тип был бы полезен, но для 32-битной реализации это бывает нечасто. Для 64-бит, ИМХО, вообще "не стОит выделки".
- ANYREC, ANYPTR. Лучше бы были.
- Динамические массивы. Без них плохо.
- POINTER TO. Здесь желательно ослабить типизацию, как это сделано в КП.
- Псевдонимы типов. Лучше бы были. В поздних ревизия они есть.
Встроенные процедуры:
- ORD(BOOLEAN): INTEGER. Используется довольно часто, странно, что в AO ее нет.
- BITS(INTEGER): SET. Такой процедуры в O7 нет. Пришлось добавить в дополнение к ORD(SET): INTEGER.
- LSR. Такой процедуры нет, но она однозначно нужна. Тоже добавил в дополнение к LSL.
- LENGTH(ARRAY OF CHAR): INTEGER. Используется часто, лучше, когда она встроена в язык. Тоже добавил.