Die beste Programmiersprache der Welt

Jeder Programmierer hat einen Traum - seine eigene Programmiersprache zu erstellen. Das Beste und Bequemste natürlich - nicht wie die vorhandenen. Für mich persönlich bestand die feste Idee darin, eine Sprache zu schaffen, in der es absolut kein Boilerplate geben würde, das so kurz wie möglich, aber äußerst eloquent wäre. Seit zwei Jahren versuche ich, das gewünschte Ergebnis zu erzielen, aber wo immer ich am Ende anfange, nachdem ich alles überflüssige abgeschnitten habe, habe ich immer Lisp bekommen. Und dann kam mir ein genialer Gedanke: Lisp zu nehmen und es gemäß meinen Ideen zu verbessern. Zu Ehren des ersten, was mir aufgefallen ist, wurde das Projekt Sova genannt.


Damit die Sprache sofort auf dem Server, im Web und auf mobilen Plattformen funktioniert, habe ich beschlossen, sie in Javascript zu kompilieren, das meiner Meinung nach kein Scherz ist, eine der am besten gestalteten Sprachen unserer Zeit und vor allem ein leistungsfähiges npm-Ökosystem hat. Node.js, React und React Native.


Und bevor wir uns auf den Weg machen, um sofort Interesse an einer weiteren Lektüre des Artikels zu wecken, finden Sie hier ein Beispiel für eine Express-Anwendungsdatei zu Sova:


=-> './database' database =-> 'express' express = application express () application.get '/' -> (request response) (response.sendStatus 200) application.get '/user/:id' -> (request response) (response.send (database.getUserById request.params.id)) application.listen 8080 -> () (console.log 'Application is listening on port 8080') 

Nun, fangen wir an ...


Schritt 1: Ziehen Sie Klammern mit Python-Einzug aus Lisp heraus


Bild
Obwohl dieses Comic mich jedes Mal zum Lächeln bringt, wenn ich es mir ansehe, stimme ich seiner Hauptaussage überhaupt nicht zu. Klammern sind nicht elegant, Klammern sind Boilerplate.


Deshalb habe ich mich als erstes in meiner wunderbaren Sprache entschlossen, die Klammern loszuwerden. Die beste Lösung war der relevante Einzug, genau wie in Python. Nehmen Sie zum Beispiel einen solchen Lisp-Code:


 (* 2 (+ 1 2) (- 4 (/ 2 1))) 

Natürlich kann dieser Ausdruck in verschiedenen Zeilen verteilt sein, aber dies befreit uns nicht vom Clowning aus den verstopfenden Augen.


 (* 2 (+ 1 2) (- 4 (/ 2 1))) 

Nun wollen wir sehen, wie elegant und luftig es möglich ist, denselben Ausdruck in Sova mit Hilfe bedeutender Einrückungen zu schreiben:


 * 2 + 1 2 - 4 (/ 2 1) 

Das heißt, in Sova entspricht der Ausdruck a (bc) (d (ef)) dem Ausdruck:


 a bc d ef 

Schritt 2: Machen Sie die Sprache präzise


Was mir in den meisten Programmiersprachen nicht gefallen hat, war das Verstopfen der Syntax mit nichts Sinnvollem, sondern das Einnehmen eines Platzes auf dem Bildschirm mit einem Boilerplate - zusätzliche Schlüsselwörter, bedeutungslose Satzzeichen und viele andere. Selbst im allgemeinen Lisp werden anstelle einfacher und verständlicher Zeichen häufig Wörter verwendet, um einfache Operationen wie die gleiche defn .


Konstantenerklärung


Nehmen Sie zum Beispiel die Deklaration einer Konstante in Javascript:


 const a = 1 

Sova ist eine ausschließlich funktionale Sprache, in der alle Variablen unveränderlich sind. Sie müssen also kein zusätzliches Schlüsselwort const angeben, aber alles ist einfach geschrieben:


 = a 1 

Funktionen


Das Kernelement jeder Sprache ist die Funktion. So minimalistisch sehen sie in Sova aus:


 = addOne -> number + number 1 = doubleAndAddOne -> number = doubled (* number 2) addOne doubled console.log (doubleAndAddOne 2) 

Wie in jeder Funktionssprache kann der letzte Ausdruck im Hauptteil der Funktion zurückgegeben werden. Das heißt, der obige Code in kompiliertem JavaScript sieht folgendermaßen aus:


 const addOne = number => { return number + 1 } const doubleAndAddOne = number => { const doubled = number * 2 return addOne(doubled) } console.log(doubleAndAddOne(2)) 

Vergleiche und Bedingungen


Ein bedingter Ausdruck in Sova kann entweder zwei oder ein Argument haben.
Hier sind Beispiele für Bedingungen mit zwei Argumenten:


 console.log ? true 1 0 console.log ? (> 2 1) 'Greater' 'Less' console.log ? (> 2 1) ? (> 1 2) 'x' 'y' 'z' 

Und hier geben wir zum Beispiel in der Funktion checkNumber Werte nach Bedingung zurück:


 = checkNumber -> number ? (=== number 1) (<- 'One') ? (=== number 2) (<- 'Two') ? (<= number 9) (<- 'From three to nine') 'Ten or more' console.log (checkNumber 1) console.log (checkNumber 4) console.log (checkNumber 11) 

