REXX Language, 40. Jahrestag

REXX ist für seine Zeit eine ziemlich alte, fortgeschrittene Sprache. Er erschien laut Wikipedia 1979, das heißt, er wurde kürzlich 40 Jahre alt. Natürlich nicht die altmodischste Sprache, aber ein anständiges Alter.

Rexx ist eine Abkürzung, es bedeutet Restructured Extended Executor, was uns wahrscheinlich auf seine Vorfahren EXEC / EXEC2 verweist. Ich traf ihn im VM / SP 3-Betriebssystem, wo er genau diese Skriptsprachen ersetzte. Dann war es in OS / 2 beliebt, wurde in vielen anderen Betriebssystemen verwendet, und viele Implementierungen und abgeleitete Dialekte wurden erstellt.

Bild

Er hat Habré nicht allzu viel Aufmerksamkeit geschenkt, ich werde versuchen, die Lücken in diesem Artikel zu schließen.

Vorfahren, Ursprünge, Autoren


Die Implementierung in der Originalsprache hatte einen Autor, einen Mitarbeiter von IBM Mike Cowlishaw. Diese Implementierung wurde in S / 360 Assembler geschrieben.

Wikipedia glaubt, dass REXX von PL / 1, EXEC und EXEC2 sowie Algol beeinflusst wurde. Im Großen und Ganzen ja, diese Sprache ist zweifellos in ihrer Syntax - der Erbe von Algol (oder Pascal, wenn Sie so wollen). Das heißt, Schleifen, Blöcke usw. Konstruktionen sind nicht von geschweiften Klammern umgeben, sondern von Schlüsselwörtern, z. B. do / end. Für EXEC und EXEC2 wurde REXX als Ersatz für sie erstellt, und vielleicht hat es nichts mehr mit ihnen zu tun. Aber im Vergleich zu PL / 1 ist REXX viel einfacher und der Zweck der Sprache ist völlig anders.

Wie der REXX-Code aussieht:

/*    1  10 */ sum = 0 do count = 1 to 10 say count sum = sum + count end say "    " sum"." 

Eigenschaften


Was war meiner Meinung nach das interessanteste oder ungewöhnlichste in dieser Sprache?

1. Die Syntax der Sprache ist ziemlich frei, es ist natürlich nicht Fortran. Algol und Pascal sehen am meisten aus. Grundsätzlich auch im Grunde.

Es gibt Operatoren, die für die strukturelle Programmierung typisch sind.

Es gibt Funktionen und Verfahren. Hier ist es etwas ungewöhnlich, dass die Prozedur standardmäßig alle Variablen vor dem aufrufenden Code verbirgt. Einige davon können jedoch mithilfe des Schlüsselkonstrukts expose <Variablenliste> verfügbar gemacht werden.

Das Tippen ist dynamisch. Eine Variable kann zu verschiedenen Zeitpunkten der Ausführung als Zeichenfolge oder als Zahl interpretiert und auch nicht definiert werden (dies kann überprüft werden, obwohl es schief ist). Tatsächlich hat die Sprache einen primitiven Datentyp - Zeichenfolgen, über die arithmetische Operationen ausgeführt werden können, wenn die Zeichenfolge eine korrekte Zahl ist.

Hier ist ein kleines Wikipedia-Beispiel:

 say hello /* => HELLO */ hello = 25 say hello /* => 25 */ hello = "say 5 + 3" say hello /* => say 5 + 3 */ interpret hello /* => 8 */ drop hello say hello /* => HELLO */ 

Dies zeigt, dass die undefinierte Variable in der ersten (und letzten) Zeile in ihrem Namen in Großbuchstaben berechnet wird. Auf diese Weise können Sie auf Unsicherheit prüfen.

Die Interpretationsaussage ist ein Analogon zu dem, was heute gewöhnlich als eval bezeichnet wird.

Die Fehlerbehandlung ist Basic vielleicht am ähnlichsten:

 signal on halt do forever ... /*   */ end halt: /* .    halt,    */ exit 

