[Open source, JavaScript, HTML, Canvas, Инфографика] Опыт использования транслятора OberonJS для создания редактора интерактивных моделей

Автор Сообщение
news_bot ®

Стаж: 6 лет 4 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
30-Ноя-2020 15:30

Занимательное дело — создавать образовательные модели. Приятно видеть, что человек понял какой-то сложный принцип в естественных науках или алгоритмах, взаимодействуя с твоей программой. По профессии я биофизик, так что с уравнениями и математикой обычно у меня нет проблем, а вот с инструментарием для создания наглядных интерактивных моделей — прошел достаточно длинный путь. Начинал делать модели в Matlab, там отличные библиотеки для решения уравнений, есть возможность легко строить графики. Недостаток в том, что результатом сложно поделиться, и достаточно сложно сделать что-то выходящее за рамки, предусмотренные разработчиками. Нужно больше свободы. Также пробовал использовать технологию Flash, в те годы технология была ещё актуальна для web, и язык ActionScript позволял делать достаточно занятые интерактивные модели. Однако сам язык программирования ActionScript не соответствовал моим строгим представлениям о гармонии и порядке, а потом и вовсе технология Flash была вытеснена из браузеров новым стандартом HTML5... К тому времени я уже активно программировал модели в среде BlackBox Component Builder. Это швейцарская open-source разработка, достаточно герметично изолированная от операционной системы IDE, которую они разработали на базе операционной системы ETHOS. Графические библиотеки меня вполне устроили, производительность компилятора, скорость выполнения расчётного кода — тоже. И главное, язык Оберон идеально лёг на моё представление о том, сколько вообще язык программирования должен занимать в голове у специалиста предметной области. Не нужны были какие-то лингвистические причуды, было приятно находиться в зоне комфорта и думать о задаче. Однако в 21-веке распространять компилированные приложения, чтобы показать студентам что-то, или просто выкладывать в Интернете модели — очень сложно. Ведь люди просто боятся запускать сторонние приложения, и антивирусы часто дают ложно-положительные срабатывания. Десктоп приложения для науки и производства — отлично, интерактивные модели для просвещения людей — нет.В 2014 году вместе с проектом Информатика-21 мы проводили IT-конференцию в Москве. Туда приехали специалисты по Оберон-системам со всей России и даже из Белоруссии. Я тогда не поленился взять свою старенькую камеру, и [url=https://www.youtube.com/playlist?list=PLoKr-_Vv5yq7KbxkSITmtanYElP73xsxU ]записал большую часть докладов[/url]. Из доклада Алексея Веселовского я узнал про транслятор OberonJS. Тезис доклада простой: JavaScript — это субстанция весьма аморфная, так что разрабатывать на нём что-то крупное — головная боль, а вот если JavaScript оформить Обероном, будет существенная экономия на отладке. Оберон в некотором роде среднее звено между блочным программным конструктором LEGO MINDSTORMS и безграничной свободой Си. В общем, сделать можно на нём что угодно, и при этом вероятность «выстрелить себе в ногу» минимальна. Мужики тогда сделали демку, чтобы показать, как это работает. Код из окошка CodeMirror прямо в клиентском браузере транслируется из Оберона в JavaScript и выполняется. Это бы меня не зацепило, если бы Алексей не сделал демонстрацию, как это можно объединить с фреймворком ProcessingJS!Строгий простой язык + продвинутая графика в HTML5 = идеальная формула для образования, чтобы пользователи не только видели интерактивную графическую модель, но и могли легко понять алгоритмы в её основе. Люблю приводить цитату Сергея Залмановича Свердлова:
«Оберон — идеальный язык для изучения программирования. Он прост, понятен, неизбыточен. При этом содержит необходимые и достаточные средства структурного, объектно-ориентированного и модульно-компонентного программирования. Оберон великолепно подходит и для изучения методов трансляции, и как объект и как инструмент».
Модуль «Привет Мир!» на Обероне будет выглядеть следующим образом:
MODULE HelloWorld;
IMPORT Log;
BEGIN
Log.String("Привет Мир!"); Log.Ln
END HelloWorld.
Синтаксис Оберона очень напоминает язык Паскаль, однако не стоит их путать.Взяв за основу транслятор OberonJS, я начал экспериментировать, как можно сохранять модули в базе данных, как это отобразить в интерфейсе на сайте. Идея такая, чтобы возможно было хранить код на Обероне в базе данных, загружать в CodeMirror у клиента в браузере, транслировать онлайн и выполнять. Как выглядит интерфейс, который у меня получился, вы можете посмотреть на примере модели самоорганизующейся карты Кохонена. Автор транслятора Владислав Фольц помог сделать систему русификации сообщений об ошибках в коде и вывод точной позиции. В итоге удалось объединить систему хранения модулей с системой учётных записей пользователей и довести сайт до состояния MVP, чтобы получить поддержку моего университета для развития данного гуманитарного проекта.Набор инструментов для создания моделей свелся к шести модулям: Log для вывода текстовой информации из программы, Math для математических функций, Strings для работы со строками, Draw для рисования, Forms для создания элементов управления и Plot для создания графиков. Последние два модуля пока достаточно сырые, работа над ними продолжается.Вместо библиотек ProcessingJS, поддержка которых была остановлена, теперь используется библиотека p5.js. Мы оборачиваем вызовы к библиотеке и JavaScript коды в процедуру JS.do, а в остальном — используем синтаксис Оберона. Так как в Обероне запрещено автоматическое преобразование типов, то между REAL и INTEGER преобразование осуществляется процедурами FLOOR и FLT. Чтобы уменьшить вызов явных преобразований, для рисования используется два типа процедур: первые с действительными аргументами, вторые с целыми. При этом, чтобы избежать проблем с размытием линий, для целочисленных вызовов к координатам автоматически добавляется половина пикселя:
MODULE Draw;
IMPORT JS;
...
PROCEDURE Line*(x0, y0, x1, y1: REAL);
BEGIN JS.do("Instance.line(x0,y0,x1,y1)")
END Line;
PROCEDURE LineInt*(x0, y0, x1, y1: INTEGER);
BEGIN JS.do("Instance.line(x0+0.5,y0+0.5,x1+0.5,y1+0.5);")
END LineInt;
...
END Draw.
Звездочка * обозначает экспорт процедуры за пределы области видимости модуля. Instance создаётся в момент запуска модуля через процедуру Draw.Start, и необходимые нам процедуры присваиваются, заменяя стандартные колбэки библиотеки p5.js, так как показано на примере процедуры InnerDraw ниже.
MODULE Draw;
TYPE
ProcessingType* = POINTER TO RECORD END;
VAR
Instance: ProcessingType; focus, started: BOOLEAN;
...
PROCEDURE InnerDraw;
BEGIN
IF DrawProc # NIL THEN
  TrackMouse;
  DrawProc;
  IF FormDraw # NIL THEN FormDraw END
END
END InnerDraw;
PROCEDURE Start*;
BEGIN
ASSERT(~started);
JS.do("let sketchProc = function(p){
p.preload=Preload;
p.draw=InnerDraw; p.setup=InnerSetup;
p.keyPressed=InnerKeyPressed; p.keyTyped=InnerKeyTyped;
p.mousePressed=InnerPressed; p.mouseReleased=InnerReleased;
p.mouseOver=InnerOver; p.mouseOut=InnerOut;
Instance=p;
}");
JS.do("var processingInstance = new p5(sketchProc);");
JS.do("Instance.colorMode(Instance.RGB, 255, 255, 255, 1);");
JS.do("removeSketch = function() { Remove(); }");
focus := FALSE;
started := TRUE
END Start;
END Draw.
Такой подход позволяет полностью изолировать вызовы JavaScript кода при создании интерактивных моделей, так что пользователь работает только с шестью модулями, описанными выше. Когда программа готова, её возможно опубликовать. Если открыть исходный код опубликованной страницы, то мы увидим работу транслятора:
...
var Init = function (Log){
function Do(){
  Log.String("Привет Мир!");
  Log.Ln();
}
Do();
}(Log);
Для дополнительной безопасности транслятор добавляет проверку выхода за границы массивов, что не предусмотрено в JavaScript. К примеру для определения длины строки по дубовым требованиям:
MODULE Strings;
IMPORT JS;
PROCEDURE Length* (s: ARRAY OF CHAR): INTEGER;
VAR i: INTEGER;
BEGIN i := 0;
WHILE (i < LEN(s)) & (s[i] > 0X) DO INC(i) END
RETURN i
END Length;
...
получим результат трансляции:
var Strings = function (JS){
function Length(s/*ARRAY OF CHAR*/){
  var i = 0;
  i = 0;
  while (true){
    if (i < s.length && RTL$.charAt(s, i) > 0){
      ++i;
    } else break;
  }
  return i;
}
Проверка charAt осуществляется в специальном наборе функций рантайма:
var RTL$ = {
    charAt: function(s, index){
        if (index >= 0 && index < s.length)
            return s.charCodeAt(index);
        throw new Error("index out of bounds: " + index);
    },
...
}
Поскольку такая проверка обходится достаточно дорого по вычислительным ресурсам, то приходится предусмотреть возможность отключения проверки для программ, интенсивно использующих массивы. Наглядно разница в скорости выполнения видна в программе сортировки вставками. В настоящий момент — это главная проблема проекта. Уверен, что среди читателей, найдётся немало специалистов по JavaScript. Может быть кто-то подскажет, как сделать проверку выхода за границы массива эффективной. Вторая проблема — ввод данных в рисованные поля ввода с телефона. Нужно как-то предусмотреть, чтобы клавиатура появлялась в момент, когда пользователь нажал на определённую область холста HTML5.Однако не взирая на технические сложности, концептуально OberonJS помог решить проблему создания дружелюбного интерфейса программного конструктора для создания интерактивных моделей. Также немаловажный плюс в том, что транслятор OberonJS при создании программы не обращается к серверу, и выполнение программы также происходит на стороне клиента, а значит, в случае масштабирования, нагрузка на сервер должна возрасти незначительно.В перспективе было бы интересно объединить OberonJS с фреймворком Electron.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_open_source, #_javascript, #_html, #_canvas, #_infografika (Инфографика), #_obrazovanie (образование), #_oberon (оберон), #_html5_canvas, #_javascript, #_modelirovanie (моделирование), #_open_source, #_javascript, #_html, #_canvas, #_infografika (
Инфографика
)
Профиль  ЛС 
Показать сообщения:     

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

Текущее время: 02-Июл 18:45
Часовой пояс: UTC + 5