Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 15 дек 2019, 10:16

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ 1 сообщение ] 
Автор Сообщение
 Заголовок сообщения: Ответ Alone Coder'у
СообщениеДобавлено: 28 май 2014, 11:37 
Не в сети
Аватара пользователя

Сообщения: 987
Откуда: Днепропетровская обл.
Dmitry Bystrov писал(а):
Всё-таки Оберон - не тот язык, который мне нужен. Не подходит ни для Z80, ни для FPGA (речь не про софт-ядра!).
Можно лишь констатировать устаревание Z80. Недостаточное количество адресуемой памяти, страничная работа с ней, низкая скорость, переусложнённая система команд CISC, неоптимальная для трансляции с языков высокого уровня.

Цитата:
Он очень заточен на ту архитектуру, для которой изначально разрабатывался:
- что там процессор, причём 32-разрядный (не нужен 64-битный целый тип) - исправлено в Component Pascal
Разрядность типов, насколько я помню, не зафиксирована в сообщении о языке. Если брать Оберон-07, я тоже от него не в восторге. Если брать Оберон-2/КП — тип LONGINT можно сделать 64-битным (в трансляторе Ofront, например, разрядность типов задаётся в отдельном конфиге Ofront.par). В ETH Oberon есть тип HUGEINT. Он может быть 128 бит. Я настаиваю, что Обероны можно и нужно пересматривать и улучшать.

Цитата:
- что там фоннеймановская архитектура (не нужно два типа указателей и ограничение стека)
На самом деле там бы не помешало два типа указателей, только не для кода и данных, а указатели, подчинённые сборке мусора (теговые) и не подчинённые (безтеговые). На уровне языка это не решено, и, по-моему, это явная недоработка, которую можно оправдать стремлением Вирта сделать несистемную составляющую языка как можно более безопасной. Впрочем, в некоторых реализациях Оберона для опасных указателей есть системное свойство [untagged] или [NOTAG].

Но указатели на код в чистом виде есть. Это процедурный тип.

Цитата:
- что там однозадачность (не нужно распараллеливание и т.п.)
BlackBox уже устроен многопоточно. Можно пользоваться многозадачностью, которая не вшита в язык (как в Модулу-2), а устроена библиотечно. Притом она может быть как классической многопоточной, так и кооперативной. Просто в свете Оберон-исследований (я имею ввиду проект Active BlackBox И.Ермакова) и стремления к простоте и надёжности делается бОльший упор на кооперативную. Иначе с привязкой вида многозадачности к языку он станет непереносимым.

Цитата:
- что там нет задач реального времени (обновление визуализатора - атомарная операция)
В AO заявлена работа в режиме реального времени. Не знаю как это сочетается со сборкой мусора. Этот вопрос я подробно не исследовал, но там есть системные секции, отвечающие за это.

Цитата:
- что там английский язык (не нужны символы, кроме ASCII) - исправлено в Component Pascal
Ну, этим страдают многие ЯП. В XDev я это тоже исправлю. Будет Оберон-2 + кириллица.

Цитата:
Оберон:
=======

С точки зрения надёжных вычислений:
-----------------------------------

- Нет ASSERT.
В C++ есть.
Ну и откуда же такие данные? В любом диалекте Оберона ASSERT есть.

Цитата:
- Средствами Оберона невозможно отследить переполнение в целочисленной арифметике (даже не определены банальные константы типа maxint).
Ну как же. Определены. MAX(INTEGER) и MIN(INTEGER). Тоже есть в любом диалекте Оберона.

Я не вижу проблемы встроить средства для проверки на переполнение. В BlackBox, кстати, они встроены, только, по-моему, выключены по умолчанию. Для эффективности.

Цитата:
Можно было просто расширить целые типы значением NaN (в отладочном режиме компиляции, которого нет).

- Прерывание вычислений - опасное поведение. В том числе при делении на ноль.
Для этого в IEEE float предусмотрены значения infinity и NaN, но в Обероне они не поддержаны.