In kompiliertem JavaScipt sieht es so aus:


 const checkNumber = number => { if (number === 1) return 'One' if (number === 2) return 'Two' if (number <= 9) return 'From three to nine' return 'Ten or more' } console.log(checkNumber(1)) console.log(checkNumber(4)) console.log(checkNumber(11)) 

Sammlungen


Array


Die Hauptsammlung jeder Sprache ist ein Array. So sieht die Deklaration und Dekonstruktion des Arrays in Sova aus:


 = list | 1 2 3 4 console.log list console.log list.map (-> x (+ x 1)) = (| first second) list console.log first console.log second 

In kompiliertem JavaScript sieht es so aus:


 const list = [1, 2, 3, 4] console.log(list) console.log(list.map(x => x + 1)) const [first, second] = list console.log(first) console.log(second) 

Objekt


Die zweitwichtigste Sammlung ist die Hashmap. In Sova sieht die Ankündigung und Dekonstruktion der Karte folgendermaßen aus:


 = map : a 1 b 2 c : d 3 e 4 f 'Hello' console.log map = (: a (c (: de))) map console.log a console.log d console.log e 

In kompiliertem JavaScript sieht es so aus:


 const map = { a: 1, b: 2, c: { d: 3, e: 4 }, f: 'Hello' } console.log(map) const { a, c: { d, e }} = map console.log(a) console.log(d) console.log(e) 

Wenn wir eine Methode für ein Objekt aufrufen möchten, gibt es zwei Möglichkeiten, dies zu tun. Wir können es als object.method parameter1 parameter2 oder als .method object parameter1 parameter2 . Mit der zweiten Methode können wir eine Kette von Methodenaufrufen erstellen.


Module importieren und exportieren


Importieren


Sie können Module aus anderen .sv Dateien sowie aus .js Dateien in Sova-Code importieren. In diesem Beispiel werden beispielsweise zwei Module importiert - data/index.js und handler/index.sv :


 =-> './data' (: greeting name) =-> './handler' handle handle greeting name 

In kompiliertem JavaScript sieht es so aus:


 const { greeting, name } = require('./data') const handle = require('./handler') handle(greeting, name) 

Durch den Import von JavaScript- und Sova-Modulen kann Sova problemlos in ein vorhandenes Javascript-Projekt integriert werden.


Exportieren


In diesem Beispiel wird die Funktion aus dem Modul exportiert:


 <-= -> (greeting name) console.log greeting console.log name 

In kompiliertem JavaScript sieht es so aus:


 module.exports = (greeting, name) => { console.log(greeting) console.log(name) } 

Anwendungsbeispiele


Um all die Schönheit, Luftigkeit und Prägnanz von Sova zu sehen, müssen Sie sich ein mehr oder weniger umfangreiches Programm ansehen. Hier ist beispielsweise ein Programm, das das Durchschnittsalter von Personen berechnet und den Namen der Person ermittelt, deren Alter dem Durchschnittsalter am nächsten kommt.


 =-> 'lodash' _ = people | : (name 'Alice') (age 24) : (name 'Bob') (age 15) : (name 'Chris') (age 46) : (name 'Daniel') (age 35) : (name 'Elisabeth') (age 29) : (name 'Fred') (age 52) = averageAge / .reduce (.map people (-> man man.age)) -> (xy) (+ xy) 0 .length people = manWithClosestToAverageAge _.minBy .map people (-> man (: (name man.name) (distance (Math.abs (- averageAge man.age))))) 'distance' console.log averageAge console.log manWithClosestToAverageAge.name 

Aufgrund der Tatsache, dass die Sprache in JavaScript kompiliert ist, wird die Entwicklung für jede Plattform möglich. Hier ist beispielsweise ein kleines Beispiel für eine React-Anwendung für Webbrowser:


 =-> 'react' React =-> 'react-dom' ReactDOM =-> './styles' styles = (: createElement:e) React = App -> ((: name)) e 'div' (: (style styles.container)) e 'div' (: (style styles.hello)) 'Hello' e 'div' (: (style styles.name)) name ReactDOM.render (e App (: (name 'John'))) (document.getElementById 'root') 

Im Repository befinden sich auch Beispiele für Express-Server- und React Native-Anwendungen für mobile Plattformen.


Fazit


So enthält Sova das Beste aus mehreren anderen Sprachen:


  • die Einfachheit und Kraft von Lisp
  • Python-Einrückung sauber
  • Laufzeit- und JavaScript-Ökosystem

Der Compiler-Code mit Beispielen für die Verwendung der Sprache finden Sie hier https://github.com/sergeyshpadyrev/sova . Ich werde mich freuen, die Sterne im Repository von all jenen zu sehen, denen das Konzept der Sprache gefallen hat und die weiter daran arbeiten möchten. Ich werde Sie jedoch sofort warnen, dass dies vorerst nur ein Proof of Concept ist und es aufgrund der fehlenden Dokumentation und einiger Funktionen äußerst schwierig ist, mit der Sprache zu spielen. Zum Beispiel hat die Sprache noch keine Ausnahmebehandlung, Klassen und andere notwendige Dinge. Und es ist unwahrscheinlich, dass Windows erfolgreich ist.


In den folgenden Schritten möchte ich die Syntax ergänzen und stabilisieren, den Parser neu schreiben, Tests für den Parser und den Übersetzer schreiben und die Dokumentation schreiben. In der Zwischenzeit vielen Dank für Ihre Aufmerksamkeit und bis bald.

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


All Articles