Eigene Programmiersprache
-
314159265358979 schrieb:
Hm, also da sind schon gewaltige unterschiede zwischen unseren Vorstellungen.
Meine Sprache baut auf einem Modulsystem auf. Ein Modul ist eine Codedatei und besteht (optional) aus Namespaces, die wiederum Funktionen und Variablen enthalten. (Klassen heb ich mir für später auf.)
Was die genaue Syntax angeht, habe ich mir noch keine Gedanken gemacht. Ich weiß nur, dass man den Typ von Variablen nirgens explizit hinschreibt.
Beispiel:
let x = 42; let y = "blah"; let z = 'c';
usw.
Funktionen sind entweder normale Funktionen, oder aber überladene Operatoren:
let f(x) = x < 42 ? 666 : x; let operator pow 5 (a, b) = b ? a * (a pow (b-1)) : 1; # binärer operator, priorität 5 let operator ! 123 (a) = a ? false : true; # unärer operator
Konstrukte wie if, for, while, do-while, etc. gibt es nicht.
Quasi einfach eine weitere 0815 funktionale Sprache, die niemand braucht.
-
FSharp schrieb:
Dein Ansatz erinnert mich stark an F#.
F# kenne ich nicht mal
Realerr schrieb:
Quasi einfach eine weitere 0815 funktionale Sprache, die niemand braucht.
Es interessiert mich herzlich wenig, ob das jemals jemand braucht.
-
314159265358979 schrieb:
(Klassen heb ich mir für später auf.)
Ah da freu ich mich dann schon auf das explizite self wie bei Python und weglassen liefert natürlich keinen Syntaxfehler, Warnung oder so, sondern geht erst beim Aufrufen in die Hose
Klassen nachzufrickeln ging schon bei Python schief, bitte nicht nachmachen, sondern aus deren Fehler lernen.
-
314159265358979 schrieb:
Realerr schrieb:
Quasi einfach eine weitere 0815 funktionale Sprache, die niemand braucht.
Es interessiert mich herzlich wenig, ob das jemals jemand braucht.
Wenn die Sprache niemand braucht, also auch du nicht, was ist dann deren Existenzgrundlage?
Und warum müsst ihr beiden auch so kranke Syntaxen ausdenken? Wie wäre es mit etwas lesbarem?
-
Wenn die Sprache niemand braucht, also auch du nicht, was ist dann deren Existenzgrundlage?
Lernen und Spaß an der Entwicklung?
Und warum müsst ihr beiden auch so kranke Syntaxen ausdenken? Wie wäre es mit etwas lesbarem?
So "krank" finde ich weder meine Syntax noch die von Pi. Zumindestens wenn man nicht gerade Basic als Messlatte nimmt ...
-
Tippgeber schrieb:
Ah da freu ich mich dann schon auf das explizite self wie bei Python und weglassen liefert natürlich keinen Syntaxfehler, Warnung oder so, sondern geht erst beim Aufrufen in die Hose
Klassen nachzufrickeln ging schon bei Python schief, bitte nicht nachmachen, sondern aus deren Fehler lernen.
Sorry, aber Python kann ich nicht. Was ist da so schlimm?
-
Danke er meint dass du immer ein self (ist wie this in C++) vor einen Zugriff schreiben musst, auch wenn die Variable/Funktion standardmäßig in der Klasse definiert ist. Angesichts der Tatsache dass du in Python aber auch lustig zur Runtime neue Variablen/Funktionen in eine Klasse stopfen kannst, finde ich das garnicht mal so tragisch.
-
Wurden Klassen in Python wirklich nachträglich reingefrickelt? In welcher Python-Version gabs denn noch keine Klassen?
-
Bashar schrieb:
Wurden Klassen in Python wirklich nachträglich reingefrickelt? In welcher Python-Version gabs denn noch keine Klassen?
http://python-history.blogspot.com/2009/02/adding-support-for-user-defined-classes.html
-
ein Objektmodell draufklatschen und ein bisschen was funktionales, map reduction und lambda etwa, ist heute ein Muß :xmas2:
Warum programmiert ihr nicht was Schönes Neues in Erlang oder Prolog oder helft sonstwie einer existierenden Sprache in die Zukunft, die es verdient hat ?
-
Ethon schrieb:
Danke er meint dass du immer ein self (ist wie this in C++) vor einen Zugriff schreiben musst, auch wenn die Variable/Funktion standardmäßig in der Klasse definiert ist. Angesichts der Tatsache dass du in Python aber auch lustig zur Runtime neue Variablen/Funktionen in eine Klasse stopfen kannst, finde ich das garnicht mal so tragisch.
Nein, damit kann man schon noch leben. Ich meine das:
class Foobar: def eineMethode(self, arg1, arg2): print arg1, arg2 f = Foobar() f.eineMethode(1, 2)
Könnt ja mal das self weglassen und dann ausführen, dann erhält man
>>> f.eineMethode(1,2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: eineMethode() takes exactly 2 arguments (3 given)
Dabei könnte der Interpreter ja wenigstens per Kommandozeilenparameter beim Parsen der Methoden-Definition warnen wenn die nicht mit self anfängt. Statt dessen geht es erst beim Aufruf schief und wer sonst normale Sprachen gewohnt ist vergisst das schonmal
Finde Python aber immernoch besser als Java von daher will ich nicht meckern bzw. erkenne an, dass man in beiden schnell etwas umsetzen kann (in Python natürlich schneller). Aber eine schöne Sprache wie Ruby reizt mich einfach mehr, damit arbeite ich dann auch wirklich gerne.
-
Tippgeber schrieb:
Dabei könnte der Interpreter ja wenigstens per Kommandozeilenparameter beim Parsen der Methoden-Definition warnen wenn die nicht mit self anfängt. Statt dessen geht es erst beim Aufruf schief und wer sonst normale Sprachen gewohnt ist vergisst das schonmal
Der Bezeichner
self
ist eine reine Konvention, das geht also nicht so einfach.BTW F# hat etwas ähnliches. Es muss auch explizit ein
self
-Parameter (der auch nicht so heißen muss) angegeben werden, der aber syntaktisch an seiner natürlichen Stelle steht, so dass man ihn (eigentlich?) nicht vergessen kann. Etwa so:member self.eineMethode y = self.z * y
(Disclaimer: Bin noch beim Lernen und syntaktisch nicht so sattelfest.)
-
Bashar schrieb:
Tippgeber schrieb:
Dabei könnte der Interpreter ja wenigstens per Kommandozeilenparameter beim Parsen der Methoden-Definition warnen wenn die nicht mit self anfängt. Statt dessen geht es erst beim Aufruf schief und wer sonst normale Sprachen gewohnt ist vergisst das schonmal
Der Bezeichner
self
ist eine reine Konvention, das geht also nicht so einfach.Dass ist mir bewusst, aber es ändert nichts an der Möglichkeit Warnungen dafür zu unterstützen. Ob man den Namen nun direkt mit self vergleicht ist mit einem Namen der als Kommandoargument angegeben wurde spielt dafür ja keine rolle. Ansonsten stellt sich noch die frage wie viele Leute hier etwas anderes verwenden
-
Tippgeber schrieb:
Dass ist mir bewusst, aber es ändert nichts an der Möglichkeit Warnungen dafür zu unterstützen. Ob man den Namen nun direkt mit self vergleicht ist mit einem Namen der als Kommandoargument angegeben wurde spielt dafür ja keine rolle. Ansonsten stellt sich noch die frage wie viele Leute hier etwas anderes verwenden
Was ist ein Kommandoargument?
Aber wie willst du wissen ob folgender code OK ist oder das self vergessen wurde:def f(a,b,c): return a.foo + b.foo + c.foo
ist a jetzt korrekt self oder nicht?
-
Shade Of Mine schrieb:
Was ist ein Kommandoargument?
Er meint beim Aufruf des Interpreters.
python --self=this
würde dann erlauben, dass der self-Parameterthis
heißt. Eine Methode ohnethis
würde dann bei ihrer Definition eine Warnung hervorrufen.
-
Bashar schrieb:
Shade Of Mine schrieb:
Was ist ein Kommandoargument?
Er meint beim Aufruf des Interpreters.
python --self=this
würde dann erlauben, dass der self-Parameterthis
heißt. Eine Methode ohnethis
würde dann bei ihrer Definition eine Warnung hervorrufen.Und wie würde man das mit externen Libraries machen?
Ich müsste dann ja quasi pro .py Datei definieren können wie self heisst.Ne, einfach immer self verwenden und statische code analyse verwenden um solche Fehler zu finden. Aber um ehrlich zu sein, ich hatte noch nie einen Bug in einer Python Anwendung der auf ein fehlendes self zurückzuführen war...
-
es wirkt aber trotzdem hochgradig künstlich, wie umgeschult auf objektorientiert.
-
Für meine experimentellen Programmiersprachen habe ich folgende Komponenten benötigt:
- Lexer
- Parser
- Erstellung von deBruijn-Indizes oder Symbol-Tabellen
- Typ-Inferenz oder Typ-Checker (falls erwünscht)
- Interpreter oder Code-Generator
Für Lexer und Parser kann man sich einfache Parser-Kombinatoren schreiben, dann braucht man keinen Parser-Generator.
DeBruijn-Indizes sind hilfreich, um in den Stack oder in Umgebungen zur Laufzeit zu indizieren.
Für Typ-Inferenz braucht man Unifikation; Typ-Checker sind in der Regel einfacher zu schreiben. In Sprachen wie Python gehört der Checker zur Laufzeit-Umgebung.
Wenn man eine Sprache kennt, die der eigenen ähnlich ist, bietet sich zunächst ein Code-Generator für diese Sprache an, das macht am Anfang am wenigste Arbeit.
C/C++ geht natürlich als Zielsprache, sofern kein garbage collector benötigt wird.
Ein Interpreter macht zwar ein wenig mehr Arbeit, aber auch mehr Spaß bei Benutzung.Auf jeden Fall fängt der Stress erst nach dem Parsen an, denn zu Parsern findet sich im Internet viel.
Wenn man nicht alles verstehen will, sondern nur die Sprache bauen will, bieten sich Bibliotheken an.
Man kommt auch ohne aus, aber mit gehts schneller:- Parsec, JParsec, FParsec, scala.util.parsing.combinator, Boost::Spirit, je nach Sprache für Lexer/Parser
- Tabellen finden sich in den meisten Sprachen, für die Erstellung von deBruijn-Indizes benutzt man funktional Listen, imperativ kann man einen Stack benutzen.
- Als Typ-Inferenz könnte man Prolog benutzen oder "constraint-programming"-Bibliotheken. (letztere hab ich noch nie benutzt)
- Als Code-Generator kann man die LLVM in C++ oder OCaml benutzen. .NET bietet "Reflection", um bytecode zu erstellen.
Funktionale Sprachen (Haskell/ML/F#/Scala) sind zu empfehlen, um den Compiler/Interpreter zu schreiben, aber nicht zwingend notwendig, C# oder Python gehen auch. Funktionaler Code ist in der Regel kürzer.
Als Inspiration für Typ-Systeme oder neue Programmiersprachen kann Types&Programming Languages dienen,
Parser-Kombinatoren und deBruijn-Indizes sind in MLftw erklärt, ebenso wie der Lambda-Kalkül.
In das Drachenbuch habe ich mal reingelesen um LALR-Parser zu verstehen, aber das war nicht so schön erklärt und eher weniger verständlich. Ich kenne aber nur die deutsche Version, vielleicht ist die englische besser.Ich hoffe, dass die Anregungen helfen! Je mehr Leute verstehen wie man Compiler schreibt, desto besser!
-
Danke alf42red für den guten Beitrag.
Aber eine neue Frage. Meine Sprache ist mittlerweile für triviale Sachen zu gebrauchen, bis jetzt interpretiere ich sie.
Jetzt habe ich mich gefragt, ob es zufälligerweise eine primitive Metasprache + passenden Compiler gibt, um Binaries zu erzeugen. Zum Beispiel dass ich eine XML-Representation meines ASTs erzeuge und das kompilieren kann. (Einen eigenen Code-Generator schreiben oder mit LLVM würde ich ungern machen, würde lieber mehr high-level bleiben und etwas auf dem Niveau von XML ausgeben).Mich stört es nämlich gerade etwas, die Eigenheiten von C++ erdulden zu müssen, die teilweise auch limitieren.
-
Du kannst deine Sprache auch nach C(++) konvertieren und dann kompilieren.