При range check тоже следовало бы возвращать NaN (при чтении) и пропускать запись (при записи).
Или хотя бы давать выбор - компилировать с прерыванием вычислений или с NaN'ами.
Опять же для простоты. В некоторых реализациях на уровне ядра можно это отслеживать.

Цитата:
- Присваивание <REAL> := <LONGINT> чревато ошибками округления. Предупреждения не выдаётся.
Всегда при присваивании целого вещественному есть ошибки округления

Цитата:
- Не контролируется ошибка сравнения <вещественное> = <вещественное> или <вещественное> = <целое>.
Согласен, здесь надо более строго.

Цитата:
- Нет деструкторов, в итоге из функции нельзя возвращать объект и использовать его, например, так: UseObject(ReturnObject(x)).
В C++ можно.
В ООП-языках деструктор — это процедура, вызываемая неявно. А если при деструкции нужны какие-то дополнительные уточнения, как именно деструктировать? Если нужен параметр? Появляются деструкторы вызываемые и явно, и неявно. Начинается путаница. Теряется прозрачность. Впрочем, в Обероне эти вещи, можно сказать, вынесены на уровень модулей, а не объектов. И инициализация при загрузке (а в КП — и деинициализация при выгрузке) модулей происходит неявно — через секции BEGIN (CLOSE). Это своеобразные конструктор и деструктор модулей.

Цитата:
Деструктор - это не просто освобождение памяти, которое может сделать сборщик мусора! Там могут освобождаться и другие ресурсы!
В Дельфи деструкторы тоже вызываются явно, но это никому не мешает. Впрочем, я не спорю. Но всегда будет желание помимо неявного вызова деструктора добавить в язык ещё и вот эту вкусняшку. Мёссенбёк остановился на этом, кто-то пошёл бы дальше.

Цитата:
- Принципиально отсутствует отладчик, что не позволяет отследить поведение при использовании сторонних модулей. Это не вопрос "правильного проектирования", т.к. сторонние модули пишут другие люди и у этих модулей даже может не быть исходника. В случае, если эти модули работают с железом, вообще процветает рандом в квадрате.
Почему бы не создать отладчик, я давно себя об этом спрашиваю. Я за творческий подход к Оберон-технологиям. И если дядя Вирт обходится без отладчика, а кому-то он нужен, то почему бы его и не использовать.

Цитата:
- Без GOTO нельзя реализовать исключения, а готовой конструкции нет.
В C++ есть.
Библиотечно и, главное, в ядре можно иметь процедуры, которые будут даже перехватывать ASSERT и обрабатывать его, если понадобится. Не говоря уж об исключениях. Подобные механизмы встроены в BlackBox.

Цитата:
- Строковые и символьные константы пишутся одинаково. Чревато ошибками.
В Си по-разному.
Этот вопрос уже критиковался Патриком Реали (кажется). Так что вопрос известен, и оберонщики себе его ставят. В практическом же программировании я не чувствую с этим никаких проблем. Строка длиной в один символ является строкой или символом в зависимости от контекста.

Цитата:
- Символы в строках адресуются по номеру вместо бегунка.
Чревато ошибками при использовании UTF8.
В Си в роли бегунка указатель.
Ну, для использования кодировок с разной длиной символов этот механизм не задумывался. Впрочем, такие строки неудобно обрабатывать. Есть смысл перекодировать их в строки с одинаковой длиной символов. Опять же, можно работать со строками в UTF8 как с двоичными данными.

Цитата:
- Разрешена рекурсия. Компилятор даже не выдаёт предупреждение.
Отсюда уязвимость через переполнение стека (без рекурсии глубина стека известна ещё на этапе компиляции).
В Си это тоже есть. ;)

Цитата:
- Нет вещественного типа с точностью (a+-p).
(Его и нигде нет, хотя нужен.)
Не знаю. Много чего есть в Ada или новой ревизии Модулы-2. Но это большие и сложные языки. Перед Обероном стоит цель быть простым, а не всеобъемлющим.

