История изменений
Исправление X512, (текущая версия) :
Посмотрел я на Оберон…
Вы забыли главное преимущество: безопасность языка и наличие сборщика мусора. Все варианты Паскаля принципиально не сильно лучше C/C++, в них легко испортить память и сделать утечку памяти или double free. Есть 2 подхода обеспечения безопасности памяти: сборщик мусора как в Обероне и Go или контроль владения как в Rust. Rust слишком сложный, содержит недостатки и дыры в архитектуре и медленно компилируется, в нём нет нормальных модулей (динамическая загрузка, инициализаторы/финализаторы модулей, детерминированный порядок инициализации).
Где-то на уровне C++ (1983) и Standard ML (1984) это превосходство заканчивается, потому что они привносят высокий уровень полиморфизма с малыми накладными расходами.
В Обероне dynamic_cast эффективнее, чем в C++. Типичной практикой является обработка сообщений через проверку расширений типов:
PROCEDURE (c: Controller) HandleCtrlMsg* (
f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View
), NEW, EXTENSIBLE;
BEGIN
focus := c.focus;
WITH msg: Controllers.PollCursorMsg DO
PollCursor(c, f, msg, focus)
| msg: Controllers.PollOpsMsg DO
PollOps(c, f, msg, focus)
| msg: PollFocusMsg DO
IF msg.all OR (c.opts * modeOpts # mask) & (c.focus # NIL) THEN msg.ctrl := c END
| msg: Controllers.TrackMsg DO
Track(c, f, msg, focus)
| msg: Controllers.EditMsg DO
Edit(c, f, msg, focus)
| msg: Controllers.TransferMessage DO
Transfer(c, f, msg, focus)
| msg: Controllers.SelectMsg DO
IF focus = NIL THEN c.SelectAll(msg.set) END
| msg: Controllers.TickMsg DO
FadeMarks(c, show);
CheckMaskFocus(c, f, focus)
| msg: Controllers.MarkMsg DO
c.bVis := msg.show;
c.Mark(f, f.l, f.t, f.r, f.b, msg.show)
| msg: Controllers.ReplaceViewMsg DO
ReplaceView(c, msg.old, msg.new)
| msg: Properties.CollectMsg DO
IF focus = NIL THEN
msg.poll.prop := ThisProp(c, direct)
END
| msg: Properties.EmitMsg DO
IF focus = NIL THEN
SetProp(c, msg.set.old, msg.set.prop, direct)
END
ELSE
END
END HandleCtrlMsg;
В C++ аналогичный код будет страшно выглядеть и медленнее работать.
а в 1991 году выпускается Oberon-2, в который безальтернативно прошиты числа и строки без намека на перспективу.
Не понял что вы имеете в виду.
без намека на перспективу
В Component Pascal - наследнике Oberon 2 есть 4 числовых типа (BYTE, SHORTINT, INTEGER, LONGINT, 1, 2, 4 и 8 байт соответственно), а также 2 символьных типа SHORTCHAR (1 байт), CHAR (2 байта). Язык ничего не знает о кодировке кроме того, что во встроенных строковых операциях массив из символов должен оканчиваться на нулевой символ. Обработка кодировок выполняется в библиотеках.
Писать системщину на Oberon-2 можно, как и на Си, как и на паскале — но это тупо неэффективно.
Очень даже эффективно: не надо бороться с порчей памяти и нарушением консистентности указателей. Любой сколь-нибудь сложный код на Си/C++ полон багов и уязвимостей, позволяющих осуществить удалённое выполнение кода.
Исходная версия X512, :
Посмотрел я на Оберон…
Вы забыли главное преимущество: безопасность языка и наличие сборщика мусора. Все варианты Паскаля принципиально не сильно лучше C/C++, в них легко испортить память и сделать утечку памяти или double free. Есть 2 подхода обеспечения безопасности памяти: сборщик мусора как в Обероне и Go или контроль владения как в Rust.
Где-то на уровне C++ (1983) и Standard ML (1984) это превосходство заканчивается, потому что они привносят высокий уровень полиморфизма с малыми накладными расходами.
В Обероне dynamic_cast эффективнее, чем в C++. Типичной практикой является обработка сообщений через проверку расширений типов:
PROCEDURE (c: Controller) HandleCtrlMsg* (
f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View
), NEW, EXTENSIBLE;
BEGIN
focus := c.focus;
WITH msg: Controllers.PollCursorMsg DO
PollCursor(c, f, msg, focus)
| msg: Controllers.PollOpsMsg DO
PollOps(c, f, msg, focus)
| msg: PollFocusMsg DO
IF msg.all OR (c.opts * modeOpts # mask) & (c.focus # NIL) THEN msg.ctrl := c END
| msg: Controllers.TrackMsg DO
Track(c, f, msg, focus)
| msg: Controllers.EditMsg DO
Edit(c, f, msg, focus)
| msg: Controllers.TransferMessage DO
Transfer(c, f, msg, focus)
| msg: Controllers.SelectMsg DO
IF focus = NIL THEN c.SelectAll(msg.set) END
| msg: Controllers.TickMsg DO
FadeMarks(c, show);
CheckMaskFocus(c, f, focus)
| msg: Controllers.MarkMsg DO
c.bVis := msg.show;
c.Mark(f, f.l, f.t, f.r, f.b, msg.show)
| msg: Controllers.ReplaceViewMsg DO
ReplaceView(c, msg.old, msg.new)
| msg: Properties.CollectMsg DO
IF focus = NIL THEN
msg.poll.prop := ThisProp(c, direct)
END
| msg: Properties.EmitMsg DO
IF focus = NIL THEN
SetProp(c, msg.set.old, msg.set.prop, direct)
END
ELSE
END
END HandleCtrlMsg;
В C++ аналогичный код будет страшно выглядеть и медленнее работать.
а в 1991 году выпускается Oberon-2, в который безальтернативно прошиты числа и строки без намека на перспективу.
Не понял что вы имеете в виду.
без намека на перспективу
В Component Pascal - наследнике Oberon 2 есть 4 числовых типа (BYTE, SHORTINT, INTEGER, LONGINT, 1, 2, 4 и 8 байт соответственно), а также 2 символьных типа SHORTCHAR (1 байт), CHAR (2 байта). Язык ничего не знает о кодировке кроме того, что во встроенных строковых операциях массив из символов должен оканчиваться на нулевой символ. Обработка кодировок выполняется в библиотеках.
Писать системщину на Oberon-2 можно, как и на Си, как и на паскале — но это тупо неэффективно.
Очень даже эффективно: не надо бороться с порчей памяти и нарушением консистентности указателей. Любой сколь-нибудь сложный код на Си/C++ полон багов и уязвимостей, позволяющих осуществить удалённое выполнение кода.