Dies ist die Programmabschlussverarbeitung (per Taste vom Terminal). Neben dem Anhalten gibt es noch andere „Signale“, darunter beispielsweise die Syntax (Syntaxfehler im interpretierten Code). Ich erinnere mich nicht, dass ich es praktisch angewendet habe, aber es ist ziemlich logisch, die syntaktische Korrektheit zu überprüfen, zum Beispiel, was der Interpretationseingabe zugeführt wird.

2. Es gab keine regulären Ausdrücke, wie wir in Perl sagen (es blieben jedoch fast 10 Jahre vor Perl). Das Konzept der regulären Ausdrücke tauchte früher auf, und es handelte sich sicherlich bereits um das Grep-Dienstprogramm. Stattdessen gab es den Analyseoperator, ein vereinfachtes Analogon von Stammgästen, mit der Substitution von Gruppen in Variablen.

 parse [origin] [template] 

Das heißt, Wir analysieren den Inhalt der Quelle (der ein Argument für eine Funktion, eine Variable, einen Ausdruck usw. sein kann) auf Übereinstimmung mit der Vorlage. Die Vorlage kann Literale enthalten, die die Werte und Variablen, die den Wert von der Quelle erhalten haben, zwischen diesen Trennzeichen trennen. In gewisser Weise sieht es aus wie Gruppen in regulären Ausdrücken.

 fio = ', ' parse var fio firstName ',' LastName say firstName say LastName 

Dies ist natürlich viel einfacher als reguläre Ausdrücke, schon allein deshalb, weil es keine Metazeichen wie \ d, keine Wiederholung in Form von * oder +, keine Alternativen, nichts dergleichen gab.

3. Rexx verfügte über eine API, mit der es nicht nur für das Betriebssystem (CMS), sondern auch für jedes andere Programm, das diese API unterstützte, als Skriptsprache verwendet werden konnte. Das heißt, Tatsächlich war es eine DSL-Schriftsprache. Wahrscheinlich einer der ersten. Gleichzeitig könnte die Laufzeit den Interpreter implementieren und ihm zusätzliche Funktionen oder Befehle zur Verfügung stellen, die als Ergebnis des Programms verfügbar sind.

Es sah ungefähr so ​​aus: Als er den XEDIT-Texteditor startete, suchte er irgendwo auf zugänglichen Datenträgern nach einer Datei namens PROFILE XEDIT, die ein REXX-Skript enthielt. Dieses Skript kann Funktionstasten zuweisen und zusätzliche Befehle definieren, die von XEDIT verfügbar sind. In Bezug auf die Bedeutung ist es heute zum Beispiel .bashrc am nächsten. Oder sein Analogon für vim.

Dementsprechend könnten die in PROFILE XEDIT definierten REXX-Prozeduren und -Funktionen Editorbefehle ausführen und auf Informationen über geöffnete Dateien zugreifen, einschließlich des Inhalts der Datei selbst.

4. Für die Übertragung von Befehlen an die Host-Umgebung (z. B. das Betriebssystem oder beispielsweise einen Texteditor) war keine spezielle Syntax erforderlich. Stattdessen wurden alle Ausdrücke, die Rexx nicht erkannte, an die Ausführung übergeben. Um den Betriebssystembefehl in das Skript zu schreiben, war es ausreichend, ihn in Anführungszeichen zu setzen, zum Beispiel:

 'list * * * (stack' 

Ein Befehl kann durch Verketten von Zeichenfolgenkonstanten und -variablen erstellt werden. Das Symbol der Verkettungsoperation war einfach ein Leerzeichen.

Um den Befehl an eine andere Anwendung zu übertragen, gab es eine Adressanweisung. Wenn Sie beispielsweise den XEDIT-Texteditor in der Umgebung verwenden, müssen Sie Folgendes tun, um nicht den XEDIT-Befehl, sondern das Betriebssystem (CMS) auszuführen:

 address cms 'list * * * (stack' 

5. Das CMS implementierte eine API für den Zugriff auf den OS-Befehlsstapel, mit der Rexx auch Daten austauschte. Der obige Befehl gab die resultierende Liste der Dateien an den Stapel zurück, von wo aus das Skript sie abrufen und eine Zeile als Standardeingabe lesen konnte. In mancher Hinsicht ähnelt dies Unix-Pipes, unterscheidet sich jedoch etwas von diesen. Eine Pipe ist immer noch ein Bytestrom, und ein Stapel in CMS ist eine Sammlung von Zeichenfolgen. Im Allgemeinen ist dies ein typischer Unterschied zwischen der Ideologie von Unix und dem Betriebssystem von IBM, bei dem die Dateien weitgehend auf feste oder variable (aber gleichzeitig bekannte) Längen ausgerichtet waren.