Цитата:
- Нельзя проконтролировать, что переменная инициализирована.
Ср. язык Rust - там это делается ассертом на этапе компиляции.
Есть гарантия, что неинизиализированный указатель всегда будет равен NIL. Для числовых переменных сочли это излишним. Ну что ж, при работе на Паскале, C++ или Java это никого не смущает тоже. Впрочем, никто не мешает генерировать предупреждение при использовании неинициализированной переменной. Что, впрочем, может вызвать трудности с таким кодом:
Код: "OBERON"
  1. Call(var); (* Предположим, что var — это VAR-параметр, результат работы процедуры. *)
Не очень красиво, но разрешено. Не предлагаешь ведь запретить такой код тоже?

Цитата:
- Нельзя проконтролировать, что файл открыт на момент использования или закрыт на момент уничтожения объекта.
Ср. язык Rust - там это делается ассертом на этапе компиляции.
Ну это ты уже придираешься. Работа с неоткрытым файлом приведёт к тому, что первый же прогон программы выдаст ошибку.

Прошу озвучить недостатки языка Rust. Я уверен, что даже в сравнении с Обероном их много. Или, по крайней мере, их достаточно, чтобы я не использовал Rust.

Цитата:
С точки зрения красоты языка:
-----------------------------

- MAX для SET возвращает максимальный элемент. А что если SET пустой?
MAX(SET) возвращает не максимальный элемент, а максимальное значение типа. А это всегда константа.

Цитата:
- MIN для SET возвращает 0. Зачем нужна функция, которая всегда возвращает 0?
Для симметрии, затем же, что и MIN(INTEGER).

Цитата:
- Один ряд совместимых типов (вещественные смешаны с целыми), из-за чего пришлось отказаться от беззнаковых (в том числе BYTE) и даже от 64-битных целых!
Исправлено в Component Pascal, хотя названия типов несколько непрозрачны (BYTE знаковый, а SHORTCHAR нет, хотя ожидалось бы наоборот).
Ну кого интересует знаковость символьного типа, разве что сишников.

Вещественные типы не смешаны с целыми, а выстроен иерархический ряд, где меньшие типы поглощаются бОльшими, отсюда нужно меньше телодвижений по явному преобразованию меньших в бОльшие типов.

Беззнаковые типы отнесём к суровым трудностям прошлого. Хотя, впрочем, я слышал, что в новом компиляторе Активного Оберона есть полная линейка системных беззнаковых типов, и как-то они там уживаются с линейкой знаковых. Так что реализовать можно, как говорится, было бы желание. А пихать ли их в стандарт языка — это для меня спорное улучшение. Из-за путаницы от смешивания знаковых с беззнаковыми.

64-битные целые никто не отменял. В КП тип LONGINT это как раз они и есть.

Цитата:
- WHILE и LOOP зачем-то разделены.
В итоге в WHILE появляются нечитаемые двойные условия или вычисление условия в теле цикла, что тоже нечитаемо.
Они разделены не зачем-то, а очень даже затем, что так надо. А именно: после выполнения цикла WHILE гарантируется, что условия вхождения в цикл стопроцентно исчерпали себя. А из цикла LOOP всегда можно выйти по EXIT.

Это ограничение дарит ни с чем несравнимое чувство полного контроля над циклом, дополнительную мотивацию продумывать построение циклов, а не лепить корявые циклы, из которых всегда можно выйти, если что. И это недостижимо в других ЯП, разве что если перестать использовать в цикле WHILE явный выход из него, что, впрочем, хорошо для одного дисциплинированного разработчика, но всех так писать не заставишь.

Цитата:
- OR, но & и ~.
Явное отступление от принципов читабельности Паскаля.
& — международный символ. Не мешает. Наоборот, неплохо для краткости. Непривычно после Паскаля, да. Но мне нравится.

