OberonCore
https://forum.oberoncore.ru/

Ограничивающий инструментарий, стимулирующий мышление?
https://forum.oberoncore.ru/viewtopic.php?f=6&t=2284
Страница 1 из 2

Автор:  Евгений Темиргалеев [ Вторник, 26 Январь, 2010 21:30 ]
Заголовок сообщения:  Ограничивающий инструментарий, стимулирующий мышление?

Лозунги об ограничении свободы выражения программерской мысли Виртовскими языками известны.

Три вида ошибок (по учеб. Кушниренко, изложение произв.):
1) времени компиляции = запись алгоритма на ЯП забракована
2) времени выполнения = аварийный останов исполнителя
3) логические = исполнитель работает по программе, но цель алгоритма не достигается

Перечислены по степени сложности обнаружения. Очевидно, что перевод ошибок в меньший по номеру класс повышает надёжность.

Конкретика (иллюстрирующая направление движения): функции "с результатом" и его указание (возврат). Ошибка: функция без результата --- в какой-то из веток возврат результата упустили.
  • (например) Си: логическая ошибка
  • Оберон: ошибка времени выполнения (останов в конце тела функции)
  • Оберон-07: синтаксическая ошибка. (RETURN в Оберон-07 просто слово в конце процедуры-функции в отличие от Оберон, где был оператором)

Свобода ограничена. Теперь просто так с 20-ю выходами функцию не склепать. Приходится подумать. Но и серьёзность ошибки "уменьшилась". Как минимум -- равноценный размен.

Попробую (критикуйте, то что выше - тоже) немного аналогии:
  • инструментарий требующий повышенной мысленной активности -> "закаляющий" мышление
  • не "сковывающий" инструментарий, позволяющий писать как вздумается и, возможно, предупреждающий (в 100% случаях предупреждения не спасут, т.к. думать пока дано и всё равно придётся только человеку) -> ...

  • Регулярные физ. упражнения и пр. требуют преодоление себя, ограничивают свободу времяпрепровождения -> закаляют здоровье
  • Медикаменты и в частн. антибиотики по каждому поводу позволят жить свободно и будут поддерживать "здоровье=не болезнь" (но организм привыкает) -> ...