6. Als Teil der API können Anwendungen auf Rexx-Skriptvariablen zugreifen und diese lesen und ändern. Dies war eine weitere Möglichkeit, Daten auszutauschen.

7. Eine ziemlich effektive Arithmetik beliebiger Genauigkeit wurde implementiert. Beliebig - das bedeutet zum Beispiel 100 Zeichen oder mehr - wie viel Speicher ausreicht.

8. Speicherverwaltung - automatisch. Es gab zwar zum Beispiel einen Drop-Operator, um den Wert einer Variablen (eines assoziativen Arrays oder seiner Elemente) zu löschen, aber auf jeden Fall hatten Sie nichts mit Zeigern und Blockgrößen zu tun.

9. Als einzige, aber gleichzeitig sehr universelle Datenstruktur gab es assoziative Arrays, die beispielsweise Javascript sehr ähnlich waren. Das heißt, wenn Sie a.1 schreiben, ist dies ein Element des Arrays a mit Schlüssel 1. Wenn Sie ab schreiben, ist dies ein Element mit Schlüssel b.

Angenommen, Sie fügen dem Wörterbuch ein Wort hinzu:

 add_word: procedure expose dictionary. parse arg w n = dictionary.0 + 1 dictionary.n = w dictionary.0 = n return 

Die Wörterbuchvariable in diesem Fragment ist unser assoziatives Array. Die Prozedur gibt dieses Array nicht zurück, macht es jedoch von außen zugänglich (mithilfe von exponieren). dictionary.0 speichert die Anzahl der Elemente im Wörterbuch (dies ist nur eine Konvention, und wie Sie sehen können, führen wir sie selbst aus), dictionary.n ist das n-te Wort des Wörterbuchs.

10. Die Sprache hatte keinen einfachen Zugriff auf den Speicher oder die OC-API, obwohl es im Prinzip durchaus möglich war, etwas Ähnliches dafür zu schreiben. Ich kann einige Beispiele für Spracherweiterungen nennen, eines wurde für die Arbeit mit einer SQL / DS-Datenbank (DB2) entwickelt und das zweite für den Austausch von Nachrichten zwischen virtuellen Maschinen in VM / SP. Das heißt, alles, was Sie als DSL arrangieren können, kann im Prinzip implementiert werden.

REXX-Unterstützung in Anwendungen


Zusätzlich zum CMS selbst unterstützte REXX sofort den Haupt-XEDIT-Texteditor. Sie konnten damit Makros auf REXX schreiben, die an Funktionstasten aufgehängt werden konnten, oder Befehle entweder über die Befehlszeile oder als sogenannte aufrufen. "Präfix" -Befehle, die neben den Zeilen des Textes eingegeben wurden und deren Bearbeitung ermöglichten. Mit dem Befehl d konnten Sie beispielsweise die Zeile löschen, neben der Sie eingegeben haben, es gab Befehle zum Kopieren oder Verschieben und andere. Ein Makro unter REXX kann beispielsweise eine Zeichenfolge in Groß- oder Kleinbuchstaben konvertieren.

Die zweite Anwendung, die die Sprache in meinem Speicher unterstützte, hieß DMS (Display Management System für CMS (DMS / CMS)) und war ein Tool zur Entwicklung interaktiver Programme, die aus Panels bestanden. In REXX war es möglich, eines der vorgezeichneten Formulare auszuwählen, seine Felder mit Werten zu füllen und auf dem Bildschirm anzuzeigen. Nachdem der Benutzer eine Funktionstaste gedrückt hatte, erhielt das Programm die Steuerung zurück und die REXX-Variablen enthielten die Werte der geänderten Felder. Das nächste funktionale Analogon von DMS würde ich HTML und seine Formen nennen. Und in Bezug auf die Komplexität (Einfachheit) der Entwicklung war dies vielleicht sogar ein wenig einfacher, obwohl HTML sicherlich in Bezug auf Ausdrucksmöglichkeiten gewinnt (zum Beispiel gab es in DMS überhaupt keine Bilder, was für Textterminals verständlich ist).