Цитата:
- Звёздочки и минусы для пометки идентификаторов - ненаглядно и забывается, что есть что.
Явное отступление от принципов читабельности Паскаля.
Угу, уж конечно читабельнее дублировать процедуры в теле INTERFACE/IMPLEMENTATION. ;)

Очень приятно же здесь то, что можно использовать ленивый экспорт по мере необходимости, без перебрасывания прототипов из тела в интерфейс. Звёздочкой часто помечают. А минус это ограниченный экспорт, да тут же мудрено запутаться, разве что в первочтении сообщения о языке.

Цитата:
- Структуры адресуются и по указателю, и непосредственно - в результате этой ненужной свободы понадобился ненаглядный символ ^.
Можно было сделать только по указателю. Компилятор даже может это оптимизировать.
При этом в языке даже не понадобилось бы выражение POINTER TO.
А это бы привело к тому, что все структуры стали бы динамическими, что убило бы производительность, что мы и наблюдаем в языке Java, где всё динамическое.

В КП можно опускать символ ^.

Цитата:
- & некоммутативна (хотя сам Вирт ругал Си за то, что там a=b и b=a означают разное).
Это как же?

Цитата:
- Допустима конструкция END END; (вместо END;END;) - плохой стиль (такая программа не расширяется простой вставкой строк).
Кроме того, как это ест "простой" парсер?
Можно было бы отказаться от разделителей на концах строк (как в языке Go), но проблема с длинными выражениями.
Разделители были бы вообще не нужны, если бы все выражения писались в скобках.
Но тогда бы было засилье скобок. Впрочем, кому что нравится. Я пишу END END потому что так чище смотрится. Но в конце строки всегда ставлю ;

Цитата:
- вместо ENDIF, ENDWHILE, ENDLOOP, ENDWITH один END - путаница при чтении исходника.
В конце процедуры тоже END, но с параметром - как это ест "простой" парсер?
Да вот ест.

Не вижу проблем, нормально. В крайнем случае пиши END(*IF*)

Цитата:
- В идентификаторах запрещены "_", поэтому переменные пишутся в CamelCase, но с маленькой буквы!
Исправлено в Component Pascal.
И в XDev. :)

Цитата:
- Строки определены на массивах, для этого пришлось ввести массив плавающей длины и функцию длины массива по любому измерению.
Что же плохого в динамических массивах?

Цитата:
С точки зрения скорости:
------------------------

- Разрешена рекурсия. Из-за этого компилятор не может оптимизировать локальные переменные, сделав их псевдоглобальными.
(Некоторые оптимизирующие компиляторы Си с большим трудом находят места, которые можно так оптимизировать,
для этого надо гарантировать, что указатель на эту функцию и вызывающие её никуда не передаётся
и что все её вызывающие функции не вызываются из этой функции и функций, которые она вызывает, в том числе в других модулях.)

- Символы в строках адресуются по номеру вместо бегунка.
Неэффективный подход с точки зрения скорости.
В Си для этого используются указатели типа char*.
Бегунок = {адрес, [длина слева], длина справа} и должен обновляться при обновлении строки.
Или компилятором должен контролироваться запрет обновления строки, пока бегунок не освобождён.
Конец строки определяется по состоянию "бегунок.длинасправа=0".

- Без GOTO трудно реализовать выборочное выполнение программы для контрольно-проверочных систем.
Единственный способ - препроцессор, который генерирует процедуру для каждой строчки кода. Это очень неэффективно.

- Строки NULL-terminated, то есть 1) нельзя хранить произвольные символы, 2) тормозная конкатенация.
Есть простой и эффективный метод: строка = {адрес, длина, [ссылки на бегунки]} (детали реализации должны быть скрыты от пользователя).
Всё зависит от того как именно ты интерпретируешь символы в строке. Если без NULL, то будет всё без NULL, вон в Оберон-07 уже он необязателен. Кстати, поверх таких строк можно делать структуры для более эффективной работы с фрагментами строк, я встречал такой код в системе ETH Oberon.