Автор:  Валерий Лаптев [ Вторник, 26 Январь, 2010 22:52 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

1. Нифига Оберон не ограничивает. Ибо формально эквивалентен все той же машине Тьюринга, что и все остальные.
2. КП+ББ - это сильно лучше для начинающих программеров, чем Додиез+Студия (и аналогичные).

Автор:  Info21 [ Вторник, 26 Январь, 2010 23:23 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Евгений Темиргалеев писал(а):
Лозунги об ограничении свободы выражения программерской мысли Виртовскими языками известны. ...
Полезное рассуждение.

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

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

Ну это так, с ходу. Кое-что другого плана можно сказать, но ... потом. Нужно отдохнуть.

Автор:  Axcel [ Среда, 27 Январь, 2010 10:09 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Единственно, мне кажется, что в своих рассуждениях Евгений не учел "нелинейность" степени опасности. Ошибки 1 и 2 все таки где-то рядом. Во всяком случае при охранительном стиле. А вот логические это да.

Автор:  Евгений Темиргалеев [ Четверг, 28 Январь, 2010 09:42 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Axcel писал(а):
в своих рассуждениях Евгений не учел "нелинейность" степени опасности
Даже не думал... Основная мысль - соотнести изменения в языке с переводом части ошибок одного вида в другой, менее серьезный.

Вторая мысль: навязываемые языком ограничения в итоге принуждают применять "Divide et impera" там, где без ограничений себя нужно заставлять самому. При постоянном примении навык тренируется и начинаешь применять на автомате. Пример: viewtopic.php?f=6&t=2290

Автор:  Евгений Темиргалеев [ Четверг, 28 Январь, 2010 10:18 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Можно ли сюда отнести изменения CASE?

(1) (например, Си, Делфи) switch/case - другой способ записи if (синт. сахар). Вариант "Иначе" по-умолчанию пустой
(2) Оберон - другой способ записи if (синт. сахар). Вариант "Иначе" обязателен.
(3) Оберон-7 - особый случай: сначала нужно выполнить классификацию с отображением на 0..n-1, а затем обработать "ситуацию" согласно её классу. Последнее эффективно реализуется урезанным CASE: метки только целые 0..n-1, вариант "Иначе" отсутствует.

(1)-(2) по первой мысли.
(2)-(3) по второй.

См. разницу в примерах (+ оставлен синт. CASE):
The Programming Language Oberon (Revision 1. 10. 90) писал(а):
9.4. If statements
...
Example:
Код:
          IF (ch >= "A") & (ch <= "Z") THEN ReadIdentifier
          ELSIF (ch >= "0") & (ch <= "9") THEN ReadNumber
          ELSIF ch = 22X THEN ReadString
          END
9.5. Case statements
...
Код:
    CaseStatement      =  CASE expression OF case {"|" case} [ELSE StatementSequence] END.
    Case               =  [CaseLabelList ":" StatementSequence].
    CaseLabelList      =  CaseLabels {"," CaseLabels}.
    CaseLabels         =  ConstExpression [".." ConstExpression].
Example:
Код:
CASE ch OF
    "A" .. "Z":  ReadIdentifier
   | "0" .. "9": ReadNumber
   | 22X :       ReadString
ELSE             SpecialCharacter
END

The Programming Language Oberon (Revision 1.11.2008) писал(а):
9.4. If statements
...
Example:
Код:
          IF (ch >= "A") & (ch <= "Z") THEN ReadIdentifier
          ELSIF (ch >= "0") & (ch <= "9") THEN ReadNumber
          ELSIF ch = 22X THEN ReadString
          END
9.5. Case statements
...
Код:
   CaseStatement =      CASE expression OF case {"|" case} END.
   case            =    [CaseLabelList ":" StatementSequence].
   CaseLabelList =      LabelRange {"," LabelRange}.
   LabelRange      =    label [“..” label].
   label           =    integer | ident.
Example:
Код:
       CASE k OF
            0: x := x + y
          | 1: x := x − y
          | 2: x := x * y
          | 3: x := x / y
       END


Автор:  Axcel [ Четверг, 28 Январь, 2010 10:39 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

В принципе, по "теории" возражений нет, но все же, чисто интуитивно, Оберон 2 - КП ближе к "золотой середине". Какой-то "люфт" все-таки должен быть.
Все-таки, мне кажется, дополнительные ограничения Оберон -07 идут от специфики сферы применения - встроенные системы.
Кстати когда Терехов использовал Алгол-68 для встроенки (путем кросстрансляции), то эти подмножества алгола сильно смахивали на Оберон-07. Но потом сделали процессор "Самсон". И насколько я знаю, одним из стимулов его создания - возможность использования полного Алгола-68.

Автор:  Александр Шостак [ Суббота, 30 Январь, 2010 05:36 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Простите, а деградация с современного строкового типа "со сборкой мусора" и присвоением по ссылке STRING (делфи) возврат к pchar-ам с их недостатками и ручному выделению памяти под "массив символов" или допотопное использование константных буферов - это тоже ограничение, снижающее уровень ошибок?

Цитата:
Теперь просто так с 20-ю выходами функцию не склепать.

Мне одному приходит мысль: LOOP...IF...EXIT..IF..EXIT.. END в качестве обёртки для функции? )
Мой личный скромный опыт программирования в таком стиле не дал положительных результатов. В целом хочется стремиться к идеальному программированию, но, возможно, не все рамки оправдывают свои ожидания.

Автор:  Axcel [ Суббота, 30 Январь, 2010 10:18 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Berserker писал(а):
Простите, а деградация с современного строкового типа "со сборкой мусора" и присвоением по ссылке STRING (делфи) возврат к pchar-ам с их недостатками и ручному выделению памяти под "массив символов" или допотопное использование константных буферов - это тоже ограничение, снижающее уровень ошибок?

По поводу строк: если я правильно понимаю, то аналог string Delphi это текстовая модель в ББ, а строки на основе array of char соответствют старым паскалевским строкам. Это очень грубое сопоставление, но по моему где-то так.
Т.е. это не ограничение, а иное перераспределение функциональности.

Автор:  Илья Ермаков [ Суббота, 30 Январь, 2010 13:03 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Именно так.

TextModels.Model. Или иногда, если уровнем пониже, Files.File в памяти.

Очевидно же, что столько вариаций реализации может быть, что средство должно быть БИБЛИОТЕЧНЫМ.
Вот нужен УТФ-8, и что? В язык utf8-string вводить?

Автор:  Александр Шостак [ Суббота, 30 Январь, 2010 14:47 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Цитата:
Очевидно же, что столько вариаций реализации может быть, что средство должно быть БИБЛИОТЕЧНЫМ.
Вот нужен УТФ-8, и что? В язык utf8-string вводить?

Всего два типа нужно стандартных: AnsiString и UnicodeString (SHORTCHAR, CHAR). Экзотику можно реализовать и самому. Но строки должны быть не зависимы от каких-то терминирующих символов (грабли СИ) и естественно применяться в выражениях:

S1:=S2;
S1:=S2+'World';
IF S3 = 'Hello' THEN...

А для UTF-8 можно и класс писать с Assign, Compare и т.д.
Бесспорно, реализаций может может быть и много, но те, что нужны для мейнстрима, не так уж многочисленны. В частности это обычный ASCII и двухбайтовый юникод. Ввели же тип CHAR, который с UTF-8 не дружит (по причине переменной длины последнего).

Нет, правда. При том, что творения Вирта весьма уважаю и изменения часто приветствую, считаю,что строки должны обрабатываться на уровне компилятора (нативно).

Автор:  Илья Ермаков [ Суббота, 30 Январь, 2010 15:08 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Berserker писал(а):
Бесспорно, реализаций может может быть и много, но те, что нужны для мейнстрима, не так уж многочисленны.


Да. Но если сфера применения языка шире, чем "нужна для мейнстрима", то прошивать в него это не следует.
У Оберона одна из приоритетных ниш - системное программирование ("современный Си"). В инструменте этого класса засорять язык предложенными Вами типами - как зайцу пятая нога. Нет, ну правда. Мы много работаем именно в этой нише - и видеть в языке эти типы (и уж тем более использовать их) очень не хочется.
Кроме причин концептуальных, причина техническая - эти типы будут скрывать в себе специфическое управление памятью. К прозрачности работы с памятью мы, например, шли долго и упорно - и для обычного КП схемы такой работы отточили. И тут бац - засорять язык каким-то "запаянным ящиком"?

Прочувствуйте эту аргументацию, тогда будет ясно, почему такая осторожность в плане добавления вроде бы неопасного "комфорта".

Аргумент про "ожирение" компилятора известен; но если это не убеждает, то вспомним ещё и про ожирение рантайма. Явно прикладная, частная логика должна быть тогда частью базовой системы времени выполнения. Мне, например, это совершенно не нужно, но я буду таскать эту "строковую библиотеку" прямо в Kernel?

Автор:  Александр Шостак [ Суббота, 30 Январь, 2010 15:35 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Илья, всё это верно, но хотелось бы кое-что уточнить:
Цитата:
эти типы будут скрывать в себе специфическое управление памятью

Сборка мусора по умолчанию закреплена за Обероном. Если объект уходит из поля видимости, его удаляют. Присвоение объектов происходит по ссылке.
Тот же стандартный делфийский AnsiString (до дельфи 2009) имеет следующий формат:
Код:
TYPE
STRING = ^TString.Data;

TString = RECORD
  RefCount: INTEGER;
  Len: INTEGER;
  Data: ARRAY Len OF CHAR;
  Null: CHAR = #0;
END;

Что мешает внутренне работать со строкой как с обычным объектом? Менеджер памяти так или иначе будет присутствовать. Просто во время компиляции "+" заменится на TString.Add, ":=" на TString.Assign и т.д.

Если я в чём-то ошибаюсь, просветите.

Автор:  Илья Ермаков [ Суббота, 30 Январь, 2010 16:29 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Мда? А как в Дельфе дешёвое удлиннение строки происходит? Я думал, там блочность сделана, нет?

Тогда вопрос только в пришлёпке к компилятору. Но вопрос тонкий. Видите, в КП строковые операции (которых нет в Обероне-2) введены, но получилось как раз мутное место в языке, с этим $. Фактически, вопрос в том, чтобы удобно сочетать литералы и переменные в местах ввода-вывода в программе. Как это сделать без спец. типа в языке, интересно..

Автор:  Александр Шостак [ Суббота, 30 Январь, 2010 17:57 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

В Делфи удлинение строки не дешёвое, а обычными средствами менеджера памяти производится (GetMem, FreeMem, ReallocMem). Фактически, в Обероне для Ansi-строк эквивалент:

TYPE
STRING = POINTER TO ARRAY OF SHORT CHAR;

Рассмотрим особенности Делфи строк:
1) Получение Length через поле вместо strlen в pchar через сканироdание строки.
Оберон: LEN.
2) Строки динамичны и занимают ровно столько места, сколько в них символов, не считая накладных расходов (в Делфи до 2009 версии это 8 байт на длину строки и кол-во ссылок на неё + расходы на блок памяти со стороны менеджера).
В Обероне все нужные операции присутствуют для массивов. Массивы динамичны.
3) S1:=S2 вызывает не копирование, а присвоение по ссылке. Для копирования в Делфи есть операция UniqueString, которая убеждается, что на текущий массив символов только одна ссылка (если более, выделяется новый блок и туда копируются данные). В Обероне присвоение объектов тоже по ссылкам + сборка мусора универсальная (в Делфи только для строк). Реализация аналога UniqueString - несколько строк.

Так что фактически это в Делфи было серьёзное нововведение с автоматическим контролем памяти, а Оберон мог бы поддерживать строки с лёгкостью. Хотя бы указанные два типа, покрывающие 90% нужд. А для utf-8 люди и сами напишут конвертеры.

Исключительно имхо.

Автор:  Илья Ермаков [ Суббота, 30 Январь, 2010 18:08 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Тут учитывайте, что большинство строк в программе на Обероне (вся мелочь обыденная) оказываются вообще не объекты, а массивами на стеке, передаваемые через VAR-параметры. И манипуляции с ними идут без нагрузки на динамику.

Автор:  Galkov [ Суббота, 30 Январь, 2010 18:25 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

В принципе, я слегка шокирован определением AnsiString в Дельфи. Не знаю, не знаю... Хотя 2009-м и не пользовался.
Если в структуре допускаются массивы переменной длины, то я серьезно отстал отжизни.
И вообще-то, там точно есть еще одно поле - RefCount. Но и у Len, и у RefCount - отрицательные смещения

Автор:  Александр Шостак [ Суббота, 30 Январь, 2010 19:26 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Это формат записи, описанный мной с помощью языковых конструкций. Я так и форматы файлов делаю в документации :) Реально используется строка как массив символов, начиная с 1.
Сама STRING - указатель на первый символ. По смещению -4 находится положительный Length, -8 - кол-во ссылок. Для констант оно =-1, что означает запрет на освобождение этого блока, даже если ссылок на него больше нет. Но повторюсь, это технические вещи, о которых вовсе знать не нужно. В Обероне RefCount не нужен, так как своя сборка мусора, а Length-поле у всех массивов динамических есть.

Автор:  Евгений Темиргалеев [ Суббота, 30 Январь, 2010 23:15 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление

Berserker писал(а):
Простите, а деградация с современного строкового типа "со сборкой мусора" и присвоением по ссылке STRING (делфи) возврат к pchar-ам с их недостатками и ручному выделению памяти под "массив символов" или допотопное использование константных буферов - это тоже ограничение, снижающее уровень ошибок?
Для всех (вручную созданных) динамич. объектов действует сборка мусора. И контроль индексов для всех массивов.
Berserker писал(а):
Цитата:
Теперь просто так с 20-ю выходами функцию не склепать.

Мне одному приходит мысль: LOOP...IF...EXIT..IF..EXIT.. END в качестве обёртки для функции? )
Меня такая мысль теперь обходит стороной. А в Оберон-07 вообще нет LOOP...

Автор:  Евгений Темиргалеев [ Четверг, 07 Июнь, 2018 23:25 ]
Заголовок сообщения:  Re: Ограничивающий инструментарий, стимулирующий мышление?

Была где-то у Александра Ильина отдельная тема, где он циклы переписывал, на сразу не нашел, а сюда тоже пойдет.

Ковыряюсь в Zlib (который из A2) и не знаю, что думать. Вирта на них не было? Сперли сишную реализацию?
Код:
   (** close writer **)
   PROCEDURE Close* (VAR w: Writer);
   VAR
      done: BOOLEAN;
      len: INTEGER;
   BEGIN
      ASSERT(w.s.in.avail = 0, 110);
      done := FALSE;
      LOOP
         len := BufSize - w.s.out.avail;
         IF len # 0 THEN
            w.r.file.WriteBytes(w.r, w.out^, 0, len);
            ZlibBuffers.Rewrite(w.s.out)
         END;
         IF done THEN EXIT END;
         ZlibDeflate.Deflate(w.s, ZlibDeflate.Finish);
         IF (len = 0) & (w.s.res = BufError) THEN
            w.res := Ok
         ELSE
            w.res := w.s.res
         END;
         done := (w.s.out.avail # 0) OR (w.res = StreamEnd);
         IF (w.res # Ok) & (w.res # StreamEnd) THEN EXIT END
      END;
      ZlibDeflate.Close(w.s);
      w.res := w.s.res
   END Close;

Поковыряешься в таком, и в очередной раз убеждаешься, что пространства для GOTO-like маневров оставлять никак нельзя. Что Вирт и сделал к Оберону-07 (RETURN и цикл Дейкстры).
Код:
   PROCEDURE Close* (w: Writer);
      VAR   len: INTEGER;
   BEGIN
      ASSERT(w.s.open, 30);
      ASSERT(w.s.res = ZlibDeflate.Ok, 100);
      LOOP IF w.s.out.avail = 0 THEN
         w.rider.WriteBytes(w.out, 0, BufSize);
         ZlibBuffers.Rewrite(w.s.out)
      ELSIF (*~(w.s.out.avail = 0) &*) (w.s.res = ZlibDeflate.Ok) THEN
         ZlibDeflate.Deflate(w.s,  ZlibDeflate.Finish);
         ASSERT((w.s.res = ZlibDeflate.Ok) OR (w.s.res = ZlibDeflate.StreamEnd), 101)
      ELSE EXIT END END;
      ASSERT(w.s.res = ZlibDeflate.StreamEnd);
      len := BufSize - w.s.out.avail;
      IF 0 < len THEN w.rider.WriteBytes(w.out, 0, len) END;
      ZlibDeflate.Close(w.s); ASSERT(~w.s.open & (w.s.res = ZlibDeflate.Ok));
      w.rider := NIL
   END Close;

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/