Die Notwendigkeit, eine neue Sprache zu entwickeln und die Syntax einer der vorhandenen gemeinsamen Programmiersprachen nicht zu kopieren, beruht auf einer Art originellem Konzept, über das wir heute sprechen werden. Unserer Meinung nach ist der Prozess der Erstellung und Umsetzung des Konzepts einer neuen Sprache selbst eine faszinierende und informative Geschichte für alle, die sich für die Pragmatik von Sprachen interessieren.
Wir gehen davon aus, dass der Leser zum Verständnis des vorgestellten Materials mit der Syntax und Semantik mehrerer gängiger universeller Programmiersprachen vertraut ist.
Beißen Sie nicht in meinen Finger, schauen Sie, wohin ich
Warren S. McCulloch, 1960er Jahre zeige
Erste Erklärung des Problems
Zunächst haben wir uns die Aufgabe gestellt, die Technologie der autonomen Erzeugung interaktiver Aufgaben für die Entwicklung der menschlichen Intelligenz zu implementieren, die sich an seine Erfolge und Misserfolge anpassen wird. Das heißt, wenn eine Person eine Folge von Rätseln erfolgreich löst und Spiele erfolgreich weitergibt, baut diese Technologie ihre Algorithmen neu auf, sodass eine Person Rätsel mit neuen, komplexeren Bedingungen und unvorhersehbaren Versionen von Spielen lösen kann, die nie genau wiederholt werden. Im Falle eines Misserfolgs bringt diese Technologie eine Person in bereits vertraute Positionen zurück, um das Programm ihrer Fähigkeiten und ihrer Bereitschaft, einen neuen intellektuellen Aufstieg durchzuführen, neu zu strukturieren. Im Kern leistet das adaptive Programm hier den gleichen Job wie ein erfahrener Personal Trainer im Sport.
Im Allgemeinen wurde diese Aufgabe mit einigen Einschränkungen bereits 2018 von der Helius- Anwendung gelöst - voller Leben , die im App Store zu finden ist .
Bei der Implementierung des Helius-Konzepts haben wir erkannt, dass wir eine integrierte algorithmische Skriptsprache benötigen, deren Auflistung möglich ist, um den nächsten Schritt zu unternehmen und eine grundlegend neue Klasse adaptiver Anwendungen zu implementieren, die ihre Architektur vollständig an die menschlichen Fähigkeiten anpassen kann wird gleichermaßen erfolgreich in Textform sowohl von der Anwendung selbst als auch von einer Person generiert oder kann von einer Person oder einem anderen Programm basierend auf dem bereitgestellten Code als erster Prototyp geändert werden .
Wir formulierten die Hauptanforderungen und kamen schnell zu dem Schluss, dass ein Konzept, das sich darauf konzentriert, die kreativen Bedürfnisse eines Entwicklers auszudrücken, in keiner der gängigen Sprachen sehr gut modelliert ist, da unser Ziel mit einem gewissen Witz darin besteht, Menschen zu programmieren, nicht Computer.
Da es für ein gut gestaltetes intellektuelles System gleichermaßen „bequem“ ist, die Syntax einer konsistenten Sprache in irgendeiner Form zu generieren, um die Kommunikationssprache zwischen „künstlicher“ und „natürlicher“ Intelligenz zu verwenden, ist es logisch, den traditionellen algorithmischen Code zu verwenden, um ihn für menschliche Denkmuster so bequem wie möglich zu machen vertraut mit den gängigen Sprachen, deren Vorfahr Algol war. Sie sind Nachkommen entlang der Linie von Pascal (Ada, Modula) und C (C ++, Java, Swift). Unser Konzept, Abstraktionen zu konstruieren und Klammern zu beachten, entspricht jedoch dem Geist von Scheme (Lisp), und die Integration von Programmierumgebungsbefehlen in die Ausdrucksmittel der Sprache entspricht den Ideen von Skriptsprachen, Vintage BASIC für die ersten Mikrocomputer und dem Oberon-Projekt - dem System von Niklaus Wirth.
Unser ursprüngliches Ziel ist es auch, eine einfache und bequeme algorithmische Sprache für die schnelle Programmierung von Gedankenspielen und Rätseln mit einer Lernkurve für Anfänger von ein bis zwei Stunden bereitzustellen. Gleichzeitig haben wir das visuelle Design von Anwendungsobjekten im Sinne von Scratch oder das Prototyping von Spielen im Skript und in den visuellen Editoren grundsätzlich außer Acht gelassen. Dies lenkt unserer Meinung nach von der Kreativität und dem Ausdruck der eigenen Ideen ab, da kreative Anstrengungen eher durch sorgfältiges Studium und Transformation von [grafischen] Objekten ersetzt werden. Wir schlagen vor, diese Arbeit in Zukunft als Schulung für Algorithmen für intelligente Agenten anzubieten.
Infolgedessen werden wir den Zweck der Sprache als formulierenAustausch von Algorithmen zwischen künstlicher und natürlicher Intelligenz, gemeinsame Programmierung von Aufgaben (Spiele und Rätsel) für sich und andere, freier Austausch von Programmtexten.
Hi Welt
Bevor wir die Hauptpunkte für die Erstellung der Syntax der Sprache diskutieren, präsentieren wir drei Kurzcode-Schnipsel. Beginnen wir mit dem traditionellen Begrüßungsprogramm:
PRINT “Hello world!”
Wir sehen, dass unsere Sprache einen Skriptcharakter hat und eine schnelle Interpretation voraussetzt. Der Druckbefehl wird in Großbuchstaben geschrieben, und auf das eingebaute Funktionsargument folgen hier keine Klammern.
Lassen Sie uns zwei weitere interessante Beispiele vorstellen: Finden des größten gemeinsamen Teilers für zwei ganze Zahlen im imperativen Stil und Verwenden der Rekursion:
FUN gcd
INPUT a: INT
INPUT b: INT
WHILE a ~= b LOOP
IF a > b THEN a -= b ELSE b -= a ENDIF
REPEAT
PRINT “gcd = “, a
RETURN
FUN gcd _ a: INT, _ b: INT -> INT
IF b == 0 THEN RETURN a ENDIF
RETURN gcd b, (a % b)
PRINT gcd 6, 9
# 3
Hallo Sprachanforderungen
Jede erfolgreiche Sprache wurde mit einem bestimmten Zweck entworfen, der ihre syntaktischen Merkmale und ihre Semantik bestimmt. Zum Beispiel wurde ASSEMBLER entwickelt, um Prozessoranweisungen direkt in einer menschenfreundlichen mnemonischen Form zu codieren. BASIC (das mit Zeilennummern und einer GOTO-Anweisung) setzte die Idee, Befehle direkt in einen übergeordneten Interpreter zu übersetzen, erfolgreich fort. Die Programmiersprache Hi soll die Sprache der Befehle und Algorithmen für die Kommunikation zwischen dem Menschen und der abstrakten Intelligenz eines bestimmten Systems werden.
Als logische Konsequenz ist der Programmcode nicht der kompilierte Maschinencode und nicht der Bytecode der virtuellen Maschine, sondern der Quellcode(Auflistung) einschließlich Kommentare. Dementsprechend ist die interne Implementierung des Codes in keiner Weise standardisiert und liegt im Ermessen der Interpreter- oder Compiler-Implementierung.
Unser Hauptziel ist es also, Gedanken in formaler Sprache auszutauschen. Lassen Sie uns drei Hauptanforderungen vorstellen:
- Die Sprache sollte für eine Person leicht zu lernen sein
- Die Sprache muss zuverlässig sein
- Die Sprache muss in der Lage sein, sehr komplexe Softwaresysteme zu organisieren.
Lassen Sie uns diese grundlegenden Anforderungen genauer untersuchen.
Die Sprache sollte leicht zu lernen sein
1) Wir werden einfach zu lesende syntaktische Schriften verwenden, die jeder modernen gebildeten Person vertraut sind. Wir werden es vermeiden, zum Nachteil des Lesens mit Kürze zu experimentieren, wie dies beispielsweise in der APL-Sprache der Fall ist.
Daher verwenden wir
LOOP…REPEATeher Konstrukte dieser Art als {…}. Als netten Bonus werden wir geschweifte Klammern wie diese verwenden:
s = {1, 2, 3}Wir werden die Zuordnung der Variablen s zu einem Satz von drei ganzen Zahlen bezeichnen.
a = [1, 2, 3]Wir bezeichnen die Zuordnung der Variablen a zu einem Array von drei ganzen Zahlen.
Durch die Verwendung gut durchdachter prägnanter Sprachkonstrukte können Sie auch eine logischere Verbindung zwischen der Semantik und der Syntax der Sprache herstellen, ohne den Kontext der Umgebung zu verwenden. Wir werden diese These später genauer diskutieren, wenn wir bestimmte Sprachkonstrukte betrachten.
2) Für arithmetische Ausdrücke verwenden wir eine Notation der Form:
a + b + cund nicht (+ a b c)wie in der LISP-Familie.
3) Die Art unserer Skriptsprache erfordert eine integrierte Bibliothek aller erforderlichen Funktionen in der Sprachumgebung, ohne dass externe Frameworks erforderlich sind.
4) Wir verwenden native Algorithmen zum Denken von Mustern: eine imperative Sprache mit der Möglichkeit rekursiver Funktionen und Elemente der funktionalen Berechnung. Wie wir weiter in Betracht ziehen werden, ist der imperative Stil für die Programmierung von Anwendungen, die auf der Architektur der Ereignisbehandlung in einem deklarativen Schlüssel wie SwiftUI basieren, sehr praktisch. Mit anderen Worten, die Begriffe "Imperativ" und "Deklarativ" spiegeln eher die Position des Beobachters wider als die Realität, die uns in gewissem Sinne gegeben wurde.
5) Wir überwachen das Fehlen einer Redundanz syntaktischer Strukturen und die Ergonomie der Eingabe von Codezeichen. Wir verwenden einen Zeilenumbruch als Trennzeichen. Wie in Swift können Sie jedoch ";" in einer Zeile als Trennzeichen für mehrere Ausdrücke. Gleichzeitig protestiert unsere Ingenieurausbildung nachdrücklich dagegen, Einrückungen im Programmtext eine syntaktische Bedeutung zu geben, wie sie zuvor in Fortran und jetzt in Python verwendet wurden.
Zuverlässige Sprache
Eine notwendige Voraussetzung für die Existenz komplexer Systeme in der Zeit ist das Erfordernis einer vollständigen semantischen Einzigartigkeit und Durchführbarkeit jedes korrekt geschriebenen Programms ohne Korrekturen im Falle einer unvermeidlichen Entwicklung und Komplikation der Sprache in der Zukunft. Wie kann dieses Problem der Programmzuverlässigkeit im Falle seiner unvermeidlichen Entwicklung und Erweiterung gelöst werden? Um den Konflikt des Zusammentreffens von Bezeichnern und reservierten Wörtern zu vermeiden, verwenden wir einen einfachen und effektiven Weg, wie dies beispielsweise in Oberon der Fall ist. Die HI- Sprache reserviert alle Bezeichner mit Großbuchstaben ohne Zahlen und mit mehr als einem Zeichen als Dienstzeichen . Daher sind die folgenden Beispiele gültige Bezeichner, die von einem Programmierer von Hand geschrieben oder von einem intelligenten System generiert wurden:
foo, Foo, f_001, F1, F, for
Beispiele für Bezeichner, die von der Sprache reserviert werden:
FOO, FOR, HI, YES, EVERYRESTRICTIONMATTER
Aus Gründen der Codezuverlässigkeit verwenden wir statische Typisierung mit der Möglichkeit, Typen automatisch aus Deklarationen des Formulars abzuleiten:
LET x = 6 # x INT
VAR boolean = TRUE # boolean BOOL
Wir unterscheiden Konstanten und Variablen nicht, um die Ausführungszeit des Codes zu optimieren, sondern um dem Entwickler ein gutes Verständnis für den Zweck der von ihm gesteuerten Objekte zu vermitteln.
Eine Sprache zum Erstellen sehr komplexer Softwaresysteme
Die Architektur einer universellen Sprache sollte eine durchdachte Möglichkeit bieten, komplexe Programme aus kleinen autonomen Teilen, beispielsweise bis zu 250 LOC, in einer Quelle zu erstellen, denn verzeihen Sie uns, lieber Leser, nur ein Scanner und ein Parser können problemlos mit Quelltexten beliebiger Komplexität arbeiten, und eine Person kann sogar ein paar dreistellige Werte multiplizieren ganze Zahlen sind ohne Taschenrechner schwer.
Im Moment werden wir die Implementierung der Architektur komplexer Systeme in der Hi-Sprache außer Acht lassen und diese Probleme in Zukunft detailliert analysieren, wenn wir das Konzept der Organisation von Klassen vorstellen - Protokolle, Kommunikation zwischen ihnen und Methoden zum Aufbau ihrer Hierarchie. Wir stellen nur fest, dass die Architektur komplexer Anwendungen aus kleinen autonomen, leicht lesbaren und modifizierbaren Fragmenten aufgebaut sein wird, und wir haben uns hier nicht vom Studium der Informatik inspirieren lassen, sondern von der Architektur der Interaktion von Zellen und Organen lebender Organismen. Der Körper eines gewöhnlichen Menschen besteht aus etwa 50 Billionen lebensfähigen Zellen, die trotz schwieriger Umgebungsbedingungen, des Vorhandenseins vieler Parasiten und der dauerhaften Schädigung von Millionen von Mikrokomponenten erfolgreich funktionieren. Der Schöpfer eines Computersystems,Was aufgrund eines einzelnen Aufrufs eines nicht vorhandenen Array-Index vollständig nicht mehr funktioniert, gibt es hier viel zu lernen.
Obwohl wir zunächst eine Skriptsprache beschreiben, die für die schnelle und angenehme Programmierung kleiner Rätsel geeignet ist, müssen wir den Entwicklern das volle Vertrauen geben, dass sie auf der Plattform einmal entwickelter einfacher Softwarekomponenten ohne die Verwendung von Lösungen von Drittanbietern in Zukunft funktionsfähige Systeme mit unbegrenzter Komplexität erstellen können.
Einschränkungen
In der Praxis müssen wir immer dann, wenn wir Anforderungen an den Entwurf von Systemen stellen, entweder etwas opfern oder etwas nicht beachten. Für uns ist es beim Aufbau der Hi-Sprache nicht von grundlegender Bedeutung:
- Genaue Syntaxkompatibilität mit anderen Programmiersprachen
- Möglichkeit, vorhandene externe Codebibliotheken zu verwenden oder in andere Softwaresysteme zu integrieren
- c n-
- /
- — ,
Lassen Sie uns abschließend über die Herkunft des Anzeigenamens der Programmiersprache HI, Hi oder hi sprechen. Lassen Sie es sein H Elius' i Programmiersprache nteractive oder H uman I ntelligence Programmiersprache. Im Gegensatz zu allen Konstruktionen in unserer Sprache ist dies die einzige Meta-ID, die keine eindeutige Semantik aufweist.
Im nächsten Artikel werden wir die Beschreibung der Hi Basic-Programmiersprache "auf einer" Seite präsentieren und dann die Syntaxkonstruktionslogik gemäß den Anforderungen der oben dargestellten Thesen analysieren.