Цитата:
- Есть куча прагм, но ни среди них, ни в настройках компилятора нет отладочной компиляции (с ASSERT, контролем NaN и range check'ами).
В итоге на выходе получается программа, которая имеет range check (тормозная отладочная функция),
но при этом не контролирует переполнение в целочисленной арифметике и диапазоны входных данных.


С точки зрения операционных систем:
-----------------------------------

- В строках определено использование только символов ASCII! Т.е. русские буквы - это хак, потенциально несовместимый.
Исправлено в Component Pascal, хотя там не весь набор символов Unicode (для этого нужно 21 бит).

- Не предусмотрено ничего для атомарных операций и исключения гонок доступа к данным (мьютексы, транзакции...).
Исправлено в Ulm's Oberon Library.

- Не предусмотрена работа с байтовыми файлами.
Да ладно? Ещё как предусмотрена. И тип SYSTEM.BYTE есть в любой реализации Оберона. А в КП это просто BYTE.

Цитата:
Работа с ними через INTEGER машинно-специфична (разный порядок байтов).
Работа с ними через SHORTINT требует ручного преобразования типа в более широкий и коррекции знака.
Работа с ними через CHAR является ошибкой, т.к. CHAR в Обероне определён для 7-битной кодировки ASCII, а не для 8-битных байтов.
Исправлено в Component Pascal через SHORTCHAR.

- Нет интерфейса между задачами? (Во всяком случае, не нашёл)


С точки зрения встраиваемых систем:
------------------------------------

- В микроконтроллерах гарвардской архитектуры внутренняя (код и константы) и внешняя (переменные) память адресуются разными командами.
В Си для различения двух типов указателей используется слово static.
В Обероне не предусмотрено ничего, в итоге под эти микроконтроллеры программировать невозможно.

- Разрешена рекурсия. Компилятор даже не выдаёт предупреждение.
Рекурсия исключает использование на ряде микроконтроллеров и процессорах типа 6502.

- Из-за того, что строки - это массивы произвольной длины, даже для простейших программ требуется куча.

- Без GOTO нельзя реализовать protothreads.

- Не предусмотрена обработка прерываний (нет naked процедур).
Ты лучше посмотри как устроены ETH Oberon и A2. Половина твоих претензий отпадёт. Потому что всё там есть. Или может быть легко добавлено.

Цитата:
С точки зрения FPGA:
--------------------

- Разрешена рекурсия. Компилятор даже не выдаёт предупреждение.
Рекурсия исключает использование на FPGA.

- Не различаются процедуры и модули с состоянием и без состояния ("чистые").
Ср. язык Rust.
Чистые процедуры могут вызывать только чистые.
Чистые процедуры соответствуют линиям, процедуры с состоянием - модулям.

- Не различаются волатильные и неволатильные переменные.
Ср. язык Rust.
Неволатильные переменные надо определять прямо в блоке и больше не менять.
Волатильные переменные соответствуют регистрам, неволатильные - линиям.

- IF и CASE реализованы как последовательность действий, а не как вычисление результата.
В частности, не контролируется присваивание всех переменных и не определяются их значения по умолчанию: сохранить старое значение или поставить случайное (наиболее выгодное с точки зрения покрытия карты Карно).
IF в языке Rust возвращает значение, но это не всегда удобно (ср. VHDL и особенно Verilog).

- Не контролируется независимость итераций в FOR, поэтому их нельзя распараллелить.
Непараллельные циклы надо писать через WHILE или FOREACH.

- Не контролируется взаимозависимость действий в блоке (допустимы блоки типа a:=1;P(a);a:=2;P(a);).
Для таких блоков требуется стейт-машина и потеря производительности. Но предупреждение не выдаётся.
Стейт-машина должна использоваться только для циклов или явно описанной конструкции последовательного вызова.

- Активные объекты в Active Oberon передают управление без обмена данными. Возникает вопрос, как их тогда использовать?
Для сравнения, в языке Go с этим всё в порядке.

- Нельзя соединить активные объекты в сеть на этапе компиляции. Этого требует разработка на FPGA.
(Язык Go тоже страдает этим.)



Система Оберон (сужу по описаниям, поэтому везде вопросы):
===============

- Нет батников? Надо все команды исполнять руками?
А там каждый документ это потенциальный батник. ;)

