@kisybi read-only
Пользователь
25 мая 2015 в 17:52

Разработка → Проект «Оберон 2013» из песочницы

Мне тут коллеги одну полезную нагрузочку дали. Я быстренько с вами проведу беседу о вреде избирательной слепоты, поскольку с нею, проклятою, в нашей индустрии не совсем благополучно. Значит, перво-наперво, прежде чем с нею бороться, с нашим общим врагом – слепотой проклятой, давайте мы как следует обсудим и изучим примеры того, что не видит сообщество, чтобы наверняка знать, как оно может быть на самом деле.

История


Итак, в 1986-89 гг. Никлаус Вирт с коллегами разработали первую версию системы «Оберон», машину, компилятор языка Оберон и операционную систему System Oberon, которая обладала графическим интерфейсом пользователя, расширенными концепциями использования текста в интерфейсе и в целом являла собой материальное доказательство применимости концепций Н. Вирта. Эта операционная система положила начало эволюционной ветке продуктов и языков с непростой судьбой, каждый из которых достоин отдельной статьи.



Через почти 30 лет, наблюдая ситуацию неконтролируемого усложнения продуктов в ИТ, Н. Вирт решил вновь преподнести людям свое видение того, как строить маленькие, мощные и надежные системы. Сама работа автора будет служить доказательством того, что такие системы существуют и работают.

Все течет, все меняется


Как оказалось, та модель процессора, которая использовалась в первоначальной системе, уже пропала с рынка. Как и его архитектурные аналоги. Вместо использования готовых коммерческих решений, Н. Вирт решил дополнить свою систему еще одним компонентом — своим вариантом языка для программирования FPGA, который был назван Lola. Следовательно, процессор для новой машины был разработан самим Виртом на базе RISC. Его мы рассмотрим в отдельном разделе статьи. Вся система работала на девборде Xilinx Spartan-3 с 1 МБ памяти и 25 МГц процессором.

То есть, мы имеем проект, в котором реализован полный цикл разработки вычислительного комплекса from scratch, и реализованы все доступные инженеру/программисту этапы этого проекта.

Процессор


RISC-архитектура отличается особой последовательностью работы процессора с данными. Все вычисляющие инструкции процессора работают с данными, расположенными в регистрах, а данные в память/из памяти переносятся особыми инструкциями процессора, SAVE и LOAD. Таким образом достигается монотонность работы, когда количество тактов на одну инструкцию предсказуемо, и зачастую большинство инструкций умещается в один такт. Особенностью процессора Вирта так же является параллельная работа конвейера по записи данных в память, правда, для этого пришлось снизить частоту получившегося процессора в два раза, с 50 до 25 МГц.

Система команд опирается на 32-х битное слово, в котором старшие четыре бита отданы под определение формата команды. Формат команды определяет класс операции, количество операндов и их местоположение.
Команды АЛУ определяют набор арифметических и логических операций с тремя регистрами или с двумя регистрами и константой. Команды АЛУ оставляют после себя дополнительные значения знака результата в специальных однобитных регистрах.
Команды памяти определяют инструкции загрузки в память и чтения из памяти одного слова или одного байта в регистр.
Команды управления потоком исполнения позволяют управлять значением регистра PC, описывать условные и безусловные переходы с опорой на значение регистра или константы.

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

Выглядит это примерно так:



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

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

Система


Основная цель ОС состоит в том, чтобы предоставить пользователю и программисту определенный уровень абстракции. Устройства ввода/вывода, устройства хранения и интерфейсы взаимодействия с этими устройствами, а так же ограничения железа. Гибкость абстракций, выбранных в системе Оберон позволяет бесшовно запускать ее в качестве отдельной программы на различных софтверных платформах/ОС, при этом эмулирован может быть уровень процессора или же уровень программных реализаций абстракций.

Язык


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

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

Модульность


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

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

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

Базовая метаинформация


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

Динамическая модульность


Необходимость такой передачи управления вытекает из необходимости наличия в ОС не просто модульности, а динамической модульности, так как ОС это инфраструктурный продукт, и сама по себе не имеет конкретный применений у пользователей, пользователи должны иметь возможность в процессе работы программы загрузить в память нужные им модули. При этом у модуля есть точка входа и тело, которое выполнится один раз, при этом важным моментом является тот факт, что модуль останется загруженным в память, и может предоставлять свои типы и процедуры для дальнейшей работы других модулей. Так вот, для того чтобы в процессе работы ОС управление можно было передавать уже загруженным модулям, а заодно и загружать модули и выполнять их процедуры, понадобилось иметь возможность выполнять процедуры по имени. Конечно, у данной фичи есть невообразимо сложные аналоги в мейнстриме, но на данный момент такой фичи достаточно. Все равно, она реализуется библиотечно, а в язык добавлять ничего не надо.

Сборка мусора


В операционной системе Оберон сборка мусора выполняется на уровне ядра ОС, которое управляет размещением динамических объектов в куче. Для компонентной среды сборщик мусора это очевидная необходимость, так как компонент, предоставляющий динамические объекты клиентам не может решать, когда их удалить из памяти.
Вот цитата самого Вирта по этому поводу:
The Oberon System does not provide an explicit deallocation procedure allowing the programmer to signal that a variable will no longer be referenced. The first reason for this omission is that usually a programmer would not know when to call for deallocation. And secondly, this «hint» could
not be taken as trustworthy. An erroneous deallocation, i.e. one occurring when there still exist references to the object in question, could lead to a multiple allocation of the same space with disastrous consequences. Hence, it appears wise to fully rely on system management to determine which areas of the store are truly reusable.


Итак, когда требования к языку и среде его исполнения (она же ОС, она же рантайм) определены, можно приступить к написанию кода. По сути, ОС по набору функций может быть описана всего несколькими модулями. Остальные функции могут взять на себя сторонние компоненты. Компилятор не обязан быть частью ОС, но так как без него не создать ни единой команды процессору, мы рассмотрим его в первую очередь.

Компилятор


Язык программирования — это бесконечный набор символов из набора ключевых слов, которые связаны ограниченным набором выражений, составляющих синтаксис. Каждое выражение представляет собой синтаксическую конструкцию с правилами ее написания. Смысл написанного определяется набором семантических правил, сопоставленных с каждой конструкцией.

Оберон


Язык Оберон с самой первой редакции был задуман как язык, не имеющий ничего лишнего в своем составе. Для решения очевидных проблем, связанных с минимализмом языка, была предложена концепция модульности. Таким образом, предполагалось, что наборы модулей разной функциональности могут эффективно заменить собой экспансивный рост возможностей самого языка. Описание языка занимает меньше 20 страниц, компилятор реализуется довольно быстро, в целом, Вирт подчеркивал, что у него получился отличный язык для обучения (более лучший, чем Pascal). Конечно, злые языки тут же подхватили эту фразу и носятся с ней, утверждая, что Оберон хорош только для обучения. Что ж, клевету легче посеять, чем искоренить.

Как можно видеть в этом проекте, Оберон и его концепции подходят для реализации кода на любом уровне, низкоуровневый, middleware, высокоуровневые редакторы схем, почтовики и т.д. Все эти приложения Вирт реализовал как proof of concept в своей ОС.

Пример низкоуровневого кода на языке Оберон.
Модуль Kernel, сборщик мусора. github.com/ilovb/ProjectOberon2013/blob/master/Sources/Kernel.Mod#L82
(* ---------- Garbage collector ----------*)

  PROCEDURE Mark*(pref: LONGINT);
    VAR pvadr, offadr, offset, tag, p, q, r: LONGINT;
  BEGIN SYSTEM.GET(pref, pvadr); (*pointers < heapOrg considered NIL*)
    WHILE pvadr # 0 DO
      SYSTEM.GET(pvadr, p); SYSTEM.GET(p-4, offadr);
      IF (p >= heapOrg) & (offadr = 0) THEN q := p;   (*mark elements in data structure with root p*)
        REPEAT SYSTEM.GET(p-4, offadr);
          IF offadr = 0 THEN SYSTEM.GET(p-8, tag); offadr := tag + 16 ELSE INC(offadr, 4) END ;
          SYSTEM.PUT(p-4, offadr); SYSTEM.GET(offadr, offset);
          IF offset # -1 THEN (*down*)
            SYSTEM.GET(p+offset, r); SYSTEM.GET(r-4, offadr);
            IF (r >= heapOrg) & (offadr = 0) THEN SYSTEM.PUT(p+offset, q); q := p; p := r END
          ELSE (*up*) SYSTEM.GET(q-4, offadr); SYSTEM.GET(offadr, offset);
            IF p # q THEN SYSTEM.GET(q+offset, r); SYSTEM.PUT(q+offset, p); p := q; q := r END
          END
        UNTIL (p = q) & (offset = -1)
      END ;
      INC(pref, 4); SYSTEM.GET(pref, pvadr)
    END
  END Mark;

  PROCEDURE Scan*;
    VAR p, q, mark, tag, size: LONGINT;
  BEGIN p := heapOrg;
    REPEAT SYSTEM.GET(p+4, mark); q := p;
      WHILE mark = 0 DO
        SYSTEM.GET(p, tag); SYSTEM.GET(tag, size); INC(p, size); SYSTEM.GET(p+4, mark)
      END ;
      size := p - q; DEC(allocated, size);  (*size of free block*)
      IF size > 0 THEN
        IF size MOD 64 # 0 THEN
          SYSTEM.PUT(q, 32); SYSTEM.PUT(q+4, -1); SYSTEM.PUT(q+8, list3); list3 := q; INC(q, 32); DEC(size, 32)
        END ;
        IF size MOD 128 # 0 THEN
          SYSTEM.PUT(q, 64); SYSTEM.PUT(q+4, -1); SYSTEM.PUT(q+8, list2); list2 := q; INC(q, 64); DEC(size, 64)
        END ;
        IF size MOD 256 # 0 THEN
          SYSTEM.PUT(q, 128); SYSTEM.PUT(q+4, -1); SYSTEM.PUT(q+8,  list1); list1 := q; INC(q, 128); DEC(size, 128)
        END ;
        IF size > 0 THEN
          SYSTEM.PUT(q, size); SYSTEM.PUT(q+4, -1); SYSTEM.PUT(q+8, list0); list0 := q; INC(q, size)
        END
      END ;
      IF mark > 0 THEN SYSTEM.GET(p, tag); SYSTEM.GET(tag, size); SYSTEM.PUT(p+4, 0); INC(p, size)
      ELSE (*free*) SYSTEM.GET(p, size); INC(p, size)
      END
    UNTIL p >= heapLim
  END Scan;


