Experience in using the OberonJS translator to create an interactive model editor

It's fun to create educational models. It's nice to see that a person has understood some complex principle in natural sciences or algorithms by interacting with your program. I am a biophysicist by profession, so I usually have no problems with equations and mathematics, but I have come a long way with the tools for creating visual interactive models. I started making models in Matlab, there are excellent libraries for solving equations, it is possible to easily build graphs. The disadvantage is that the result is difficult to share, and it is quite difficult to do something outside the scope of the developers. More freedom is needed. I also tried to use Flash technology, in those years the technology was still relevant for the web, and the ActionScript language made it possible to make quite busy interactive models.However, the ActionScript programming language itself did not correspond to my strict ideas about harmony and order, and then the Flash technology was completely squeezed out of browsers by the new HTML5 standard ... By that time, I was already actively programming models in the environmentBlackBox Component Builder . This is a Swiss open-source development, quite hermetically isolated from the IDE operating system, which they developed based on the ETHOS operating system... Graphic libraries were fine for me, the performance of the compiler, the speed of execution of the computational code - too. And most importantly, the Oberon language ideally lay on my idea of โ€‹โ€‹how much a programming language should take in the head of a domain specialist. There was no need for any linguistic quirks, it was nice to be in the comfort zone and think about the task. However, in the 21st century, it is very difficult to distribute compiled applications to show students something, or to simply publish models on the Internet. After all, people are simply afraid to run third-party applications, and antiviruses often give false positives. Desktop applications for science and industry are excellent, interactive models for educating people are not.

In 2014, together with the Informatics-21 project, we held an IT conference in Moscow. Oberon systems specialists from all over Russia and even from Belarus came there. Then I was not too lazy to take my old camera, and recorded most of the reports . From Alexei Veselovsky's talk, I learned about the OberonJS translator . The thesis of the report is simple: JavaScript is a very amorphous substance, so developing something large on it is a headache, but if JavaScript is designed with Oberon, there will be significant savings in debugging. Oberonsort of a middle link between the LEGO MINDSTORMS blockbuster and C's unlimited freedom. In general, you can do anything on it, and at the same time the probability of "shooting yourself in the foot" is minimal. The guys then made a demo to show how it works. The code from the CodeMirror window is translated from Oberon to JavaScript directly in the client browser and executed. This would not have caught my eye if Aleksey had not made a demo of how this can be combined with the ProcessingJS framework!

Strict, simple language + advanced graphics in HTML5 = the perfect formula for education, so that users not only see an interactive graphics model, but can easily understand the algorithms at its core. I like to quote Sergey Zalmanovich Sverdlov:

ยซ โ€” . , , . , - - . , ยป.

ยซ !ยป :

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.

However, despite the technical difficulties, conceptually OberonJS helped solve the problem of creating a friendly software designer interface for creating interactive models. Also, an important plus is that the OberonJS translator does not contact the server when creating a program, and the program is also executed on the client side, which means that in the case of scaling, the load on the server should increase slightly.

In the future, it would be interesting to combine OberonJS with the Electron framework.




All Articles