Цитата:
- Нет защиты при исполнении команд? Можно неожиданно выполнить даже команду, написанную прозрачным цветом?

- Однозадачность (нельзя паковать архив и при этом что-то делать).
Ну зачем же. В винде 3.11 было ведь можно.

Цитата:
- Типичная ошибка - программа скомпилирована, но в память загружена старая версия (и это никак не определить).
Ручками выгрузить. Или "батником".

Цитата:
- В этой системе невозможно работать без мышки.

- Каким образом проводить совместную разработку по сети?

- Не предусмотрены каталоги модулей (типа rar/, где модули ppmd, arithcod, zlib, rarfile и т.п.)?



Какой язык я хотел бы увидеть (и я ищу его довольно давно):
1. Программа состоит из модулей согласно dataflow diagram. Цепь
составляется во время компиляции!
2. У модулей произвольное число входов и выходов (т.е. это не Actor
model).
3. Модули взаимодействуют атомарной передачей данных.
Реализация на Z80 вот: http://pastebin.ru/L2KulLbB
Реализация на FPGA должна включать запрос READY и линии DATA и SYNC.
Данные забираются по SYNC.
4. Последовательные конструкции явно определены.
5. Максимальная поддержка надёжных вычислений.
6. Исходники должны быть читабельными.


-- Best regards, Dmitry http://alonecoder.nedopc.com
Я считаю Оберон идеально читабельным языком, в этом смысле он даже лучше Паскаля — исходники на Обероне смотрятся хорошо даже без подсветки синтаксиса. А лепить скобочки на скобочках — пусть лепят, но это не к нам.

Вобщем, что сказать, ищешь — ищи. А мне нравится Оберон. Я умею исправлять его недостатки или же учусь этому. Оберон аскетичен. Любое чревоугодие языковых средств при всём его разновкусии рано или поздно выходит боком, любая переусложнённость несёт проблемы, явные и скрытые. И те, которые икнутся потом. Мне кажется, разумный программист со временем понимает какую-то необходимость самоограничения. И в этом смысле любой простой язык будет недостаточным для чего-то, но вполне пригодным для других целей. Ты вот обвинил Оберон в неподходящести для Z80, но это никак не мешает разрабатывать на Обероне для этого процессора. И Rust, и Go, и [впиши нужное] здесь абсолютно неприменимы. А по твоей ссылке я вообще нашёл какую-то Z80-ассемблерно-макросовскую муть, захотелось почему-то застрелиться. ;)

Так что бОльшая часть твоих претензий, если не все — исправимы. Если отойти от стандарта, добавить новые фичи, что, кстати, в контексте Оберона делается на порядки проще. Для сравнения попробуй протащить свои идеи языкоусовершенствования, например, в сообщество C#. Не-а. Там всё уже предусмотрено и запаковано. Оберон же — конструктор. За счёт чего его недостатки могут быть исправлены в новом диалекте, построенном путём уточнения уже имеющихся. Притом небольшими силами, например, маленького коллектива разработчиков (или даже одного человека). И я уже этим занимаюсь (в рамках проекта XDev), исходя конечно из своего понимания вопроса.

Уверен, что мнений и предложений (причём и не совпадающих, и взаимоисключаемых) по новому диалекту Оберона будет столько же, сколько и программистов, желающих высказаться на эту тему. И отнюдь не все из них будут полезны.


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ 1 сообщение ] 

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club