Пример высокоуровневого кода
Модуль Texts, сохранение текстовых файлов редактором. github.com/ilovb/ProjectOberon2013/blob/master/Sources/Texts.Mod#L127
  PROCEDURE Store* (VAR W: Files.Rider; T: Text);
    VAR p, q: Piece;
      R: Files.Rider;
      off, rlen, pos: LONGINT;
      N, n: INTEGER;
      ch: CHAR;
      Dict: ARRAY 32, 32 OF CHAR;
  BEGIN pos := Files.Pos(W); Files.WriteInt(W, 0); (*place holder*)
    N := 1; p := T.trailer.next;
    WHILE p # T.trailer DO
      rlen := p.len; q := p.next;
      WHILE (q # T.trailer) & (q.fnt = p.fnt) & (q.col = p.col) & (q.voff = p.voff) DO
        rlen := rlen + q.len; q := q.next
      END;
      Dict[N] := p.fnt.name;
      n := 1;
      WHILE Dict[n] # p.fnt.name DO INC(n) END;
      Files.WriteByte(W, n);
      IF n = N THEN Files.WriteString(W, p.fnt.name); INC(N) END;
      Files.WriteByte(W, p.col); Files.WriteByte(W, p.voff); Files.WriteInt(W, rlen);
      p := q
    END;
    Files.WriteByte(W, 0); Files.WriteInt(W, T.len);
    off := Files.Pos(W); p := T.trailer.next;
    WHILE p # T.trailer DO
      rlen := p.len; Files.Set(R, p.f, p.off);
      WHILE rlen > 0 DO Files.Read(R, ch); Files.Write(W, ch); DEC(rlen) END ;
      p := p.next
    END ;
    Files.Set(W, Files.Base(W), pos); Files.WriteInt(W, off); (*fixup*)
    T.changed := FALSE;
    IF T.notify # NIL THEN T.notify(T, unmark, 0, 0) END
  END Store;


Язык послужил прямым предком для языка параллельного программирования (Active Oberon), различных модификаций языка Оберон под другие среды исполнения (Component Pascal, Zonnon), был реализован на нескольких платформах (JVM, CLR, JS), послужил прообразом языка Java. Сама система Оберон послужила прообразом для проекта Microsoft Singularity. Такое заимствование нельзя назвать однозначно негативным фактором, я считаю, главный негативный фактор это забытие, которому бизнес предал источник своих успешных концепций.

Парсер


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

Архитектура компилятора Оберона может быть описана этой схемой:



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

Парсер однопроходный и не хранит очень много информации о программе в процессе работы. Это достигается по причине простоты и монотонности инструкций языка и процессора. После формирования полной информации о той или иной команде она передается Генератору кода, который сразу производит формирование готового к исполнению кода для процессора RISC. Слежение за состоянием регистров так же возложено на генератор.

Так же сканер занимается графическим отображением места ошибки в исходном коде, и поэтому взаимодействует с модулями ОС.

Кодогенерация


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

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

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

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

Организация памяти


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

Компилятор так же управляет передачей запроса на выделение памяти под динамические объекты ядром, но на этом функции компилятора по управлению такими объектами заканчиваются, далее они рассматриваются просто как смещение по значению указателя.

Ядро и системные модули


Ядро системы Оберон представляет собой модуль, который в основном занимается управлением памятью, выделением памяти под новый экземпляр, сборкой мусора и отловом исключений. Так же, из соображений простоты в ядро был встроен набор процедур по доступу к SD карте по протоколу SPI. Это сделано для того, чтобы минимизировать число модулей в статически слинкованной прошивке и в процессе загрузки сразу перейти к обычному методу динамической загрузки файлов-модулей с диска.

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

Файловая подсистема представлена модулем Files, который внутри себя скрывает реализацию обращения к файловой системе SD-карты. Таким образом клиенты модуля Files уже ничего не знают о низкоуровневых особенностях. Это, как очевидно, высокоуровневые возможности языка Оберон.

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

гифка
image

А вот как выглядит графический интерфейс в процессе работы:



Концепция текстовых команд непосредственно связана с понятием команды, как экспортированной процедуры модуля. Тут мы можем увидеть, насколько тонка грань между реальным кодом и пользовательским интерфейсом в системе Оберон, при сохранении платформонезависимости самой концепции.

Сам графический интерфейс тайловый, монохромный. Это связано с ограничением видеоподсистемы девборды. Графические примитивы базируются на понятии Фрейма, в которых различные модули могут отрисовывать текстовое или графическое содержимое. Идея фреймов была реализована в виде фреймворка BlackBox под Windows, где являлась одной из центральных абстракций графического приложения.

В системе Оберон реализован механизм шрифтов, хоть и не такой мощный, как современные аналоги.

Прикладные модули


Прикладные модули, или, проще, приложения — это прямой аналог приложений в популярных ОС. Так как после загрузки в память модули остаются в памяти, взаимодействие с юзером основано на асинхронной обработке событий от Фреймов.

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

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



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

Можно так же отметить приложение почтового клиента и сервера.

Заключение


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

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

Никлаус Вирт в своем почтенном возрасте продолжает следовать принципам, которые заложил в начале эпохи ИТ. Следует ли этим принципам сама индустрия? Мне кажется — не следует, но это уже философский вопрос, вопрос целеполагания, внутренней непротиворечивости и самоограничения, недоступного рынку.

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

С другой стороны, просто непонятно, почему при наличии ресурсов и ниши те же господа из МЦСТ потратили сотни усилий на создание продуктов, которые позволят встроиться в существующую экосистему Си и GNU/Linux вместо выстраивания собственной экосистемы, пусть даже и не на основе Оберона (хотя хотелось бы, чего скрывать).

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

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

Ссылки


@kisybi
карма
–16,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (388)

  • +39
    Астрологи объявили неделю Оберона. Количество языкосрача в комментах утраивается.

    Извините.
  • +40
    Посмотрел код — глаза вытекли. Не знаю теперь вот, куда деваться.
    • 0
      Доктор сказал «В морг.», значит, в морг.
    • +22
      Код – это просто ад. Надо давать студентам как пример того, как никогда не нужно писать код.
      И это при том, что на работе приходится часто иметь дело с Oberon-2, т. е. глаза более-менее привыкшие.
      • –18
        В то время, как в Цюрихе будут давать студентам новый курс Вирта, вы будете говорить, чтобы они так не делали. Интересно рассуждаете. Не поделитесь размышлениями о коде?
        • –15
          То есть присутствуют люди, которые считают главных по информатике в Ethz глупыми, а Оберон — отрицательным примером для студентов?
          • +28
            Нет, присутствуют люди, которые считают, что приведенный пример кода плох.
            • –19
              Оценить код Н. Вирта, вот это дело. Не каждый день бывает.
              • +12
                Берем список правил из Макконелла и плохие запахи из Фаулера и оцениваем. Абсолютно беспристрастно по выработанным сообществом разработчиков и описанным вышеупомянутыми авторами принципам.

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

                • +11
                  Это точно! Не уедут они далеко с переменными n и N.
                  • +3
                    Посмотрел код, глазам стало больно. Очень похоже на примеры из книг серии «как не надо писать код».
                    Удивительно что эти люди (уже не первый раз) говорят об уменьшении количества ошибок в коде. Смотря на ихние советы и примеры — похоже на саботаж.
                    • +10
                      Мне кажется, что все три аккаунта — это один и тот же человек. Уж слишком стиль изложения и образ мысли совпадают.
                      • +11
                        Возможно (вообще их четверо: kisybi, OberonForGood, oberon87 и akastargazer). Тоже заметил что все аппелируют к одной и той же цитате «язык должен быть максимально простым но не проще» и дальше утверждают что оберон — это и есть тот самый язык, а когда просишь обосновать — начинают переводить тему, говорить «рынок ничего не понимает» и приводить в примеры сниппеты говнокода. Еще забавно что все начали активность примерно в одно время.
                        • –14
                          1) я точно один :)
                          2) вы нихрена не поняли, продолжайте в том же духе.
                          • +5
                            Как объяснили так и поняли. Пытаетесь доказать абсурдные вещи — надо ожидать что никто не поймет аргументации. Просто потому что она не вяжется с реальностью.
                        • +5
                          нет, akastargazer это реальный человек. А вот те трое — да, виртуалы одного человека.
                      • +9
                        Скорее некий препод и его студенческая секта.
                        Демагогия, переходы на личности, аппеляции к авторитетам и вера в «непогрешимость оберона» без понимания сути вопроса…
                        Точно, студенты, у которых бомбануло.
                    • –9
                      Когда мы увидим Ваш проект уровня Системы Оберон, тогда и посмотрим, где саботаж, а где просто вы тренируетесь в острословии.

                      А ошибок на весь проект сколько, уже посчитали?
                      • +15
                        По мне — так весь код в приведенном выше файле — одна сплошная ошибка, ибо читать его невозможно. Одно это чего стоит:
                        VAR pl, pr, p, qb, qe: Piece; org, end: LONGINT;

                        IF (qb # NIL) & (qb.f = pl.f) & (qb.off = pl.off + pl.len) & (qb.fnt = pl.fnt) & (qb.col = pl.col) & (qb.voff = pl.voff) THEN
                        qb.f? pl.off? voff? Серьезно? Это продакшн код или первые шаги школьника изучающего программирование? Я, помню, писал такой код в школе примерно первые пару лет после того как купил первую книжку по программированию.

                        Кстати об ошибках — вот тут уже и косяк, qb на NIL проверяется, а pl — нет, а при этом pl — это указатель который может быть нулевым, и нигде выше по методу не гарантируется что он будет не нулевым.
                        • –22
                          На Обероне это просто работает. Я и сам так пишу. Впрочем, происхождение Ваших оценок понятно, а как мы убедились, личное мнение комментатора самое верное.
                          • +11
                            Это не мое исключительное личное мнение, это базовые правила написания хорошего кода, о которых говорится в любой более-менее известной книге по написанию хорошего кода, которые есть практически в каждом гайде и которые используются повсеместно. Работать оно будет хоть на обероне, хоть на любом другом языке, компилятору на это пофиг, вот только люди читать и разбираться в этом будут гораздо дольше. С null'ом тоже ошибку не выкинет? Или все ошибки написанные на обероне — это не ошибки а фичи?
                            • –14
                              Гайды важны, но не стоит забывать что они не для Оберона изначально написаны.
                              • +12
                                Да не важно какой язык, qb.voff = pl.voff — нечитаемо вне зависимости от языка.
                                Код написан настолько безобразно, что даже автор вероятно через год не сможет разобрать его.
                                • –15
                                  Вы джавист?
                                  • +15
                                    Нет. Вообще не вижу как это может влиять на тот факт что код по ссылке — безобразен?

                                    Я приведу еще один пример:
                                    PROCEDURE SetWidth*;
                                    VAR S: Texts.Scanner;
                                    BEGIN GetArg(S);
                                    IF (S.class = Texts.Int) & (S.i > 0) & (S.i < 7) THEN Graphics.SetWidth(S.i) END
                                    END SetWidth;
                                    Что такое S.i? И почему он может быть от 1 до 6?

                                    Еще к «безошибочности»:
                                    PROCEDURE Backup (VAR name: ARRAY OF CHAR);
                                    VAR res, i: INTEGER; ch: CHAR;
                                    bak: ARRAY 32 OF CHAR;
                                    BEGIN i := 0; ch := name[0];
                                    WHILE ch > 0X DO bak[i] := ch; INC(i); ch := name[i] END;
                                    IF i < 28 THEN
                                    bak[i] := "."; bak[i+1] := «B»; bak[i+2] := «a»; bak[i+3] := «k»; bak[i+4] := 0X;
                                    Files.Rename(name, bak, res)
                                    END
                                    END Backup;
                                    Если входящая строка более 32 символов — что будет? Будет ошибка, потому что массив выделяется на 32 элемента внутри. А если строка 28 символов или более но меньше 32 — то метод просто молча ничего не делает.

                                    О чем все это говорит?
                                    Те кто пишут говнокод — будут писать его на любом языке.
                                    Те кто пишут говнокод — будут делать ошибки на любом языке.

                                    Ну и кроме того — язык в принципе не может уберечь от 99% ошибок, потому что они языко-независимы.
                                    • –13
                                      S.i это аккумулятор для пользовательского целочисленного параметра при вызове команды? Я просто код не видел еще, исхожу из того, что вы дали. А как еще назвать?
                                      Второй кусок тоже неясно, чем вам не понравился, ведь явно написано, ЕСЛИ длина меньше 28, единственное на что вы можете жаловаться, это на отсутствие комментария с пояснением.
                                      • +21
                                        Вы правда ошибки не видите? Если длина больше 28 но меньше 32 — код ничего не делает. Я вызываю метод Backup а он не делает то, что обязуется делать по своему названию. А если больше 32 символов — вообще упадет с исключением доступа к памяти или подобным, что тоже совершенно странно.

                                        А с чего вы взяли что S.i — это аккумулятор? Я вот думаю что это 14, потому что Si — Silicon — 14й элемент в периодической таблице. А может это сокращение от iterator?
                                        Я просто код не видел еще, исхожу из того, что вы дали. А как еще назвать?
                                        Вот в этом и суть — чтобы понять то что делает строчка в методе — надо залезть еще посмотреть кучу окружающего кода, а код должен быть самодокументируемым, посмотрел на метод — понял что он делает на базовом уровне. Это должно быть очевидно из названия метода, названия параметров и тела метода, из контекста можно привязать еще название класса, но никак мне не нужно лезть в дебри чтобы понять что такое S.i.
                                        • –16
                                          Вы можете называть свои переменные, как вам угодно. Код на обероне все равно останется надежным, хоть с длинным хоть с коротким именем.

                                          И да, возможно, процедура Backup просто не обязана работать всегда, это личное дело автора. Все равно она будет работать так, как он задумал. Упадет — поправит. Непонятно, с чего вы взяли, что это влияет на надежность языка и его свойств по реализации алгоритмов? Впрочем, чего это я.
                                          • +8
                                            Вы можете называть свои переменные, как вам угодно.

                                            То есть читаемость и поддерживаемость больше не имеют значения?

                                            Код на обероне все равно останется надежным,

                                            Что лично вы вкладываете в понятие «надежность» в этой фразе?
                                          • +15
                                            И да, возможно, процедура Backup просто не обязана работать всегда, это личное дело автора. Все равно она будет работать так, как он задумал. Упадет — поправит.

                                            Ну это уже просто несерьёзно. Вы точно сторонник оберона, а не оберонохейтер-диверсант под прикрытием?

                                            И таки да, что такое надёжность, по-вашему?
                                            • –11
                                              Алё, гараж, это код не мой, все ошибаются, а процедура явно не очень важна. А накидать проблемных мест любой может, см. статью про Яист. Просто одни это сделали своей основной деятельностью, штатные эксперты-критики, а другим просто не до того.

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

                                              Плюс Оберон еще и понятен всем подряд. Даже джавистам.
                                              • +7
                                                Надежно передавая ваши мысли машине. Вот написал автор процедуру, и она будет работать. Алгоритмическая часть передается обероном точно,

                                                Точно или надежно?

                                                That aside, что вы понимаете под точностью передачи алгоритмической части, и почему вы считаете, что Оберон передает алгоритмическую часть точнее других языков? (или вы этого не считаете?)
                                              • +10
                                                Я лишь говорю о том, что код на Обероне работает так, как его написали.

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

                                                Надежно передавая ваши мысли машине.

                                                Я предпочитаю мыслить в более высоких абстракциях, извините.

                                                Плюс Оберон еще и понятен всем подряд. Даже джавистам.

                                                Мне не понятен. Я его просто читать не могу, у меня глаза вытекают.
                                          • +4
                                            А что же тогда «надежность языка»? Если он не помогает избегать ошибок — то в чем это преимущество, которое вы тут расписываете?
                                    • –10
                                      Вообще, вы сейчас делаете странную вещь, лезете в новую для вас экосистему со своим набором правил. Я не говорю, что они все не работают, но вы не доказали их применимость. А уж основное преимущество вашей позиции в том, что остальным просто лень лезть в кишки ядра линукс или jvm и искать там недостатки.
                                      • +10
                                        что остальным просто лень лезть в кишки ядра линукс или jvm и искать там недостатки.
                                        Так там есть недостатки, я же не утверждаю что язык на котором я пишу — магическим образом снижает количество ошибок, не требует отладки и прочие ереси, которые тут расписывают оберонщики. Конечно есть недостатки в любом более-менее большом проекте, это очевидно. Создание безошибочного кода (а точнее понижение вероятности ошибок до определенного уровня который можно считать «принебрежимо малым») — это очень долго и дороге, вне зависимости от языка.

                                        но вы не доказали их применимость.
                                        Т.е. на обероне не надо писать разборчивый код? Эти вещи не зависимы от языка.
                                      • +10
                                        Извините, пожалуйста, я дурак, который пока не понимает сути оберона.
                                        Вы не могли бы мне рассказать на простом примере, в каком месте семантика оберона отличается от семантики любого другого статически-типизованного язык программирования?

                                        Ну, например, чем if в обероне отличается от if в C# и почему обероновская конструкция надежнее?
                                        Или на примере for. Или любой семантической конструкции, которую вы посчитаете хорошим примером.

                                        Еще раз прошу обратить внимание на то, что я говорю про семантику.
                                        • 0
                                          Например, у них циклы без break и continue то есть по заголовку while можно однозначно определить, при каких условиях он завершится, не лазя в тушку
                                          • 0
                                            Ну как сказать… в Обероне-07 есть цикл Дейкстры, там заголовком не обойдешься. И его анализ головой не так уж прост.
                                            • 0
                                              Я имел ввиду, что есть такие циклы, а не, что все они такие.
                                              • +5
                                                while(!done)
                                                {
                                                  ...
                                                  if (...)
                                                  {
                                                    done = true;
                                                  }
                                                  ...
                                                }
                                                


                                                Цикл завершится когда done. Толку от этого? И к тому же отсутствие continue и break порождает дополнительную вложенность, что не есть хорошо.
                                                • –5
                                                  Отсутствие break гарантирует, что после цикла условие цикла будет ложным. А так как условие это expression, в циклах на обероне реализуется подход, который в свое время так хотели сишники, но не получили, подход, при котором в теле цикла в идеале только счетчик или пустота(для итераторов). А это уже ведет к тому что формула в условии может быть верифицирована при чтении.
                                                  • +4
                                                    Вы не понимаете что break — это выражение логики? Уберите break из синтаксиса и в условии while появится переменная bool done, break заменится на done = true, а в теле появятся дополнительные if(!done), да, после цикла переменная будет равна true, но только толку от нее уже не будет. Или появится while (!done && condition) вместо while(condition), все равно в конце цикла значение condition будет для вас неизвестным. И еще охватите дополнительные ошибки из-за того что надо будет писать if'ы и тем самым увеличивать цикломатическую сложность. Оно нужно?

                                                    PS. Почему вы появились в топике сразу как только заблокировали oberon87 и kisybi? Мы правы и это просто еще один виртуал?
                                                    • –6
                                                      Уважаемый, вы сейчас демонстрируете, как бы это помягче выразиться, легкое недопонимание того, как правильно применять циклы, то есть, демонстрируете понимание их сути, вот что с вами форыч сделал.
                                                      Например, есть статья oberoncore.ru/wiki/%D0%BF%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD%D1%8B_%D1%86%D0%B8%D0%BA%D0%BB%D0%BE%D0%B2 (в ней еще ссылки, тоже сходите почитать)
                                                      Если вы отвлечетесь от форыча и break, то заметите, что автор статьи строит циклы таким образом, чтобы ни дублирования не было, ни выхода из середины. Как ему это удается, ведь вы же только что сказали, что цикломатическая сложность, два флага, куча IF? Тут вы слегка облажались, конечно. И это, заметьте, только один вид циклов, с предусловием. С постусловием в два раза круче будет.
                                                      • +4
                                                        То, что по вашей ссылке, называется «итератор». И вы не поверите, но foreach (по крайней мере в C#) внутри работает именно так.

                                                        ru.wikipedia.org/wiki/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80

                                                        Покажите мне, пожалуйста, цикл по элементам коллекции коллекций (т. н. jagged array) с выходом из цикла по простому условию.
                                                      • +1
                                                        Человек приводит в пример пару циклов и объявляет что вот такие паттерны есть а других циклов быть не может. Ну это совершенно ничего не доказывает. Есть вполне хорошие гайды, есть примеры как не надо делать, в том числе — где не надо ставить break. Если цикл простой и с break выглядит лаконичнее — пишем с break. Если нет — пишем без.
                                                        Иногда код ложится на семантику for/foreach, тогда писать через while — не особо красиво
                                                        int i = 0;
                                                        while(i < something)
                                                        {
                                                           var currentListElement = someList[i];
                                                           ...
                                                        
                                                           i++;
                                                        }
                                                        

                                                        А с for без break будет:
                                                        for (int i = 0; i < something && stayInLoop; i++) { ... }

                                                        сравните с:
                                                        foreach(var currentListElement in someList)
                                                        {
                                                            if (IsThisTheElementImLookingFor(currentListElement))
                                                            {
                                                                result = currentListElement;
                                                                break;
                                                            }
                                                        }
                                                        

                                                        Я сразу избавился от забот об индексации, об инкременте индекса, о введении каких-либо дополнительных переменных.

                                                        Примеры конечно несколько упрощены, т.к. в данном случае вообще нужно писать:
                                                        var result = someList.FirstOrDefault(IsThisTheElementImLookingFor);
                                                        Но при небольшом усложнении логики оно перестает влезать в FirstOrDefault, и тогда приходится писать цикл.
                                                      • +2
                                                        Ага, нет выхода из середины. Зато:

                                                        • в «полном проходе» дублирование «первой» и «следующей» ситуации
                                                        • в «линейном поиске» две проверки «конца ситуаций»


                                                        «Правильное применение циклов», говорите?
                                                    • +2
                                                      Мы правы и это просто еще один виртуал?

                                                      Да
                                                • +1
                                                  Надо называть не done, а более конкретно:

                                                  while(!found && I.moveNext())
                                                  {
                                                      ...
                                                      Found = ...
                                                      If(found)
                                                      {
                                                           ....
                                                      }
                                                      ...
                                                  }
                                                  
                                                  


                                                  Тогда понятнее смысл цикла
                                                  • +1
                                                    Так я об этом и говорю — проблема не в break или continue. Написать непонятно можно и без них, и с ними можно написать понятно. То, что делает break должно быть понятно из контекста данного метода, в котором есть цикл. Если есть break — значит он не в конце цикла, значит он заставляет цикл пропустить какие-то инструкции, значит если его убрать — образуется новый if, возможно не один. Есть гайды как писать код, в нормальном коде абсолютно понятно что и как делают break и continue. Если человек пишет while на два экрана, так что не разберешь — так проблема тут совсем не в break.
                                                    • 0
                                                      Если есть break — значит он не в конце цикла, значит он заставляет цикл пропустить какие-то инструкции, значит если его убрать — образуется новый if, возможно не один.


                                                      И это нормально — кусок который не всегда будет выполняться будет выглядеть вложенным и отделен от остального. В конец итерации цикла всегда можно будет вставить кусок кода, который будет гарантированно выполняться. Рассуждать про свойства цикла будет проще.
                                                      • 0
                                                        Вопрос предпочтений, в некоторых случаях удобен break, а иногда и вообще — проще return написать во вложенном цикле, чем тащить логику в условия. Я не говорю что нужно пихать его везде. Но есть ситуации где он упрощает код. А бездумно пихая — можно испортить код любой конструкцией.
                                            • 0
                                              Кстати, этот самый цикл Дейкстры есть в каждом втором коде на эрланге, записанный в виде хвостовой рекурсии и паттерн-матчинга.

                                              Для меня было открытием, что оказывается, это цикл Дейкстры.
                                              • +9
                                                … при этом в статье про Rust один из Оберон-программистов не понимает ценность паттерн-матчинга. Вот такая вот коллизия.
                                      • +7
                                        >>> Вообще, вы сейчас делаете странную вещь, лезете в новую для вас экосистему со своим набором правил
                                        Ооо. С такой агрессией вы в свою секту адептов много не наберёте
                                        • –10
                                          Секта, адепты. А вы уже перестали пить коньяк по утрам?
                                    • –7
                                      А вы прям считали процент? Или просто так красиво соврали?
                                      • +9
                                        По своему опыту сужу. Ошибки связанные с языком это в большинстве — ошибки удаления объектов (компенсируемые сборщиком мусора), частично ошибки работы со строками и индексами массивов (компенсируются объектами строк и массивами со встроенной длиной) и подобное.
                                        Например null reference exception — это не ошибка языка, даже если в языке запретить null и указатели вообще — эта ошибка получит просто другое имя, т.к. это семантическая ошибка обращения к несуществующему элементу. Уберите указатели и эта ошибка просто превратится в обработку элемента-«пустышки», если логика кода этого не предусматривает — это так же приведет к ошибкам. Я сейчас не припомню даже когда последний раз видел ошибку именно свойственную языку а не ошибку в логике которая могла бы появиться в любом языке.
                                        • –2
                                          Про NRE не соглашусь: в большинстве случаев это именно ошибка вида «не учел, что тут объекта может не быть». И язык позволяет уменьшить количество таких ошибок почти до нуля — достаточно убрать null из языка. Тогда невозможно будет забыть, что работаешь с оберткой.
                                          • 0
                                            С чего это? Как раз будет просто другая ошибка — обертка будет обрабатываться как обычный объект. Если в ней будет где-то целочисленный 0 на который делят — получим ошибку деленя на 0, а то и хуже — можем получить ошибочные данные или сохранять пользовательский документ в пустоту.
                                            • +1
                                              Обертка (Maybe/Option) имеет другой тип. Нельзя разделить на Option[Int]. Нельзя вызвать метод myMethod у Option[Item].

                                              В том же котлине компилятор просто не позволит использовать Item? как Item если в коде нет гарантии на то, что Item? — не null (а Item? — другой тип).
                                              • –1
                                                Так будут делить на myIntValueOption.Value без проверок как сейчас делят на myObject.MyIntValue без проверки на null. Т.е. проблема остается. Хотя все эти проблемы относительно легко выявить статическим анализом, если не совсем какой-нибудь хитро-запущенный случай.
                                                • 0
                                                  Value — это из C# же? Нет там нормальных Option значений, а на то, что есть, без слез не взглянешь.

                                                  Да, к сожалению, сейчас только Maybe не позволяет стрелять себе в ногу. Но и остальные не позволяют забыть. Как я уже писал большинство NRE в моей практике из-за того, что кто-то забыл проверить.

                                                  И все выстрелы в ногу вычищаются анализатором. В той же scala достаточно запретить через scalaStyle вызов get на Option, в котлине — notNull, в java — тоже get. Это уже можно сделать и это уже активно применяется.
                                                  • 0
                                                    Я ниже ответил. В данном случае ошибки просто переносятся из одной области в другую. Можно городить защитные механизмы для предотвращения ошибки, но эти защитные механизмы сами являются кодом и сами могут содержать ошибки. Можно обязать проверять на != null перед каждым обращением к объекту, но никто не гарантирует что в ветке else этой проверки (которую теперь придется писать) будет корректная обработка — что по сути ошибка той же природы, только вынесенная в другое место.
                                                    • +1
                                                      И в третий раз: подавляющее большинство NRE — не из-за неправильно обратобки случая с null, а из-за того, что человека забыл, что тут может быть null.
                                                      • +1
                                                        Это мне напоминает спецификатор throws — была точно такая же история. Люди забывали что метод может выкинуть исключение X. Решение казалось бы простое — давайте заставим всех явно каждый раз обращать на это внимание, или добавляем исключение в throws или обрабатываем. Итог? Никто не захотел работать с overhead'ом, вызванным этим спецификатором. И толку от этого небыло, просто перехватывали все подряд исключения и забивали. Т.е. формально ошибка в том виде в котором она была — исчезла, но по факту она просто перетекла в другие виды ошибок. Здесь то же самое. Если вы обяжете всех везде каждый раз работать с проверками — вы наплодите кучу других ошибок. Точно так же как забывали проверить на null будут забывать что в метод могут передать null и все проверки окажутся бесполезными. Процент исходных ошибок уменьшится — но он перетечет в другие. При этом NRE — замечательная ошибка, потому что она обнаруживаемая, она не портит данные в тихую, не сохраняет файл в пустоту и т.д. (а именно в эти типы ошибок перетечет NRE если пытаться полностью вычистить его из языка). Кроме того NRE проверяется статическим анализатором на ура, в то время как ошибки в которые он превратится если его убрать — тяжело обнаружимы.

                                                        Гораздо лучше когда язык позволяет в тупую делать обнаружимые ошибки, потому что попытки избавиться от этих ошибок скорее всего приведут к тому что вместо них появятся ошибки которые тяжело обнаружить (может их и будет меньше, но время на поиск и исправление таких ошибок многократно выше). Опять же возрастет сложность кода.
                                                        • +1
                                                          throws — неудобное переизобретение Validation. Были бы удобные механизмы для работы с Validation — использовались бы (но это был бы уже другой язык). Там, где, например в scala, используется Validation никто его не игнорирует.

                                                          Разница между обнаружением NRE и не компилируемостью Option только в том, что NRE обнаружится уже только в рантайме. А уж какие средства будут использованы для устранения NRE и для написания компилируемого кода с Option — зависит от программиста. И там и там можно наговнокодить одинаково.

                                                          Вычисление же NRE статическим анализатором — это что-то новенькое. разве что при помощи Null/@NotNull, что является неудобным переизобретением Option, как throws — неудобное переизобретение Validation. Со всеми теми же минусами.

                                                          Про сложность кода: если есть null, то любое поле может быть null, любой параметр может быть null и любое возвращаемое значение может быть null — куда уж больше сложность?
                                                      • +1
                                                        подавляющее большинство NRE — не из-за неправильно обратобки случая с null, а из-за того, что человека забыл, что тут может быть null
                                                        Или забыл захватить нужный лок и получил data race. NPE вылетает редко, но метко.
                                                  • 0
                                        • +1
                                          (пре-скриптум: простите, сначала не дочитал, что написал senia %)
                                          КМК, проблема null не в том, что он есть, а в том, что он неотличим от нормальных ссылок и поэтому его легко забыть обработать. Пусть будут пустышки, главное, чтобы если логика кода их почему-то не предусмотрела, это бы не компилилось. Тут, например, помогают мои любимые опциональные типы, которые нынче есть и в приснопамятном яисте, тьху, расте.
                                          • –1
                                            Если вы сделаете это не компилящимся — вам придется выкинуть из языка динамические массивы, да и со статическими работать будет очень сложно. Ровно как и возникнет проблема инициализации объектов. И даже это не поможет. Все равно в конструкторах по умолчанию, например, будут заполнять все поля самодельными «пустышками», и это по определению не будет отличимо от реальных объектов. Просто потому что ошибка сама происходит не от null'ов или подобных абстракций, а от того что существует «неинициализированное» состояние объекта. И ничто не удержит программиста от написания этого состояния самостоятельно в дефолтном конструкторе. Причем в этом случае разбухнет логика и ошибок может стать даже больше потому что станет гораздо больше различных обвязок.
                                            Избавиться можно только от ошибок не зависящих от логики и предметной области. Например удаление объектов из памяти как таковое (т.е. не касающееся прочей логики деструктора) — это особенность работы с железом, при бесконечной памяти оно было бы не нужно. И даже тут мы все равно меняем ошибки (ручного удаления объектов) на проблемы производительности или утечки памяти (проблемы, связанные с непониманием работы GC).
                                            • +2
                                              Вам обязательно нужны такие низкоуровневые инструменты как массивы? Мне — крайне редко.
                                              В большинстве случаев меня интересует только контракт на коллекцию (включая сложность операций), а не конкретная реализация коллекции.

                                              Про конструкторы по умолчанию я вас, похоже, не понял. Достаточно либо убрать возможность обратиться к объекту в неинициализированном состоянии — immutable объект. Либо в явном виде отделить инициализируемое состояние от неинициализируемого (через Option).

                                              Да, устранение NRE не устранит все ошибки, но оно снизит количество ошибок. И в четвертый раз: подавляющее большинство NRE происходит не из-за того, что программист не знает как обработать случай null, а от того, что он не знает/забывает, что в данном случае может быть null, так как на уровне языка любой объект в любом месте может быть null.
                                              • –1
                                                а от того, что он не знает/забывает, что в данном случае может быть null
                                                Когда вы каждый раз слышите в кино предупреждение «выключите звук на мобильнике» — вы его начинаете просто игнорировать. И чем чаще вы туда ходите тем больше гарантии что на предупреждение вы не будете проверять телефон. Так же и здесь — человек точно так же будет забывать и будет машинально писать обертку, как будто все хорошо. В итоге вместо 10 NRE получите 5 трудноуловимых ошибок. Предупреждения хороши когда они осознанно обрабатываются — например при запуске стат. анализатора (и то не 100% гарантия). Но разменивать такую замечательно обнаружимую ошибку как NRE на что-то более опасное — смысла нету.
                                                • +1
                                                  Вот проблема именно в «каждый раз». При наличии null все может быть null. Именно поэтому возникает NRE — если все может быть null и все проверить невозможно, то забывают проверять даже то. что надо.

                                                  В случае же с Option null нет. А Option может быть только то, что имеет тип Option. И таких мест. как выясняется, довольно мало.

                                                  И что такое «машинально писать обертку» в случае с Option? Машинальных действий при работе с Option всего 2:
                                                  1. getOrElse — аналог ?? для null. Если существует применимое значение по умолчанию (заметьте, относительно null ничего не изменилось).
                                                  2. map/flatMap, если значения по умолчанию нет.

                                                  Всё остальное — не «машинальные» действия.
                                                  • +1
                                                    А если сюда добавить не только maybe, но и монаду maybe (как например в Haskell), то сделать ошибку уже и из за лени становится еще сложнее. Тем более что никакого оверхеда в тексте программы уже и не будет.
                                        • +2
                                          семантическая ошибка обращения к несуществующему элементу


                                          Это ошибка того, что не разделяются nullable и не nullable — по умолчанию считается что метод может возвратить null и это никак не контроллируется. Посомтрите например на kotlin и на проект введения не nullable ссылок на объекты в C# 7:

                                          Вы явно декларируете ссылку как не nullable и тогда нельзя присвоить туда nullable без специальных приседаний — компилятор контроллирует.

                                          Сэр Тони Хоар называет введение null ошибкой на миллиард долларов

                                          www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
                                          • 0
                                            Да, в этом полностью согласен. Может не так ясно выразил мысль выше. Если будет nullable и не nullable ссылки — это будет акцентом, и будет смещать внимание на то что «а вот эта ссылка не nullable, а почему? надо проверить». Если же все будут не nullable то это будет просто восприниматься как ограничение (или особенность) языка и акцента не будет.
                                            Ввести опционально не nullable ссылки было бы полезно.
                                    • –8
                                      По поводу Backup. Она предназначена для обработки имён ограниченной длины, причём в рамках определённого контекста, где как раз и делается охрана этих самых имён. Сама процедура Backup делает ровно то, что необходимо, но не больше. Контекст уже предполагает правильность имён, поэтому нет смысла наворачивать лишнее мясо в коде. Но охрана длины всё же стоит, потому что Files.Rename жёстко завязана на длину.
                                      Процедура Backup не универсальная, причём скрытая от клиентов модуля. Смысл, который я описал, легко можно понять, бросив короткий взгляд на исходник.

                                      Но вы подняли крик про говнокод, не вникая, о чём идёт речь. Как обычно. Хабра-экспертиза, my ass. С последующими вселенскими выводами, конечно.
                                      • +1
                                        Борис, ты не прав.
                                      • +3
                                        Метод называется Backup, на 28 проверяет, а если больше 32 — вылетает, так уж определитесь или не проверять совсем или проверять по человечески. Фиксированный массив на 32 — тоже шикарно. Как и +4, +8 и прочее в коде работающим со структурами там далее (удачи с портированием на другую разрядность).
                                        Я уж не говорю о безобразнейшем копировании строк, которое не то что в принципе не безопасно, а еще и руками реализовано каждый раз.
                        • –1
                          Ну вот, а покажешь каллиграфически оформленный код на Аде, будут жаловаться, что можно уснуть, пока допишешь.
                        • +5
                          Сеймур Крэй мог надиктовать по телефону бутлоадер своего суперкомпьютера.
                          А Никлас Вирт всю жизнь тренировался на однобуквенных идентификаторах и достиг совершенства в самообфускации.

                          Дзен же.
                          Вначале были горы букв и реки строк. Потом горы перестали быть горами, а реки реками. И наконец, снова горы стали горами, а реки реками.
                        • +4
                          Здесь следует учитывать несколько факторов.
                          Имена переменных в Обероне — не «бесплатны» — они хранятся в объектных файлах и используются например в трапах, где выводятся стек вызовов и значения и имена локальных переменных и аргументов.
                          Так что это может использоваться, в том числе, и для отладки, ибо вся информация есть.
                          Во вторых, следует учитывать железо, на котором Вирт начинал программировать, его ограничение по памяти и и.п., кроме того дедушка Вирт явно увлекается ассемблером, что ествественно накладывает отпечаток на код.
                          К слову, ровно такой код я видел в программах на других языках.
                          Что касается проверки указателя, то подозреваю, что там никогда не может быть NIL
                          • +2
                            > Имена переменных в Обероне — не «бесплатны»

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

                            > Во вторых, следует учитывать железо, на котором Вирт начинал программировать, его ограничение по памяти

                            Кто нибудь, отберите уже у Вирта его старый ZX Spectrum и подарите ему нормальную машину, чтобы он перестал паниковать, когда его программа выходит за предел 48K.
                            • 0
                              Я не являюсь фанатиком Оберона (например вот тут мы с Kemet'ом долго и нудно спорим на тему чуда портирования ОС Оберон за два выходных: habrahabr.ru/post/258993/#comment_8440659 ), но поскольку я немного в теме (лет 8-9 наверно уже как), то таки имею кое-что сказать про «старый ZX Spectrum». :-)

                              Итак, Вирт в Project Oberon 2013 слепил не просто операционку, или там язык, а еще и компьютер на FPGA целиком. Слеплено это дело на Spartan-3 (стоило это дело порядка 100 баксов) с использованием в качестве ОЗУ тамошней SRAM. SRAM'a там 1 мегабайт (из которых часть используется под видеопамять). В изначальной рабочей станции (Ceres) же когда Вирт делал первоначальную версию Оберона в 1989 году по естественным причинам также было что-то около 1-2 Мб ОЗУ.

                              В этом компьютере (на FPGA, 2013 год), в процессоре, нет MMU, а также нет и прерываний. Таким образом классическая пошаговая отладка там, мягко говоря, затруднительна (напомню, что поскольку этот процессор модель для изучения, он должен быть максимально простым и вполне обозримым в плане размеров), впрочем как и, например, вытесняющаяя многозадачность.

                              Поэтому даже в 2015 году отобрать у Вирта его «старый ZX Spectrum» не представляется возможным — он сам его сделал и вот как раз совсем недавно :-)

                              Единственное что возможно — это перенести его на какую-то новую платку с FPGA (благо повод имеется — Spartan-3 выведен из продажи), где будет больше ОЗУ. Но тут нюанс — на SDRAM (которой бывает МНОГО — десятки мегабайт! иногда сотни!) перейти будет проблематично в данном проекте: с одной стороны самому писать на верилоге модуль для работы с SDRAM (его обновления и так далее) — это существенно увеличить объемы исходников компа и их сложность, кроме того после этого остро встанет проблема процессора — у процессора Вирта нет конвеера, поэтому он будет бОльшую часть времени просто простаивать. С другой стороны, использовать готовый модуль (которые тем же Xilinx'ом предоставляются) для работы с SDRAM тоже нельзя — это противоречит духу проекта :-) Абсолютно все части компа должны быть как на ладони и понятно как работают.

                              А дешевых плат с большими объемами SRAM я лично не встречал :-( Собственно даже на альтеру DE2-115 просто так не перетащить: там просто так не сделать 32битную адресацию для SRAM (без потери производительности).

                              Если есть предложения как можно было бы наименее болезненным способом нарастить память у Оберон-компа — велком! Может совместными усилиями и придумаем что. ;-)
                          • –1
                            Кстати, мне пока не удалось обнаружить в Project Oberon 2013 подтверждение того, что имена локальных идентификаторов где-то хранятся.

                            Не можешь подсказать где именно эта информация находится в обеъктном файле? Вот его структура:

                            CodeFile = name key version size
                             imports typedesc varsize strings code commands entries ptrrefs fixP fixD fixT body "O".
                            imports = {modname key} 0X.
                            typedesc = nof {byte}.
                            strings = nof {char}.
                            code = nof {word}.
                            commands = {comname offset} 0X.
                            entries = nof {word}.
                            ptrrefs = {word} 0.


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

                            Результаты моих личных исследований и экспериментов говорят об обратном — размер объектного файла (*.rsc) никак от именований локальных переменных не зависит.

                            Вот тестовый модуль:
                            MODULE Test;
                                IMPORT Files, Texts, Oberon;
                            
                                PROCEDURE P*;
                                    VAR
                                        W : Texts.Writer;
                                        file : Files.File;
                                        t : INTEGER; (* длину названия именно этой переменной будем варьировать *)
                                BEGIN
                                    Texts.OpenWriter(W);
                                    file := Files.Old("Test.rsc");
                                    Texts.WriteInt(W, Files.Length(file), 6);
                                    Texts.WriteInt(W, 123, 6); (* число 123 будем менять, чтобы убедиться, что у нас запущена новая версия модуля *)
                                    Texts.Append(Oberon.Log, W.buf);
                                END P;
                            END Test.
                            


                            Размер объектника получается у данного модуля всегда 320 байт. вне зависимости от того, сколько букв t в названии переменной, то есть зовется она t, или же ttttttttttttttttttttt.

                            Таким образом получается, что названия локальных переменных в Обероне все же бесплатны.

                            Или я что-то делаю не так?

                            Кроме того, в Обероне также нет возможности (по крайней мере я такой возможности не обнаружил) посмотреть при трапе стек или кучу. Если укажешь на таковую возможность, буду весьмя благодарен.

                            При трапе лишь указывается место в исходнике где трап произошел.

                            PS. Да, на слово я не верю, все и всегда стараюсь проверять экспериментально. Особенно если я могу это сделать. В случае с обероном я могу. Сори :-)
                            • 0
                              Во-первых, а почему вы не использовали хоть как-то переменную, длину названия которой варьируете? А то наверняка компилятор не совсем дурак, неиспользуемые переменные просто игнорирует.

                              Зачем вообще была эта t, можно же было изменять длину названия, скажем, переменной W?

                              Во-вторых, я уверен, что в объектном файле есть какое-нибудь выравнивание. То есть, если речь об одной переменной, то из одного символа у неё название или из десяти — никакой разницы, возможно, нет, если выравнивается всё по «параграфу» в 256 байт. Для надёжной проверки надо взять исходник с двумя десятками переменных и менять имена их всех.

                              Ну и ещё можно сравнивать сами объектные файлы: если что-то изменяется, кроме времени сборки и номера версии, значит, значит, это связано с именами переменных.
                              • 0
                                Размер бинаря — 320 байт, соответственно все выровнить по 256 не выйдет. Да и формат хорошо описан (в книжке, которуя я например читал) и там нет выравнивания по 256.

                                Нет, Виртовский компилятор не выкидывает, насколько я знаю, неиспользуемые переменные.

                                Сравнить объектные файлы несколько сложнее конечно — писать придется несколько больше (а чтобы это на персоналке проверить, нужно файлы на персоналку еще как-то передать). Но я попробую для чистоты эксперимента :-)

                                О результатах отпишусь чуть позже.
                              • +3
                                Итак, я проделал ряд экспериментов. Для этого модифицировал код следующим образом:

                                MODULE Test;
                                    IMPORT Files, Texts, Oberon;
                                
                                    PROCEDURE P*;
                                        VAR
                                            W    : Texts.Writer;
                                            file : Files.File;
                                            r    : Files.Rider;
                                            t    : INTEGER;
                                            b    : BYTE;
                                            s012345678901234567890123456789, u0123456789012345678900123456789 : INTEGER; (* 2 *)
                                    BEGIN
                                        Texts.OpenWriter(W);
                                        file := Files.Old("Test.rsc");
                                        Files.Set(r, file, 0);
                                        Texts.WriteInt(W, Files.Length(file), 6);
                                        Texts.WriteInt(W, 0, 6); (* число 0 будем менять, чтобы убедиться, что у нас запущена новая версия модуля *)
                                
                                        t := 0;
                                        WHILE ~r.oef DO
                                            Files.ReadByte(r, b);
                                            t := t + b;
                                        END;
                                        Texts.WriteInt(W, t, 6);
                                        Texts.Append(OBeron.Log, W.buf);
                                        Files.Close(file);
                                    END P;
                                END Test.
                                


                                Программа подсчитывает сумму байт в объектнике (простейшая чексумма), а также смотрит какой объем файла объектника. В лог выдает: file_size flag sum, где flag это число для контроля того, что у нас модуль нужной версии загружен (это сделано, чтобы избежать человеческого фактора при тестировании).

                                Пример вывода: 432 0 32948.

                                Что будем менять: будем менять длину имени переменной t (2 варианта: t и t01234), будем менять длину переменных s012345678901234567890123456789 и u012345678901234567890123456789 (короткие варианты соответственно s и u), также посмотрим что будет, если этих двух переменных не будет вовсе.

                                При тестировании каждый вариант теста будем запускать 2 раза — с flag=0 и flag=1. Чтобы убедиться, что мы нигде не налажали.

                                Итак, результаты:
                                t     , s012... , u0123... : 432 0 32948
                                t     , s012... , u0123... : 432 1 32949
                                --
                                t01234, s012... , u0123... : 432 0 32948
                                t01234, s012... , u0123... : 432 1 32949
                                --
                                t01234,      -  ,       -  : 432 0 32932
                                t01234,      -  ,       -  : 432 1 32933
                                --
                                t01234, s       , u        : 432 0 32948
                                t01234, s       , u        : 432 1 32949
                                


                                Итого, можно уверенно сделать следующие выводы, что:
                                1. Содержимое объектного файла никак не зависит от именования локальных переменных процедур
                                2. Как и ожидалось, в зависимости от литерала flag'а (0 или 1) у нас сумма может увеличиваться на 1
                                3. Компилятор Оберона (писанный Виртом для Project Oberon 2013) не выбрасывает неиспользуемые локальные переменные


                                Также можно осторожно предположить, что объем объектника не зависит от числа локальных переменных (если они не инициализируются (в том числе неявно, компилятором) и не используются).

                                Желающие могут попробовать воспроизвести мои результаты. У вас все для этого есть. Ну, заодно и оцените каково программировать код в Project Oberon 2013 ;-)

                                PS. И я посмотрел — в Project Oberon 2013 действительно удалена глава 12.9 посвященная посмертной отладке и инспекции стека и кучи. Таким образом Вирт посчитал возможность в случае падения приложения её хоть как-то отладить, лишней. Оберон стал еще проще :-)
                                • +2
                                  Из этого теста один вывод: по крайней мере, для этого компилятора переменные можно называть нормально, а не t, s, и так далее. Длина имени влияет на восприятие программистом (упрощает), но никак не влияет на результат компиляции, и следовательно улучшит качество кода без каких-либо компромиссов.

                                  Впрочем, я бы такое сказал и в случае, если бы имена переменных хранились. Это упростило бы программирование и отладку, а два мегабайта в системе, занятые длинными именами переменных, в основном стоят очень дёшево. А где не дёшево, там мегабайтов не наберётся, но там зато килобайты стоят недорого.
                                  • +3
                                    Да. То есть в данном конкретном проекте, Project Oberon 2013 и далее, использование коротких невнятных названий переменных, лепление множества statement'ов на одну строку ничем не оправданы.

                                    То есть это можно объяснить тем, что Вирт так привык делать, что он бОльшую часть кода позаимствовал из Project Oberon 1989, где это еще на что-то влияло, и так далее. Но факт остается фактом — Project Oberon 2013 от такого стиля кодирования автора сильно страдает. Проект оказывается неоправданно сложным для восприятия того, кто его будет изучать (например студента), более того, есть шанс, что человек посмотрит на это дело, и решит что именно так и есть правильно (и я это уже наблюдал — некоторые оберонщики именно в таком стиле и пишут, сейчас. В 2015 году. В винде например).

                                    Конечно если бы Вирт переписал код с нормальными идентификаторами, и с нормальным форматированием кода, то те метрики которые он приводит вначале книжки (про то, сколько там строчек кода в системе, какой объем исходников, какое все мелкое и компактное получилось) несколько испортились бы. По моим оценкам, они стали бы хуже процентов на 30.

                                    Таким образом, я бы стал рекомендовать эту книжку и ОС для обучения только либо после того, как код в ней будет приведен к нормальному стилю кодирования (рефакторинг rename + автоформатирование), либо только как часть курса «учимся разбираться и рефакторить древний говнокод». Иначе Project Oberon 2013 может нанести больше вреда чем пользы.
                                  • 0
                                    Кстати, из моих экспериментов также можно сделать вывод, что в объектнике нигде нехранится ни номер сборки который бы инкрементировался со временем при неизменном интерфейсе модуля, ни дата/timestamp сборки.
                                • 0
                                  Целый эксперимент, с табличкой — у кого-то слишком много свободного времени ;)

                                  > Таким образом Вирт посчитал возможность в случае падения приложения её хоть как-то отладить, лишней. Оберон стал еще проще

                                  Это же очевидно! Программы на Обероне просто не могут упасть. Они сразу работают после первой-же успешной компиляции.
                                  • +1
                                    Слишком много свободного времени, это в комментах переливать из пустого в порожнее на протяжении 100500 комментов ссылаясь на авторитетов и на отсутствие личного опыта у аппонентов :-)

                                    А тут — провел эксперимент, установил факт, и всё :-) Экономия кучи времени.

                                    На самом деле многие утверждения, звучавшие во всех тих обероновских обсуждениях могут быть опровергнуты (либо не опровергнуты) экспериментом.
                            • 0
                              Алексей, не стоит упирать на число 2013 в названии Project Oberon 2013 — коду в этом проекте более 20-ти лет.
                              Поэтому ещё раз повторяю, глянь исходники проектов на других языках, относящимся к этому времени, и часто увидишь то же самое.
                              Имена локальных переменных и формальных параметров есть в A2, BlackBox, Native Oberon/ETH Oberon.
                              Если в текущем учебном проекте такого нет (сейчас(lа и в ближайшие 2-3 недели) проверить не смогу, то Вирт следовал простому правилу, сделать, как можно проще для обучения — есть основная концепция выдачи отладочной информации, минимальная, но полностью понятная. Впрочем он многое упростил в этой редакции.
                              Но это никак не отменяет моих слов, что в Оберон Системах хранятся и выдаются в трапах и имена локальных переменных ( также параметров ) и их значения.

                              В принципе, можно всё это посмотреть в обычном hex-редакторе — эмулятор же доступен
                              • +4
                                Поэтому ещё раз повторяю, глянь исходники проектов на других языках, относящимся к этому времени, и часто увидишь то же самое.

                                Ок. Глянул. Глянул в те исходники той группы рузработчиков, у которой Вирт неоднократно заимствовал идеи и черпал вдохновение, без этой группы разработчиков никогда у Вирта оберона бы не случилось. Впрочем черпал идеи у них не он один. Я говорю о Xerox Park.

                                Итак, вот код 1981 года (то есть за 8 лет до релиза первого оберона, и за 6 лет до начала его написания, то есть тогда Оберона еще и в проекте не было). Язык программирования тут конечно же Mesa:
                                  VerbalizeFtpError: PUBLIC PROCEDURE [ftpError: FtpError, message: STRING] =
                                    BEGIN
                                    -- Note:  Appends message to string.
                                    -- append message to string
                                    SELECT ftpError FROM
                                      IN CommunicationError => VerbalizeCommunicationError[ftpError, message];
                                      IN CredentialError => VerbalizeCredentialError[ftpError, message];
                                      IN FileError => VerbalizeFileError[ftpError, message];
                                      IN DumpError => VerbalizeDumpError[ftpError, message];
                                      IN MailError => VerbalizeMailError[ftpError, message];
                                      IN ClientError => VerbalizeClientError[ftpError, message];
                                      IN ProtocolError => VerbalizeProtocolError[ftpError, message];
                                      IN InternalError => VerbalizeInternalError[ftpError, message];
                                      ENDCASE => VerbalizeUnidentifiedError[ftpError, message];
                                    -- IN UnidentifiedError
                                
                                    END;
                                


                                И вот еще:
                                  RemoveDeviceFromChain: PUBLIC ENTRY PROCEDURE [network: Network] =
                                    BEGIN
                                    tail: Network ← firstNetwork;
                                    IF useCount > 0 THEN
                                      BEGIN
                                      DriverDefs.GetPupRouter[].removeNetwork[network];
                                      DriverDefs.GetOisRouter[].removeNetwork[network];
                                      network.deactivateDriver[];
                                      END;
                                    IF state = ready THEN UnlockCode[network.interrupt];
                                    IF firstNetwork = network THEN firstNetwork ← network.next
                                    ELSE
                                      BEGIN
                                      UNTIL tail.next = network DO tail ← tail.next; ENDLOOP;
                                      tail.next ← network.next;
                                      END;
                                    -- network.index is not updated.  It is used only to collect Gateway statistics.
                                
                                    END;
                                


                                И более-менее нормальное форматирование, и нормальные именования переменных, и даже коментарии в коде.

                                Желающие могут покопать код тут: xeroxalto.computerhistory.org/Ibis/AltoGateway

                                Алексей, не стоит упирать на число 2013 в названии Project Oberon 2013 — коду в этом проекте более 20-ти лет.

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

                                Если в текущем учебном проекте такого нет (сейчас(lа и в ближайшие 2-3 недели) проверить не смогу, то Вирт следовал простому правилу, сделать, как можно проще для обучения — есть основная концепция выдачи отладочной информации, минимальная, но полностью понятная.

                                Да… То есть если Вирт хранит имена переменных в бинаре, то это конечно потому, что он заботится о том, чтобы было проще программировать, чтобы можно было посмотреть состояние системы после краха и понять в чем дело, это избавляет От необходимости пошаговой отладки! Круто! Вирт молодец!

                                Если Вирт НЕ хранит имена переменных и нет возможности инспекции состояния системы после краха, то Вирт просто следует принципу максимальной простоты. Вирт снова молодец!

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

                                Похоже что бы Вирт не делал всегда найдется объяснение почему Вирт в этом случае молодец, а все остальные, мейнстримщики, просто не понимают глубину его мысли :-)

                                Честное слово, лучше бы он просто по нормальному отрефакторил свой код — одно это уже СИЛЬНО снизило бы сложность системы для изучения. При том что объем бинарников никак бы не изменился.
                • –8
                  Они на Обероне не писали, надо полагать.
                  • +11
                    Вы правда считаете, что все выработанные сообществом за десятки лет правила и рекомендации по промышленному программированию к Оберону неприменимы?
                    • +6
                      Конечно. Все эти мейнстримные паттерны и методики – это же жуть как сложно. А оберон сразу ставил цель быть максимально простым.
                      • +3
                        … но не проще! как завещал Эйнштейн.
                • +8
                  Всегда задавался вопросом, почему Pascal-like коды всегда изобилуют одбуквенными идентификаторами, обилием однострочников. Это же как сложно сопровождать, читать, изучать.
                  • +2
                    Мне кажется, это пошло из академической среды, в формулах все величины обычно одной буквой обозначают.

                    Надо отрефакторить математику…
                    • +5
                      Как это ни странно, в математике вообще не мешает. Но там есть очень крепко устоявшиеся традиции, какими буквами что может обозначаться; кроме этого, одну букву быстрее написать руками, чем десять.

                      Оставьте её в покое.
                      • +4
                        В математике, когда заканчиваются буквы, начинают играть со шрифтами. То жирный, то под-над-чёркивания, то вообще готический.

                        Скажите спасибо, что в обероновской IDE переменные не различаются по шрифтам. А то был бы адок!
                        • +4
                          В IDE как раз отличаются (традиционной подсветки синтаксиса там традиционно нет, но ЗАТО есть возможность ручками задать стиль, цвет и шрифт любой букве или идентификатору, или еще чему-то, в общем также как скажем в MS Word). Но компилятор, по крайней мере пока, это не различает :-)

                          Это, кстати, еще один пункт холиворов в оберон-сообществе с 2005 года примерно (особенно в сочетании с использованием пропорционального шрифта вместо моноширинного) :-)

                          Велком ту оберон ворлд! Он местами чудес полон, да и жители весьма своеобразны и разнообразны ;-)
                          • 0
                            Я в курсе про боевую раскраску, потому и упомянул :)
                            Мега-срач про «синтаксический оверхед» на RSDN уже был, вроде всё утихло, но тут снова заверте.
                            • 0
                              Ну, Сергей Губанов (которы инициировал тот срачик на rsdn) успешно перешел вначале на C# а затем и на С++, на коем нынче и пишет. :-)
                          • +1
                            Кстати, я знаю, как задёшево реализовать различение стиля компилятором.
                            Нужно просто кодировать стиль в манглированном имени. Например,
                            VAR
                            x: REAL;
                            x: COMPLEX;
                            x, x1: Vector;

                            это, на самом деле,
                            VAR
                            x: REAL;
                            $i$x$_i$: COMPLEX;
                            $b$x$_b$$sub$1$_sub$: Vector;

                            где $tag$ и $_tag$ — вкл-выкл того или иного стиля.
                        • 0
                          хорошо, я поменяю формулировку

                          в математике есть сильная традиция, какие глифы что обозначают

                          некоторые конечно можно перепутать, но опять же традиция, что те глифы, которые похожи, в одних формулах никогда не встречаются
              • +3
                Хороший пример argumentum ad verecundiam, ага.
                • –3
                  На хабре этих Виртов через одного, не удивишь.
                  habrahabr.ru/post/258391/#comment_8431183
  • +2
    Простите за оффтоп, но вступление повеселило!
    • +2
      Я сам хотел поблагодарить автора за положительное настроение. На самом деле, эта часть взята из выступления А. Райкина — Борьба с проклятой. Если что, в интернете есть несколько версий, но мне именно нравится эта (запись живого выступления).
      Простите, что поддержал ваш оффтоп. Думал кому-нибудь пригодится.
      • +1
        Культурная ценность этого выступления кажется непроходящей.
  • +1
    Большое спасибо за статью! Наконец-то стало примерно понятно, как это всё работает. В других статьях про Oberon понять суть сложнее, а здесь отлично разжёвано.
    Концепция интересная, лично мне напомнила Plan9 и Inferno (даже гифка напомнила местный текстовый редактор Acme) — чрезвычайно просто построенные системы, в то же время модульные и легко расширяемые. На мой взгляд, исходный код в них выглядит попроще. Не отрицаю, что у меня в голове могут мешаться понятия «простота» и «привычность».
    • –2
      Феномен взлета популярности языка Go как нам кажется, связан, кроме прочего, с врожденной простотой, которая из упомянутой Вами plan9 взята.
  • +7
    Мне тут коллеги одну полезную нагрузочку дали. Я быстренько с вами проведу беседу о вреде избирательной слепоты, поскольку с нею, проклятою, в нашей индустрии не совсем благополучно. Значит, перво-наперво, прежде чем с нею бороться, с нашим общим врагом – слепотой проклятой, давайте мы как следует обсудим и изучим примеры того, что не видит сообщество, чтобы наверняка знать, как оно может быть на самом деле.
    Потому что трудно проводить беседу о борьбе с избирательной слепотой. Может быть так, – беседу закончим. Прямо приступим к борьбы с ею. Ведь у нас…(заплетающимся языком), одно должны помнить – все мы, как один, должны мы все бороться. Должны с ею, как один. Должны мы все … бороться, один должны как. Мы все…
    Без этого говнеца статья бы смотрелась куда более прилично. А так впечатление становится негативным, к сожалению.

    Правильно ли я понимаю, что нет разделения на kernelspace и userspace? Доступен ли модуль SYSTEM для прикладных программ?

    Также остаётся вопрос, почему работа с SYSTEM.GET/SYSTEM.SET является безопасной, а работа с указателями в Си — нет. Чем SYSTEM.SET отличается от *p = q?
    • НЛО прилетело и опубликовало эту надпись здесь
    • +3
      Правильно ли я понимаю, что нет разделения на kernelspace и userspace?

      Да

      Доступен ли модуль SYSTEM для прикладных программ?

      Да
    • –1
      SYSTEM хоть и встроенный, но все же модуль, а значит можно регламентировать его использование. Хотя самому Вирту это ни к чему.
      • +5
        Конечно, в метод, написанный Виртом, никто и никогда не передаст невалидное смещение. Они не посмеют!

        А насчёт регламентировать — точно так же можно регламентировать в использование raw pointers в виде рекомендаций (что, если не ошибаюсь, делается в MISRA C) или требований языка (как в вашем любимом яисте, яве или C#).
    • +2
      Что-то мне приведенные цитаты напомнили Выбегалло. Сильно так напомнили…
  • +9
    Я, может быть, крайне неправ, но таки напишу. Вдумчивое чтение прекратил на фразе «Главный негативный фактор это забытие, которому бизнес предал источник своих успешных концепций.» Задумался, так может, это в источнике концепций что-то не так, и это что-то не позволило бизнесу (в широком понимании) взять не только концепции, но и систему в целом?

    В конце концов, код, написанный для Ubuntu может быть перенесён и в Debian, а написанный для Android код ядра Linux в итоге помогает другим мобильным ОС на базе Linux. Это только из известных всем примеров.

    Чего я не замечаю? В чём моя избирательная слепота?
    • +1
      Увы, не всегда код из ubuntu без голдовства можно перенсти в mandriva или opensuse. А в Debian переносится хорошо, потому как основан на нем.

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

      Описанная модульная структура очень сильно напоминает структуры, формируемые Java. В разработку и продвижение Java сначало не хило вложилась Sun microsystems, пока пупок не надорвала. Теперь не хило такой гигант как Oracle вкладывается. Может ли Вирт похвастаться такими спонсорами? Сомневаюсь. Хотя очень вероятно, что предложения все таки были, но видимо на кабальных условиях.
    • –6
      Вы просто ищете под фонарем. Историю не знаете, как оно там было в 90-х, не помните. Побеседуйте с Никитой Липским из Эксельсиор Джет, с Русланом Богатыревым, с Недорей, которого тут отправили в глубокий минус они вам раскажут, как оно было и какой ценой досталось текущему поколению, и где там место оберона было.
      • +8
        И опять понеслось… «Да вы не знаете, мы же своей кровью, а вы тут! Тьфу на вас!»
        • –2
          Мы-то при чем? Ну не знаете, да, вы же не знаете.
      • +19
        Если вы спросите меня, я могу сказать, что Оберон-система концептуально очень крутая вещь, я бы даже сказал гениальная вещь! И между прочим, бизнес еще не все концепции (за 30 лет!) смог переварить. Свой трибут Оберон-системе я изложил в выступлении здесь — devday.ru/report/22.

        Но все комментарии здесь, тем не менее, по делу. Главная беда Оберон-системы, что она была сделана крайне непрофессионально, как изнутри, так и снаружи. Да, Вирт писал говнокод, его студенты, которые работали над этим проектом писали говнокод, и вся система была с гусями. Именно, поэтому мой науч.рук., упомянутый выше, Недоря решил в свое время написать коммерческий (читай профессиональный) вариант Оберон-системы — Мифрил (над которой я тоже успел поработать, в том числе успел внедрить на одно предприятие).

        Но при этом молодеже здесь надо учесть, что большинству кода в Оберон-системе — 20+ лет. Тогда просто не было всех этих современных «практик», «методологий», и т.п. «Все было впервые и вновь» (хотя парное программирование было). Вы посмотрите на POSIX или Win API из тех же времен — это же тоже ад и п… ц! Особенно Win API — поубивал бы всех, кто это придумал в Microsoft во главе с Гейтсом.

        Да что там в Microsoft, знаете как мне сейчас стыдно за исторически первый код в упомянутом выше проекте Excelsior JET, написанный мной 19 лет назад (на том же языке Оберон)! Это же говнокодище чистой воды! Мне приходиться закрывать лицо руками, когда я его показываю студентам. Но при этом он живет и работает. Вот недавно туда добавлял поддержку Java 8 (плакал, но добавлял — применил правда пару «практик» и код стал чуть лучше). Но в свое оправдание могу сказать, что за последние лет 10 в этом моем коде, не было найдено серьезных ошибок. При этом при поддержке Java 8, мы нашли 2 доисторических бага (до существования Java) в коде, написанными людьми очень успешными сейчас в редмонде и силиконовой долине (один работает в упомянутом выше Microsoft).
        • +10
          Говнокод есть везде, явная претензия здесь в взаимоисключающих параграфах. Ярые оберонщики здесь утверждают что на обероне любой код — конфетка и можно писать без отладки и все работает само, но когда смотришь на код — все эти ванильные возгласы рушатся в прах.
          А так говнокод есть везде, иногда потому что сильно старый код, а иногда просто потому что так было выгоднее, проще наговнокодить и сделать быстрее, и тогда к моменту как конкуренты выпустят хороший код — у вас уже будет третий релиз, учитывающий все хотелки пользователей и оптимизированный под реалии жизни, чем собственно бизнес и выиграет.
          • –3
            Вы сильно искажаете факты. Никто и никогда не утверждал, что на обероне ЛЮБОЙ код конфетка. Интерпретация графика Свердлова (см. «Арифметика синтаксиса») говорит о том, что оберон-way направлен в сторону минимизации ошибок — на входе в абсолютный вычислитель. Я про это говорю постоянно и когерентно. Стремление к минимизации ошибок совсем не то же, что абсолютное отсутствие ошибок. Но вы как-то странно искажаете суть, не могу понять почему. Может, я как-то не так выражаю свои мысли.

            Минимизация не говорит о том, что на обероне ошибок не бывает.

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

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

            Речь идёт о том, что вот есть такой оберон-way. Он так устроен, такие особенности. Есть такая история. Интересно заглянуть туда и понять, почему оберонщики первыми оказывались там, куда майнстрим доползал спустя многие годы. А сообщество почему-то это воспринимает как надругательство над устоями майнстрима или дурацкий троллинг. Жуть какая.
            • +9
              А я вам говорю, что stateless-код и функциональщина позволяет писать код с еще меньшим количеством ошибок.
              В обероне нет first-class functions, а это сразу говорит о том, что писать на обероне правильные stateless код значительно сложнее, чем, например, в более древнем чем оберон лиспе.

              При том, что мне так никто и не может объяснить в чем состоит «жесткость» оберон-подхода и чем семантика его синтаксиса отличается от семантики еще кучи языков и как она помогает избегать ошибок.

              Вы можете выдать что-нибудь кроме «В обероне простой синтаксис и поэтому программисты на нем допускают меньше ошибок»? Что за oberon-way? В чем его суть?
              • +2
                Ну вот, теперь и вы заклеймили себя как фанат функциональщины и для евангелистов обертона любые ваши суждения потеряли объективность.
                • +6
                  О, прелесть там какая. То есть, код на Обероне должны оценивать только фанаты Оберона.

                  Ну, разумно, в принципе, да.
                  • –4
                    Можете оценивать что угодно, только не нужно строить из себя эксперта с мировым именем. И заходить в выяснительный вираж с этим ощущением тоже не стоит. Могут не понять. Хотя чего бояться, это же Оберон!
                    • +2
                      Зачем мне строить эксперта с мировым именем, если я собираюсь оценивать что-то максимум на уровне публикаций в личном микробложике и в комментариях к статьям здесь, а не на уровне докладов на ACM?

                      Я просто совсем перестаю понимать, зачем тут все эти вот статьи про Оберон, с таким подходом-то.
              • –5
                Почему вы об этом не спросили до того, как слить человеку карму? Кажется, в фильме Жмурки был эпизод, когда герой сначала выстрелил человеку в голову, а потом сказал, что хотел в руку. Вот и современный ИТ так же, сначала делает, а потом вопросы задает.
                • +4
                  А почему вы сразу не начали с объяснения в чем суть oberon-way? Почему аудитория должна вытягивать из вас информацию?
                  • –3
                    То есть, сам виноват?
                    • +1
                      Обвинение жертвы применимо в том случае, когда есть преступление или насилие. А здесь нет ни того, ни другого, есть использование изначально заложенных в сообщество механизмов.
                      • –4
                        Насилие это всегда в каком-то смысле возможность контролировать чужую деятельность или бездеятельность. Когда пацаны приходят в тред с криком «Опять оберонщик запостил очередную хрень» и минусуют, это и есть контроль. Вас много, вы сила. Ну и далее по тексту. Можно за людей не считать. Такое тоже бывает.
                        • +11
                          • –1
                            Проблема в том, что это не выяснение истины, это выяснение того, как принято думать в данном сообществе. При чем тут вообще правильность или неправильность статей, комментариев.
                    • 0
                      К слову, возможности минусовать у меня нет. Да и когда была, я этим механизмом не пользовался.
                      Я просто написал несколько комментариев, которые запустили процесс регуляции.
                • +4
                  Так спрашивали, и неоднократно.
                  • –4
                    До или после? Это не сегодня началось, зачем врать-то?
                    • +4
                      До, до. Я же и просил рассказать (не дословно про Oberon way).
                      • –2
                        И что, вас не устроил ответ и вы нажали минус? Или что, обидели вас?
                        • +1
                          Ответ меня не устроил, но минус я не нажимал. У меня и нажималки-то такой до вчерашнего вечера не было.
                          • –8
                            Ну нажали бы, какая разница.
                            • +6
                              Очевидно, мне есть разница, раз я не нажимаю. А если вам нет разницы, так что ж вы об этом так возмущаетесь-то?
                              • –2
                                Если вкратце, голосование показывает, что Вы выбрали верную сторону. Поэтому нажали лично вы или не вы, плотность огня такая, что говорить с вами становится невозможно, да еще и тренд в беседе развился в задавание вопросов не по теме и возмущение нежеланием отвечать.
                                • +7
                                  Ну то есть не важно, кто и что пишет, и кто и как минусует или плюсует, но всем скажем, что все минусуют, и поэтому ни с кем ни о чем говорить не будем (точнее, будем говорить только на удобные темы).

                                  Крутой подход, чо.
                                  • –1
                                    Зайдите на страницу /comments и посмотрите. Потом вверху на цифру с кармой. Но это так, техническая часть.
                                    И потом, показательно, что я говорю о вещах, идущих наперекор вашим критериям оценки, и этот аккаунт получает ущерб. Сразу начинается разбор полетов, мета-спор о терминах, обсуждение моей личности и прочее хамство. Ну а вы под всем этим соусом убеждаетесь, что в ответах собеседника ересь и дальше свою линию гнете. Ну и вот результат, у вас своя линия, у меня своя. Ни о чем не договорились, над Обероном пошутили, над кодом поныли, болтами померялись. Надеюсь, кто-нибудь хоть Оберон начал изучать, чтобы меня личными примерами уязвить, а то все болтология одна про «код вытеки глаза» и прочее выискивание недостатков.
                                  • –3
                                    Система голосов на хабре не учитывает, кто за что. Поэтому я не могу судить — именно вы мне минусов накидали или кто-то другой.

                                    Обезличенный Хабр (см. οχλος) накидал, и всё тут. Обезличенный Хабр не хочет меня слышать. Вы лично хотите, а обезличенный Хабр не хочет. Я тоже хотел бы вам ответить — в срок, но οχλος не хочет, чтобы я отвечал в срок. Тут код хотят? Замечательно, кто-то хочет, а οχλος не хочет получить от меня код.

                                    Ну и раз такое дело, то, как говорится, давай до свидания. У меня карма -15, я уже почти что окончательный изгой, поэтому считаю вполне этичным снять с себя весь конструктив до исчерпания запаса кислорода :)

                                    Хотите, приходите в oberon@conference.jabber.ru, или на oberoncore.ru — там можно общаться. Здесь — не дают, что поделать. Сам виноват. Охлократия, она такая.
                                    • +5
                                      Вы ответите наконец такому простому быдлу как мне на мои вопросы? Или вы только выеживаться умеете?
                                      Вместо этого комментария вы могли написать ответ или выложить код. И заработать кучу плюсов в карму для продолжения дискуссии.

                                      Кстати, читаем в википедии: «Охлократия — вырожденная форма демократии, основанная на меняющихся прихотях толпы, постоянно попадающей под влияние демагогов.»

                                      Я тут кроме как от оберонщиков никакой демагогии не видел. И вижу, что «толпа» ни за какими демагогами не идет. Наоборот, вас нещадно минусуют.

                                      Поэтому, дорогой мой, прекращайте вые@ываться.
                                      • 0
                                        сам-виноват.txt
                                        • +7
                                          Ну, я может совсем дурак, но я кое-чего не понимаю.
                                          У вас там на счетчике на данный момент — 181 комментарий.
                                          Вы потратили дикое количество времени на детский выпендреж.

                                          Соответственно, я делаю простой вывод — ответов на наши вопросы у вас нет, а сюда вы пришли ради дурацкого самоутверждения. Профессионалы так себя не ведут.
                                          • –6
                                            Вам отвечаешь, а вы строите гимназистку, типа не поднимаете. Плюс тут не дом советов, возможно на ваш вопрос ответили не вам лично. А то может и правда не понимаете, но при чем тут мы и наша карма? :)
                                            • +6
                                              Ткните мне, пожалуйста, пальцем, где ответы на вопросы про разницу в семантике и про версионность модулей.
                                      • –5
                                        На вопросы в стиле «вы можете выдать что-нибудь кроме» возможно отвечать только когда задающий подобные резкости научится сдерживать обороты :) Выдают в кассе, а я вам не касса.

                                        Здесь тон задаёт толпа, а не вы и не я.
                                    • +4
                                      Понимаете ли, в чем дело… кода от вас не было и тогда, когда с кармой все было хорошо.

                                      Более того, мне вот интересно. Я писал oberon87, а отвечаете вы, причем ровно в тех выражениях, как если бы писали вам. Нельзя не задуматься.
                                      • –3
                                        Скорее пожалуйтесь администрации и забаньте двойников навсегда. Тогда исчезнут все поводы для задумывания.

                                        Только я — это я.

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

                                        Это подтвердилось на примере с процедуркой Backup. Назвали её говнокодом и нашли несуществующую ошибку — получив плюсы. Мои возражения получили минуса. Потому что есть тренд обструкции.

                                        Тут говорить не о чем. Толпа определяет, что здесь хорошо, а что нет.

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

                                        Зачем мне вам показывать код обхода коллекции, когда у нас с вами так сильно различаются представления о коллекции en.wikipedia.org/wiki/Container_(abstract_data_type)?

                                        Зачем мне приводить какой-то код, когда люди видят какие-то ошибки там, где их нет?

                                        Я говорю об этом не для того, чтобы обидеть, а чтобы показать условия возникновения confirmation bias. Вы в моём коде увидите что-то своё, исходя из каких-то своих внутренних представлений о вещах, начнёте мне возражать, а поскольку возражения в тренде, получите плюсы просто по линии обструкции, а я по той же линии получу минусов, просто за здорово живёшь.
                                        • +1
                                          A fixed-size table (or array) is usually not considered a collection because it holds a fixed number of items, although tables/arrays commonly play a role in the implementation of collections. Variable-sized arrays are generally considered collections, and fixed-size arrays may likewise considered a collection, albeit with limitations


                                          • –2
                                            По факту даже в джаве они отделены друг от друга, хотя казалось бы, джава просто родила все что можно было обсуждать про «коллекции» в том смысле, в котором их понимает большинство не сильно рефлексирующих людей.

                                            PS, отвечал выше, извините. Кстати, отвечу тут, теперь некорректно считать виртуала виртуалом, ведь других учетных записей подконтрольных одному лицу не осталось. Думаю, админы так специально сделали, чтобы подержать посещаемость интересных Оберон-срачей подольше. Ведь охлос должен отдавать энергию подольше и побольше.
                                            • 0
                                              Ок давайте использовать термин «обход контейнера»
                                            • +8
                                              «охлос», похоже, сразу понял, что вы программировать не умеете, и даже оберон свой толком не знаете (и чем он отличается от компонент-паскаля), не говоря уже о оберон-системе

                                              худо-бедно ответить на вопрос про процедуру Backup смог только akastargazer спустя пол-дня, а до этого мы видели кучу бреда вида «вы что, не видите, что тут написано Х!» в ответ на «почему тут написано Х, это не ошибка?».

                                              «охлос» всё это время поддерживал с вами дискуссию, надеясь, что хоть что-то за душой у вас всё-таки есть. И сейчас ещё надеется, хотя после трёх дней дискуссий уже почти отчаялся

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

                                              Отчего же из вас просто клещами приходится тянуть то, что должно быть в статье и чем вы были как раз должны размахивать, вместо бахвальства «да оберон используют на атомных станциях»? Да если там такой код, как в примерах в статье, я категорически против атомной энергетики!
                                              • –5
                                                Вы увидели только то, что хотели.
                                              • –3
                                                Охлос-то да, сразу всё понял, и сделал выводы. Лично я дискуссии не увидел. Дискуссия — это когда стороны ведут равнозначное общение. Вы — мне, я вам. А когда одна сторона затыкает другой рот, это — не дискуссия. «Ты — молчи, а говорить будем мы» (см. правила хабра), разве это дискуссия?
                                                • +9
                                                  Вы увидели только то, что хотели.
                                                • +7
                                                  Кто вам рот затыкал? Вас просили: покажите код! Вы его показали. Спустя три дня. Десяток примеров. Два топика, тысяча комментариев, десять примеров говнокода, кроме одного примера.

                                                  Просили объяснить: вот мы видим говнокод, а вы утверждали, что язык побуждает писать аккуратно. Как это вообще согласуется? И тут вы утверждаете, что мы ничего не понимаем.

                                                  Конечно, «охлос» сделал выводы, что перед нами — два школьника-фанатика (один из которых под тремя аккаунтами), которые вчера учили паскаль, а потом увидели оберон, который как паскаль, и решили, что раз его в школе не учат, то вот он, Тот Самый Главный Язык. И эти школьники, которые циклы друг от друга отличить не могут и не знают, что такое «цикл с выходом из середины», пытаются учить «охлос» как ему надо жить.

                                                  Я тоже дискуссии не увидел, потому, что вы ни сами на вопросы не отвечаете, ни задать их не можете.
                                                  • –5
                                                    Бред какой-то, я сваливаю.
                                                    • +3
                                                      Вы увидели только то, что хотели.
                                        • +2
                                          Когда вам показывают обход массива на обероне, называя это обходом коллекции, и вам это не фонит, то тут надо понять, что коллекция по определению не массив.

                                          По какому определению?

                                          Зачем мне приводить какой-то код, когда люди видят какие-то ошибки там, где их нет?

                                          Вам не приходит в голову, что ситуация может быть ровно обратной — вы не видите ошибок там, где они есть?
                                        • +5
                                          Вы спорите не с неорганизованной «толпой». Вы пытаетесь спорить с рынком. А у рынка, в отличии от толпы, есть свойство — он берет и использует все что может принести деньги. Вы говорите что этот код — не говнокод а оберон может снизить число ошибок и принести прочие плюшки. Иными словами — вы говорите что на этом можно заработать из разряда «вот оно — бери и зарабатывай». Если бы это было так — рынок бы уже это взял, просто потому что есть конкуренция, не возьмет компания А, возьмет компания Б, выиграет на этом и обскочет А. Но реалии жизни в чем? В том что вы не признаете что говнокод — это говнокод, ошибки называете фичами, а факт того что оберон никому не нужен называете заговором рынка. И да, до сих пор во всех постах ни один из 4х аккаунтов (не знаю уж сколько людей там, но явно не 4) не ответил на простой вопрос — конкретно по фактам — каким образом получается более надежный код? С примером желательно. Но нет же, проще спорить и уходить от темы чем ответить на вопрос.
                                          • +5
                                            А вот тут не соглашусь.
                                            Рынок — эволюционная система, развивающаяся небольшими итерациями, крупные сдвиги парадигм случаются нечасто и не вдруг, а большинство принципиально новых™ достижений отличаются от предыдущих нескучными обоями. С одной стороны, это даёт стабильность, уменьшает риски, позволяет развиваться экстенсивно, переводить количество в качество и задавливать массой, если надо. С другой — обладает классическими проблемами таких систем, вроде ловушки локальных экстремумов, когда невозможно сделать радикальное изменение, которое в дальней перспективе принесёт ощутимый профит, потому что в ближней придётся перестрадать. Вне рынка есть множество замечательных и интересных языков и технологий, множество из которых действительно приносят плюшки вроде повышения выразительности и надёжности (и если нужно, я действительно могу это обосновать, и даже с кодом); и если бы в них влить хотя бы малую долю того, что пошло на развитие и распространение, скажем, джавы, вышла бы конфетка. Но такую тушу разом не сдвинешь, и те из них, кто действительно добился успеха, обычно хотя бы поначалу и частично мимикрируют под своих предшественников. Если нельзя развиваться скачками, приходится делать это мелкими шажочками, окольными путями, но не боясь далеко укатиться после неудачных вложений. Всё как в природе, и это нормально.
                                            • 0
                                              Так если бы оберон появился условно «вчера» — я бы не стал упомянать рынок. Я бы просто говорил о том что аргументы какие-то слабенькие и неправдивые (про почти не нужность отладки, низкое число ошибок и то что пишется все с почти первого раза). Но оберон появился не вчера, не позавчера и не 10 лет назад, первая версия появилась еще до моего рождения, а последняя появилась раньше чем многие другие распространенные языки. Крутого сдвига парадигмы я не вижу, это тот же императивный код, нет каких-то супер серьезных отличий. Выкинули 90% синтаксического сахара — так никто и не мешает на том же C# писать без всего этого синтаксического сахара. Я согласен с тем что рынок не меняется в одночасье, но если он не принял что-то за несколько десятилетий в такой динамичной области как IT, то вероятность того что он примет — крайне мала.
                                              • 0
                                                Я согласен с тем что рынок не меняется в одночасье, но если он не принял что-то за несколько десятилетий в такой динамичной области как IT, то вероятность того что он примет — крайне мала.


                                                Развитие рынка идёт по спирали, то что маловероятно на этом витке, вполне вероятно на следующем. Самые яркие примеры — NoSQL и тонкие клиенты.
                                        • +3
                                          Да нет у вас никакого кода. И понимания, что такое «коллекция» у вас нет. И спрашивал про них я, а не lair.

                                          Иначе, я не вижу реальных причин такого поведения.
                                          Про охлос я тоже умею говорить.
                                          И диагнозы ставить. Вот вам ваш — ru.wikipedia.org/wiki/%D0%AD%D1%84%D1%84%D0%B5%D0%BA%D1%82_%D0%94%D0%B0%D0%BD%D0%BD%D0%B8%D0%BD%D0%B3%D0%B0_%E2%80%94_%D0%9A%D1%80%D1%8E%D0%B3%D0%B5%D1%80%D0%B0
            • +6
              что жёсткость оберон-подхода заставляет писать аккуратно сразу.
              Так где пруфы то? Я пока вижу что можно свободно писать говнокод, чем и пользуются. А как он заставляет писать аккуратно — не понятно ни разу.
        • НЛО прилетело и опубликовало эту надпись здесь
          • +1
            POSIX — прекрасен. Просто так сейчас уже никто API не пишет. И поэтому, когда с ним работаешь, чувствуешь, что он кругом кривой и косой. Что-то обусловлено кривостью Си, но что-то и с точки зрения дизайна не очень — можно было сделать много лучше.
            • НЛО прилетело и опубликовало эту надпись здесь
              • –4
                Цепляться за орфографию или нет? Цепляться или нет?
                • –2
                  Ну ладно, в треде про Оберон нельзя цепляться к противникам Оберона, они ж свои.
                  • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          Кстати вот он habrahabr.ru/post/212887
  • +13
    Я со своей избирательной слепотой никак не могу разглядеть в обероне, например, замыкания. Каковые есть в лиспе, например, хренналиард лет.

    И никак не пойму, чем мне сейчас должен помочь прототип ОС, которую разработал Вирт в качестве proof-of-concept?
    • 0
      Простой механизм замыканий на стеке?
      • +4
        А зачем мне их реализовывать на стеке?
        Благо в обероне сборщик мусора есть, не?

        На совсем крайний случай есть разные выриации спагетти-стека, которые вам до кучи еще и continuations дадут.
        • +1
          Посмотрел бы Вашу реализацию.
          Вообще, тема расширений Оберона раскрыта в проекте Еберон на гитхабе. Там и хост подходящий — js и браузер, расширяй не хочу.
          • +2
            Смотрите, никто не мешает, с поправкой на на то что это экспериментальный интерпретатор:
            github.com/corvusalba/my-little-lispy/blob/master/src/CorvusAlba.MyLittleLispy.Runtime/Closure.cs

            Тупо и в лоб, копирование ссылки на фрейм в котором создано замыкание.
            Подозреваю, что в современном мире в котором в «настоящем» стеке хранят фрейм-поинтеры, что-то подобное реализуется и на более низком уровне.
            • –4
              А я думал, вы на Обероне напишете.
              • +2
                Извините, не имею чести писать на Обероне и до сегодняшнего дня даже не знал, что он кому-то нужен.
                Тем не менее, я посмотрел код по вашей ссылке.
                Судя по github.com/vladfolts/oberonjs/blob/master/src/ob/Scope.ob стек там реализован почти так же как и у меня.
                Соответственно, ровно ничего не мешает добавить в github.com/vladfolts/oberonjs/blob/master/src/ob/Procedure.ob ссылку на внешний скоуп, аналогично тому, как это происходит в моем интерпретаторе.
      • 0
        Принцип адресации переменных аналогичен тому, который у вложенных функциий, которыми замыкания и являются.

        В Delphi, начиная с 2009, статический анализатор выделяет одни локальные переменные на стеке, а другие — на куче, при вхождении в область кода, которая их использует. В принципе, если в теле метода есть несколько замыканий, использующих несвязанные переменные, то можно делать несколько таких объектов. Как точно сделано в последней версии, не знаю. Для значений–замыканий действует счетчик ссылок, и сами эти значения ссылаются на объекты в памяти с теми локальными переменными, которые им нужны, тоже считая ссылки. И что–то похожее сделано в Blocks в Objective-C 2.0 (2009 г.), только переменные, которые можно изменять в блоке, нужно помечать ключевым словом, а непомеченные переменные будут доступны только как const, скопированные при создании экземпляра замыкания. В языке Ада, начиная с 2005, замыкания есть, но только нисходящие, поэтому нет счётчика ссылок. Теоретически компилятор мог бы хранить нисходящее замыкание в виде двух указателей код–данные, но в AdaCore похимичили и обошлись одним указателем на динамически сгенеренный код. Не знаю всех подробностей реализации, но сделано корректно, без TLS каких–нибудь. Делал функцию, которая сначала бурит рекурсией стек на несколько кадров, а потом считает число Фибоначчи, вызывая замыкания из засевших на стеке предыдущих экземпляров себя. Работает.

        Ничего из этого мне не кажется чем–то особо сложным. Сопоставимо со сложностью разработки компилятора.

        Не буду утверждать, что сильно нужна такая возможность. В некоторых стилях написания кода нужна, а в зелёнопоточных (кажется, Active Oberon именно такой) вместо лапши коллбеков может быть обмен сообщениями по каналу. Вот когда нет ни того, ни другого, тогда, конечно, у избалованного современными языками программирования программиста получается фрустрация от невозможности найти что–то привычное на привычном месте.
    • +9
      Замыкания, очевидно, были признаны ненужной функциональностью.
      • +6
        Ну давайте тогда еще и лексические скоупы объявим ненужной функциональностью. Раз уж мы все равно все переменные в начале функции объявляем. WAIT, OH SH--
  • +6
    Не помешала бы небольшая справка по коду. Лично я мысленно споткнулся на коде:
    WHILE p # T.trailer DO

    Что делает оператор #?

    Еще, это, конечно, субъективно, но мне кажется, что код КРИЧИТ НА МЕНЯ. Оберон обращает внимание на регистр ключевых слов? Или это просто вкус у автора кода такой странный?
    • +2
      Что делает оператор #?

      Это не равно (ака !=)
      Еще, это, конечно, субъективно, но мне кажется, что код КРИЧИТ НА МЕНЯ. Оберон обращает внимание на регистр ключевых слов? Или это просто вкус у автора кода такой странный?

      Обращает внимание.
      • 0
        Понятно, спасибо. Да, я мог бы и сам догадаться, зачеркнутое равно :)
        • +2
          А я грешным делом подумал, что это начало однострочного комментария. Это всё python виноват.
          • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          А мне, кстати, понравилось, если забыть, что во всяких шеллах и питонах — это символ начала комментария, то вполне логично смотрится.
    • +1
      Рекомендую при таких непонятках обращаться к документу про язык Оберон, он короткий, www.inf.ethz.ch/personal/wirth/Oberon/Oberon07.Report.pdf
      • +2
        Должен признать, что после документации на С (которая чудовищна как по объему, так и по формулировкам), этот документ читается довольно приятно.

        Раз уж зашла речь — скажите, а есть ли в Обероне такое понятие — «неопределенное поведение»?
        • +3
          В репорте — нет. По факту — есть (репорт не покрывает всего что нужно покрыть, например что будет при целочисленном делении на 0, что будет при разименовыании NIL, что будет если NEW не сможет выделить память, и так далее — таких мест много и они в репорте не описаны).
          • +1
            Вот это уже хуже. А можно посмотреть полную спецификацию на язык?
            • +2
              Более подробного описания чем Oberon report — нет. Подробнее бывают только описания конкретных реализаций языка в разных системах и компиляторах.

              Более того, Project Oberon 2013 использует на самом деле несколько другой диалект языка, не тот который в репорте описан. Поэтому чтобы собрать код из Project Oberon его приходится портировать под компилятор реализаующий то, что описано в Oberon report.

              Поэтому язык Оберон сам по себе представляет в принципе меньший интерес, чем проект целиком. (точнее Оберон-язык представляет интерес, но не для прикладного программиста)
          • +1
            Неопределённое поведение очень легко создать на высоком уровне.

            Например, пишем функцию binary_search, у которой сказано:
            «предусловие: исходный массив отсортирован строго по возрастанию; тщательные проверки в рантайме не делаются, ради производительности; нарушение предусловия ведёт к неопределённому поведению».

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

            Ну и понятно, что GIGO приобретёт характер лавины.
            Невыполненное постусловие является невыполненным предусловием следующего за ним кода, а там, глядишь, и до форматирования диска недалеко.
  • +6
    Лучше чем предыдущие статьи про Оберон, которые были здесь. Спасибо.
    • –8
      Конформнее?
      • +9
        Хоть какие-то технические подробности:)
  • НЛО прилетело и опубликовало эту надпись здесь
    • –3
      А что, не надо доказывать? Это не принято? Иногда кажется что да, и правда у вас не принято доказывать, только интеллигентно оскорблять. И потом непонятно, я Вам мешаю писать на Обероне или что?

      Куриосити конечно пример, однако ж беспилотники тоже летают.
      • НЛО прилетело и опубликовало эту надпись здесь
        • –5
          Тогда вам стоит написать компилятор, который не позволит давать переменным и другим сущностям имена меньше скольки-то там символов. Вот раздолье для стайлгайдов.

          Для джавистов это единственный выход.
          • НЛО прилетело и опубликовало эту надпись здесь
            • –2
              В индустрии ИТ, как и на хабре, есть много смешных и несуразных расхождений между красивыми декларируемыми принципами и суровой жесткой реальностью. В обероне такое расхождение устранено, насколько это возможно. Он угрюмый и прямолинейный, что в описании, что в реализации.
              А на хабре подобное расхождение проявляется примерно так: переход на личности это нехорошо, и по идее, умные люди должны следовать хорошему тону и не делать так, а они делают, и получают одобрение. Расхождение интерфейса и реализации. Нужно знать детали реализации этого сообщества, поэтому красивые абстрактные положения, которые вы описываете свою прекрасную и правильную индустрию ИТ и языки со курлибрекетами, вырождаются, протекают, и ничего кроме смеха не вызвают.
              • +3
                Так зачем же вы начали переходить на личности?
                • –4
                  Тут так принято.
          • 0
            Хорошая идея!
            Если в одной области видимости больше пяти однобуквенных идентификаторов или десяти двухбуквенных — в сад, все в сад!
            Надо посмотреть, как пишутся расширения pc-lint'ов всяких.

            А если кто начнёт хакать и писать identifierA, identifierB, identifierC, ..., identifierZ — то будем сравнивать в префиксном и суффиксном деревьях!
    • –3
      Никто не доказывает, что «на обероне не может быть ошибок», успокойтесь. Это побочный эффект охлократии, когда все галдят и стучат по веткам, то суть разобрать сложно.
      • +10
        Никто не доказывает, что «на обероне не может быть ошибок»,

        … что возвращает нас к вопросу, что же за «надежность» имеют в виду программисты на Обероне, говоря о том, что они выбрали Оберон за надежность.
  • +10
    Всегда с интересом читаю статьи про языки программирования.
    Общеупотребительные языки описываются довольно равномерно: есть статьи, которые ругают за недостатки, и есть которые хвалят за достоинства. А уж комментарии к ним позволяют понять, что и достоинства и недостатки не такие уж и ярко выделяющиеся на фоне остальных языков.
    Новые языки, обычно воспеваются в статьях, а в комментариях, как правило, идёт поиск целевой области применения.
    Вымирающие языки описываются авторами которые любят эти языки. И часто эта любовь слепа. Но не обязательно в плохом смысле. Просто автор или не может объективно сравнить с другими языками, или, не может нормально объяснить, преимущества. И в комментариях справедливо начинается выяснение чем же так пленил его этот язык. Ведь выглядит ужасно(всё заглавными буквами), выглядит непонятно(названия переменных хуже не придумаешь — меньше чем одну букву для имени взять просто нельзя), выглядит быдлокодом… Но для автора, пленённого каким-то свойством языка, это не важно и он просто отмахивается от таких претензий. В результате, и плюсы языка не понятны, и минусы смотряться гипертрофированными.

    • +3
      Хотел написать суть, а написал ощущения. Попробую исправиться:

      Оберон ничем не лучше и ничем не хуже других языков программирования, он просто ещё один язык. У него есть сильные и слабые стороны, область применения, примеры систем/приложений. Надеюсь авторы в конце концов напишут статьи именно об этом.
      • +1
        И вот вопрос для любителей Оберона, чем он лучше ещё более древнего MUMPS?
        • +4
          О да. cast misha_shar53
          • 0
            Да, его статьи тоже довольно фанатичны. Однако, как мне кажется, он более «друждебный».
            Или мне так кажется из-за симпатий к самому MUMPS.
        • +3
          устроим баттл между сторонниками оберона и mumps :)
          • +1
            И кобола, кобола в тред!
            • 0
              Так-с, где там моя копия ISO/IEC 1539-1 (Information technology — Programming languages — Fortran). Она тяжелая и ей удобно кидаться.
  • +4
    Ну что можно сказать по результатам всех этих статей про Оберон…
    Конечно, такие олдскульные системы имеют свое олдскульное очарование. Конечно, хорошо когда есть разнообразие, когда есть альтернативные ОС и языки. И конечно, хорошо что есть люди, которые этим занимаются.
    С тезисом о том, что из-за малого количества языковых фич программы якобы получаются надежнее, я конечно же не согласен. В языке есть все небезонасные фичи — такие как указатели например, значит уровень надежности у него такой же как у Си. И уж конечно отсутствие цикла foreach не делает язык безопаснее:)
    У меня есть свое видение, каким должен быть язык программирования, и оберон скорее антипример. Но единственное что пожалуй стоит взять из оберона — это модульность, не как реализацию а как идею скорее. Во всяком случае это то, чего реально не хватает в С/С++.
    • +2
      А чем эта модульность так уж принципиально отличается от модульности в виде динамических библиотек С/С++? Точка входа есть, динамическая загрузка в память, поиск и выполнение процедур есть, что тоже реализуется библиотечными вызовами линкера. С++ даже метаинформацию кодирует за счет name mangling.

      Единственно, хэш зависимостей, который, по сути, убивает всю суть модульности, если я правильно ее понимаю тут. Т.е. обновился модуль, интерфейс его остался прежним, хэш изменился, а наша программа отказывается почему-то с ним работать, хотя причин для этого никаких нет.
      • +1
        Вот, да. Только хотел задать вопрос про версионность модулей, и вы меня опередили.
      • –6
        Вы не знаете ничего про алгоритм формирования кэша, но уже начинаете нести откровенную ложь про него.
      • +1
        Я имею в виду скорее отсутствие модульности в самом языке, и необходимость использовать архаичную систему инклудов. DLL — это фича операционной системы, от языка тут может потребоваться только поддержка (возможно библиотечная), реализация уже есть во всех ОС.
  • +2
    У меня препод в универе был фанат Оберона, даже написал его компилятор в JVM. В то время мне Оберон показался несколько ограниченной копией Паскаля, к тому же без x86 рантайма. В любом случае, что бы ни говорили, Оберон — это академический язык и всегда таким останется. Чтобы сделать индустриальный язык, нужно «завлечь» пользователя возможностями, сладостями и спецэффектами: поменьше писанины, меньше ограничений и идеологий, вместить в себя все моднючие фичи и парадигмы, цепляться. Также точно глубокий фильм со смыслом никогда не станет кассовым.
    • 0
      Вологда, Сергей Свердлов? :)
      • 0
        Он самый :) Называл Оберон лучшим языком программирования. На лекции по основам методов трансляции, которые он вел, писали парсер к Оберону. А на лабах каждый делал компилятор Оберона во что-то. Как академический язык он действительно был хорош, но не более.
  • +4
    Мне кажется что самая большая беда Оберона в том что он не приносит никаких новых концептуальных идей по сравнению с другими языками. Я не отрицаю версии, что именно он лег в основу Java, хотя и сомневаюсь в столь однозначных параллелях, но это не делает Оберон уникальным. Если на то пошло, то почти все концепции были впервые реализованы в Lisp и Smalltalk. Вот и получается что никакого интереса перехода на Оберон как бы и нет. Все чем он может похвастаться, это компактность описания синтаксиса, но и здесь его переплюнет тот же Форт. А если упирать на надежность, то уж лучше на какой-нибудь Eiffel посмотреть, больше идей принесет.
  • 0
    Закрыв глаза на качество кода, меня заинтересовало это
    Н. Вирт решил дополнить свою систему еще одним компонентом — своим вариантом языка для программирования FPGA, который был назван Lola.
    тоесть код может быть сконвертирован в verilog? Весь? Можно красивый пример типа помигать лампочкой? Вывести текст на экран? Игру тетрис?

    Например я считаю что будущее (к сожалению не близкое) развитие языков програмирования, компиляторов и операционных систем, благодаря постоянному повышению требований к энергопотребления конечных устройств, например интернета вещей, именно в сторону программируемой логики или даже воплощению в железе прямо с завода.
    • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Я могу только показать вам описание языка и менее формальное описание его применения. Вирт сделал его компилятор в системе Оберон, но компилятор портировать на любой другой язык будет легко.
      А пример кода я могу показать не очень «красивый», например четырехбитный счетчик
      MODULE Counter0 (IN clk: BIT; OUT d: [4] BIT);
      REG R: [4] BIT;
      BEGIN
      R := {R.3 ^ R.3 & R.2 & R.1 & R.0, (*R.3*)
      R.2 ^ R.2 & R.1 & R.0, (*R.2*)
      R.1 ^ R.1 & R.0, (*R.1*)
      ~R.0}; (*R.0*)
      d := R
      END Counter0.

      www.inf.ethz.ch/personal/wirth/Lola/index.html
      • 0
        Ой как на verilog похоже.
  • +9
    Уважаемые, kisybi, oberon87, OberonForGood, akastargazer.

    А давайте прекратим заниматься демагогией, тем более мы с вами видимо читали немножко разный набор книг и имеем разный опыт в промышленной разработке. Вместо этого, проведем эксперимент, как положено «в науке» — возьмем более-менее приличную по размеру задачу, и вы ее реализуете на Обероне. А я ее реализую, например, на C#. А кто-нибудь еще реализует на своем любимом языке программирование.

    А потому выставим реалиазации на суд и анализ общественности, пусть рынок рассудит, что лучше читается и что надежнее работает.
    • +1
      Ты под «приличного размера» что имеешь в виду? Алгоритм (тот же TSP, тут же беспилотники недалеко летали?)? Простое приложение (телефонный справочник)? Сложное приложение (иик)?
      • +4
        А мне все равно если честно. Вон, выше тетрис упоминали. В нем и структуры данных, и алгоритмы.
        На голых алгоритмах, имхо, сложно показать некоторые особенности языков, хотя можно и их.
      • НЛО прилетело и опубликовало эту надпись здесь
        • +6
          почему бы просто не написать интерпретатор мини-лиспа? и просто и интересно.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Именно. Так можно сравнить сколько боли и крови потребует реализация этого правила :)
              • +1
                Это не совсем честная задача, так как я ее уже реализовал и успел засветить реализацию в этой теме в ветке про замыкания ;)
                Правда, если подпишется кто-то еще с каким-либо еще ЯП, то можно взять за основу набор тестовых примеров, которые должны работать — github.com/corvusalba/my-little-lispy/tree/master/examples
          • +1
            Боюсь, тогда фанаты лиспа победят с огромным отрывом, написав repl-цикл в одну строчку.
        • 0
          Кстати, хорошая задача.

          (транспорт только лучше определить; я за HTTP, GET-запрос, логин/пароль в query string, ответ статус-кодом 204/401).
        • +1
          Давайте тогда уж STUN сервер. RFC на всех один, ТЗ составлять не надо.
          • –1
            Хорошо, когда есть сетевой стек стандартной либы от Microsoft или Oracle. Можно выбирать задачки по вкусу и перспективности. Шулер из вас так себе.
            • +4
              А для Оберона за все дцать лет его существования никто не написал стандартного модуля сетевого стека?
              • 0
                Написали, но не такой мощный, как у Вас.
                • +4
                  А зачем обязательно «мощный»? Достаточно ведь, чтобы предоставлял реализации для стандартных по нынешним меркам задач.
                  • 0
                    В контексте ветки — достаточно, чтобы он позволял вообще решить указанную задачу (сервер STUN)

                    Это вполне допустимая недоработка: например, хотя сеть в TCL абстрагирована прекрасно (ну очень просто писать TCP-серверы), средств для работы с UDP в нём вообще нет.
            • 0
              Т.е. послать UDP пакет и получить UDP пакет для Оберона слишком сложно?
              • 0
                ну зачем вы травите, ну же, только появились зачатки вменяемой дискуссии
                • +5
                  Я не травлю (честно), я просто в шоке.
      • 0
        для js фреймворков вот такой вариант есть todomvc.com
    • +4
      Добавлю упоминание, чтоб товарищам пришло извещение: kisybi, oberon87, OberonForGood, akastargazer.
      • +5
        Великий Триединый kisybi, oberon87 и oberonforgood попросят денег, уже ж было.
    • –12
      Саморегуляция тут известно как работает, поэтому нет, пожалуй, джавистам и плюсовикам я на суд идти не собираюсь. Если интересно, вы с другом, который вам тыкает, можете реализовать такой проект, как описан в статье.
      Вот, Система Оберон есть, реализуйте такую на C# и потом посмотрим. Не забудьте сами реализовать компилятор для C# и еще язык типа верилога. В общем, этапы я расписал в статье.
      • –7
        А, ну то есть мне даже вариант задачи нельзя выбрать. Неплохо, неплохо.
      • +9
        То есть, вы боитесь что сможете доказать «тупым джавистам», что ваш код хорош?
        Не проблема, тут в комментариях появился pjBooms на которого вы же и ссылались как на авторитета.
        Я не против если он тоже будет в жюри.

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

        По поводу «системы Оберон»: ну вот вам такой же академический проект на C# — ru.wikipedia.org/wiki/Microsoft_Singularity
        • –9
          Пацанский ход.
          На самом деле я уже все себе доказал, а на хабре у меня не та цель, которую вы тут себе придумали. Если хотите, берите любую мою библиотеку, из последних, например JSON парсер и делайте такой же, как умеете, а потом сравнивайте. Мне неинтересно это.

          Короче, у Вас длиннее. ;)
          • +6
            Где ваш парсер можно посмотреть?
            • +3
              Так и не снизошли до моей скромной персоны, не видать мне парсера. Рылом не вышел.
              • +3
                Вы просто денег за просмотр забыли заплатить.
              • +1
                Я так понимаю, что это тот самый парсер. А вот тут обсуждение оного.
                • +1
                  Цикл Дейкстры есть, я спокоен.
                  • +2
                    Самое забавное, что в КП (а Компонентный Паскаль не может называться обероном, согласно www.math.bas.bg/bantchev/place/oberon/oakwood-guidelines.pdf (см. 1.3 Use of the name Oberon ), ибо он не реализует Oberon или Oberon-2 (они модифицировали язык обратно не совместимым образом) нет цикла Дейкстры. Он есть только в последних ревизиях Оберона от Вирта.

                    Соответственно пишущие на КП не могут говорить, что они имеют опыт написания кода на Обероне :-)
                    • –2
                      Вообще-то может, так как отвечает указанному требованию, ибо реализует язык оберон-2. и даже часть экосистемы, модули In, Out и т.д.
                      • +3
                        Э? Кто кого реализует? Кто на ком стоял? ;-)

                        Поясню подробно, по пунктам:

                        • Есть язык Компонентный Паскаль. Это самостоятельный язык, получившийся из языка Оберон-2 после его существенной модификации под требования которые возникли при написании среды BlackBox. Модификации были таковы, что Компонентный Паскаль обратно не совместим с Обероном-2, и с Обероном оригинальным тоже не совместим (то есть модуль писаный на Обероне или Обероне-2 не соберется компилятором который умеет компилировать только компонентный паскаль)
                        • Есть компиляторы компонентного паскаля. Мне их известно два с половиной (половина — это не вполне доделаный компилятор для микроконтроллера 8051): GPCP (https://gpcp.codeplex.com) и компилятор входящий в состав BlackBox (http://blackboxframework.org). GPCP умеет компилировать только КП. Компилятор же в BlackBox имеет два режима, и в одном режиме может компилировать только КП, а в другом режиме только Оберон-2, таким образом это два компилятора в одном. Но это ничего не меняет


                        Тот факт, что компилятор которым вы пользуетесь умеет еще и другой язык, не дает вам права говорить, что вы пишете и на другом языке тоже (если вы пишете преимущественно только на одном из этих двух языков).

                        Приведу пример: компилятор gcc это тоже не один компилятор, а множество компилятором в общей инфраструктурой. Компилирует множество языков. Например написав gcc -c main.cpp оно соберет мне С++ программу, а написав gcc -c hello.adb соберет программу на Аде. Но сам факт использования мною gcc в качестве компилятора не дает мне права говорить, что я пишу и на Аде и на С++. Если я пишу на С++, значит я пишу на С++, какой бы компилятор я ни использовал, и сколько бы языков этот компилятор ни поддерживал.
                        • –3
                          What's New in Component Pascal?

                          Except for some minor points, Component Pascal is a superset of Oberon-2. Compared to Oberon-2, it provides several clarifications and improvements. This text summarizes the differences. Some of the changes had already been realized in earlier releases of the BlackBox Component Builder, all of them are implemented for Release 1.3 and higher.
                          The language revision was driven by the experience with the BlackBox Component Framework, and the desire to further improve support for the specification, documentation, development, maintenance, and refactoring of component frameworks.

                          То есть CP это расширение Оберона-2, но если их не использовать, получится Оберон. Учитывая общую тенденцию импрувментов Оберона, КП — это Оберон в той же степени, в какой и АО.
                          Послушайте, Алексей, ваша позиция в оберон-сообществе известна. Если сейчас вы решили выразить ее и собрать лайков, то вы хотя бы говорите всю правду, а не смешивайте известные факты, и ваши домыслы.

                          А то там уже отдельные умники делают далеко идущие выводы из ваших, скажем так, выдумок.
                          • +3
                            Если их (расширения) не использовать, то Оберона тоже не получится. Получится что-то похожее, но не совместимое с Обероном.

                            Есть код на Обероне, или Обероне-2, чтобы его перенести на КП нужно его портировать. Есть код на КП, чтобы его собрать на компиляторе Оберона его тоже надо портировать. Да, работы будет меньше чем при попытке собрать код на Си компилятором КП, значительно меньше, но она будет.

                            Это говорит о том, что это таки РАЗНЫЕ языки.

                            Поясню на примере: вот есть язык такой Objective-C, вот он (в отличие от например С++) действительно является чистым надмножеством С. Но, однако, даже если я пишу на ObjC постоянно и много, это таки не дает мне права говорить что я имеют богатый опыт написания кода на Си. Просто потому, что при написании проекта на чистом Си будут использоваться другие подходы к проектированию, использоваться будут другие практики нежели при написании на ObjC. Если мне нравится писать на Си, не значит что мне понравится писать на ObjC, равно как и наоборот.

                            Далее, вот есть язык swift — прямой потомок ObjC. То есть имеем C->ObjC->Swift. Так вот, если я пишу на swift это тем более не дает мне права говорить что я пишу на Си.

                            При переходе с КП на Оберон (для пущего эффекта пусть это будет Оберон пследней ревизии, а не Оберон-2) ломка будет покруче, чем при переходе от ObjC на Си.

                            Маленький пример: в КП (да и в старом-старом Обероне, от 1990 года) можно создавать массивы с неизвестной на этапе компиляции длины (то есть аналог int* foo = new int[N]). В последней ревизии Оберона этого уже нет. Можно только массивы с известной длиной на этапе компиляции (int* foo = new int[100500];). И подобных отличий там куча. И это требует других подходов как к проектированию, так и к написанию кода.

                            PS. Но конечно же те, кто называют Оберон паскалем еще больше не правы. Оберон это таки не паскаль. И даже не модула. И не Ада. Оберон это Оберон.
              • +2
                Вот репозиторий: bitbucket.org/oberoncore/yson

                Для нормального просмотра исходников понадобится BlackBox (исходники не в текстовом виде, а в формате документов BlackBox — расширение odc, не путать с форматом документов openoffice): blackboxframework.org
                • +3
                  Исходники не в текстовом виде — это прощай контроль версий? Всё настолько запущено?
                  • +8
                    Сейчас вам напишут, что контроль версий не нужен.
                    • +1
                      Оно ж на битбакете. Контроль версий есть, диффов нет
                      • +7
                        Интересно, как происходит merge. Впрочем чего это я, он же не нужен.
                    • +5
                      Ой, не представляете насколько вы близки к истине. :-)

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

                      В том числе приводилась такое мнение, что контроль версий нужен только если в коде хаос, непонятно кто за какой модуль отвечает (просто потому, что язык какой-то некошерный используется, типа С++ и модулей нет вовсе!!1), а вот если модули распределены по членам комады, у каждого модуля свой интерфейс. Модуль пишется по спецификации и сразу корректно, то и система контроля версий не нужна.

                      Если спецификация меняется, то модуль старый просто выбрасывается, и пишется новый (тоже быстро, целиком и сразу работает). Модули — это такие черные коробочки (BlackBox'инки такие, ага), монолитные и не делимые.

                      Строгость оберона способствует аккуратности написания кода и проектированию системы!

                      Вот примерно такие доводы приводились. И они таки еще в силе в среде оберон-сообщества. Хотя, безусловно, есть и движение за систему контроля версий, люди понимают зачем оно нужно и как с этим работать. Поэтому производится адаптация инструментария под это дело.

                      PS. И да, это еще одна дисциплина спец. олимпиады в оберон-сообществе: срачик на тему должены ли исходники храниться в бинарном, или же таки текстовом виде. Он периодически возникал и затухал и вновь возрождался на протяжении всех 10 лет моего участия в этом деле. За текст — высказывалось возможность использовать богатый набор готовых тулзов сторонних, использовать систему контроля версий и так далее. За бинарь — возможность раскрашивать текст как угодно, применять стили, выделять семантически значимые куски исходника, вставлять в исходник дополнительные материалы иллюстрирующие происходящее (простейший случай — вставить в исходник картинку со схемой работы алгоритма например, или примером результата работы) и так далее. А текст… Это в мейнстриме от нищеты мышления и косности восприятия!

                      Как-то так ;-)
                      • +4
                        Мне это напоминает МММ. «Все все платится» потому что «Всем все платится».
                        И Оберон способствует аккуратности написания кода, потому что оберон способствует аккуратности написания кода.

                        Собственно, что мешает класть конфиг с любыми стилями в текстовом виде рядом с текстовым же исходником? Зачем для этого бинарник?

                        Что мешает вставлять картинки и выделять значимые куски исходника так как это делает Кнут в своем «литературном программировании»?

                        Если модуль — черная коробочка, то где поддержка версионности модулей?
                        Что делать если мне нужен модуль сразу в нескольких версиях? Простой пример — я использую сторонний модуль новой версии и при этом у меня есть еще один сторонний модуль, который использует первый, но более старой версии. Вся модульная система тут же ломается?

                        Собственно, это только характеризует оберон-сообщество с не очень хорошей стороны.
                        Подозреваю, что состоит оно в основном из выходцев из академической среды, очень плохо понимающих реальные задачи и проблемы индустрии. Парадокс блаба как он есть, только в совсем смешном варианте.
                        • +5
                          И Оберон способствует аккуратности написания кода, потому что оберон способствует аккуратности написания кода.

                          Ну, в общем то да. Это очень смахивает на религию, и/или секту.

                          Собственно, что мешает класть конфиг с любыми стилями в текстовом виде рядом с текстовым же исходником? Зачем для этого бинарник?

                          А я думал про это. Не выйдет по одной простой причине — если стиль задается с точностью позиционирования до символа (буквы). Соответственно в файле стилей будет что-то вроде списка пар:
                          {range1 : {color1, style1}}, {range2 : {color2, style2}}, ...
                          так вот, как только кто-то поменяет исходник (например открыв его в каком-нибудь nano, или вообще в онлайн-редакторе в на github), но забудет поменять (предварительно пересчитав) все range в файле стилей, то все, привет-приплыли. Все оформление съедет.

                          То есть это просто так не лечится.

                          Что мешает вставлять картинки и выделять значимые куски исходника так как это делает Кнут в своем «литературном программировании»?

                          Картинки это один из самых простых вариантов того, что там в документе может быть. Там еще могут быть програмные исполняемые модули интерактивные например. Ну то есть по сложности задача упихивания в текстовый формат, примерно как задача придумать адекватный редактируемый текстовый формат для ms-word документа в который внедрено еще и всякое OLE-образное.

                          Но оговорюсь — этим всем (бинарными исходниками) особенно густо страдает именно что BlackBox (и его поклонники), с ЯП Компонентный Паскаль. В Виртовской же Оберон-системе все попроще и там в основном таки текст.

                          В дальнейшем развитии оберонов — в A2 (ранее — Bluebottle), перешли на xml там где это нужно, а там где не нужно (а оно в основном не нужно) спокойно используют plain text. Поэтому с версионностью там все норм. И пишут там немного в другом, нежели Вирт. стиле. Вот, посмотрите: svn.inf.ethz.ch/svn/lecturers/a2/trunk/source

                          Впрочем, в A2 и язык другой — Active Oberon, который более фичаст нежели Оберон.

                          Если модуль — черная коробочка, то где поддержка версионности модулей?
                          Что делать если мне нужен модуль сразу в нескольких версиях? Простой пример — я использую сторонний модуль новой версии и при этом у меня есть еще один сторонний модуль, который использует первый, но более старой версии. Вся модульная система тут же ломается?

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

                          Собственно, это только характеризует оберон-сообщество с не очень хорошей стороны.
                          Подозреваю, что состоит оно в основном из выходцев из академической среды, очень плохо понимающих реальные задачи и проблемы индустрии. Парадокс блаба как он есть, только в совсем смешном варианте.

                          Не, там много разномастного народа. В том числе довольно сильно обиженного из за чего-то на мейнстрим (разные причины). А академическая среда там не представлена представителями Computer Science (я говорю про рускоязычное сообщество сейчас, и то, которое активно общается на тематических форумах обероновских), в основном это физики-математики.

                          Как-то так.

                          У меня же к оберону свой интерес — мною движет, как обычно, чистое любопытство :-) Нарыть ковыряя Оберон можно многое, при желании и при любви ковыряться в старых документах. Бывают интересные находки. О чем я и постараюсь написать :-)
                          • +1
                            Собственно, система для математиков-физиков с форматированием, лайвкодингом и в общем-то всеми перечисленными вами фичами уже есть — Mathematica. И язык там по природе своей функциональный и похож на Лисп, что по идее гораздо ближе физикам, и уж точно позволяет писать более надежный код.
                            • +1
                              Ну, там есть свои нюансы. Например для части физиков важна например скорость работы написанного числодробильного метода. Поэтому слоупочно крутящий циклы матлаб не всегда подходит например (векторизацию никто конечно не отменял, но не все к ней сводится). Особенно если метод новый, уникальный и не сводится к предыдущим.

                              Насколько я понимаю у математики те же проблемы будут (хотя судя по julialang.org у математики все лучше с производительностью чем у матлаба). А вот тот же КП скомпилируется в машкот и более-менее быстро исполнится (хотя фортран или современный С++ его конечно сделает).

                              Так что в принципе, кое-где кое-когда для подобных вещей применение BlackBox'а даже оправдано. Его собственно и используют некоторые ученые в России.

                              Распределенные вычисления тоже делаются на нем вполне.
                              • 0
                                Матлаб, если на нём уметь писать (а уметь писать надо на любом языке), в подавляющем большинстве задач позволяет писать достаточно оптимальный и, что важнее, параллелизуемый код.

                                Я вот не умею писать, как-то на старших курсах в вузе вынужденно делая совместный проект по машинному обучению на матлабе (ок, octave в моём случае) вместо привычных плюсов, написал исключительно медленную и неоптимальную штуку, которая картинку 5000x5000 пикселей обрабатывала (выделение признаков всяких) полчаса. Код на плюсах — меньше секунды.

                                Знакомые физики либо дёргают старый код на фортране, либо пишут новый на плюсах (дёргая какой-нибудь ROOT заодно, кстати), либо изредка ваяют что-то на питоне (но это уже знакомые моих знакомых, среди моего ближайшего круга общения таких нет).
                                Есть вообще один знакомый товарищ, познавший всю мощь темплейтов, за счёт чего (expression templates, например) его код уделывает фортрановский.
                                • 0
                                  Ну, я же про матлаб и векторизацию и написал :-) Сам на нем пишу по работе (у нас стартап, так что и на матлабе писать надо, и приложение под IOS, и код для сервера, так что каждый и жнец и жрец и на трубе игрец). Что-то там можно сделать очень производительным (и с автоматическим распараллеливанием), а что-то нет (приходится на С++ писать модуль).

                                  Вообще, в науке нет какого-то единого инструмента на все случаи жизни, Марков (http://macroevolution.livejournal.com/ ) вон вообще на VisualBasic for Excel писал обработку экспериментов например :-)

                                  Поэтому даже BlackBox вполне себе применяется и некоторыми весьма успешно. Помню Иван Денисов демонстрировал автоматизированный лабораторный журнал на базе BlackBox — действительно весьма удобно получилось.