Eine weitere erwähnenswerte Anwendung hieß ISPF. Aber es war bereits viel breiter als DMS, und es ähnelte eher der integrierten Entwicklungsumgebung, wie sie jetzt aussieht, angepasst an Textterminals. Und ja, der Texteditor wurde auch in REXX programmiert.

Beginnend mit VM / SP 6 führte CMS Tools ein, mit denen virtuelle Fenster variabler Größe auf dem Terminalbildschirm erstellt und Text darin angezeigt werden können. Die entsprechende API erschien für REXX (genauer gesagt, es war hauptsächlich eine Erweiterung von REXX).

Eine weitere sehr interessante Anwendung von REXX war der sogenannte Auto-Operator. Dies war eine Anwendung, die in der virtuellen Maschine des Betriebssystembetreibers ausgeführt wurde und alle Nachrichten empfing, die normalerweise an das Terminal des Bedieners kamen, und deren programmgesteuerte Verarbeitung ermöglichte. Befehlshandler - REXX-Skript. So war es beispielsweise möglich, vielen Personen einige Bedienerfunktionen zu geben, für die diese Personen einfach Nachrichten an die virtuelle Maschine des Bedieners sendeten, und der Handler (im Namen des privilegierten Benutzers, des Bedieners) einige Befehle für sie ausführte. Nun, ich habe zum Beispiel Festplatten- oder Banddatenträger in das System eingebunden.

Die Möglichkeiten waren jedoch nicht auf so einfache Dinge beschränkt. Beispielsweise können Sie keine Nachricht an den Benutzer senden, wenn diese nicht im System vorhanden ist. Senden Sie es an den automatischen Operator, es speichert es in der Warteschlange und sendet es dann (nachdem Sie eine Nachricht erhalten haben, dass der Benutzer angemeldet ist) an wen es benötigt wird. Tatsächlich ist dies eine einfache E-Mail-Implementierung mit einem kleinen REXX-Skript.

Auswirkungen auf die Entwicklung


Ich würde sagen, dass wir mit dem Aufkommen von REXX in VM / SP 3 begonnen haben, einen wesentlichen Teil dessen zu schreiben, was zuvor beispielsweise auf PL / 1 geschrieben wurde. Dies ist eine ziemlich leistungsfähige und gleichzeitig immer noch einfache Sprache, mit der Sie relativ große Anwendungen richtig strukturieren können. Zunächst wahrscheinlich aufgrund seiner Integrationsmöglichkeiten, als es als DSL verwendet wurde.

Die Fähigkeit, Datenbankabfragen (SQL / DS) zu erfüllen, Bildschirmformulare anzuzeigen, Dateien zu lesen und zu schreiben, deckt einen wesentlichen Teil der Anforderungen an die Entwicklung von Geschäftsanwendungen ab.

Offensichtlich mochten viele Leute die Sprache. Er war in OS / 2, war auf Amigami, unter Windows und vielen anderen wo. Später gab es Object REXX mit Objekterweiterungen und NetREXX für JVM. Die Hauptsache ist, dass diese Sprache noch lebt. Und im Allgemeinen würde ich, wenn ich heute entscheiden müsste, worüber ich Skripte schreiben möchte, zum Beispiel Rexx, bash, die vollständig vogelsprachliche cmd.exe - definitiv die erste wählen würde. Aber im Vergleich zu bereits neueren Sprachen wie Perl, Python und vielen, vielen anderen ist nicht alles so offensichtlich. Angenommen, die Idee von Rexx, Befehle und Variablen zur Laufzeit zu übertragen, war gut - aber die Idee, beispielsweise COM, mit seiner Objektorientierung, ist noch funktionaler.

Trotz der letzten 40 Jahre wird es immer noch in IBM z OS verwendet, und laut Wikipedia wurde vor kurzem um 2012 ein Sprachbuch veröffentlicht. Für verschiedene Betriebssysteme ist es durchaus möglich, Live-Implementierungen herunterzuladen und selbst auszuprobieren.

Source: https://habr.com/ru/post/de457182/


All Articles