Offene Fragen bei der Entwicklung einer kleinen Programmiersprache



  • Upps, habe die Antwort jetzt erst gelesen, wurde mir unter den neuen Beiträgen nicht angezeigt.

    Ich Idiot habe es versäumt regelmäßige Backups zu machen und der Projektordner ist einer Dummheit zum Opfer gefallen.
    Musste mit einem sehr alten Stand weiterarbeiten, was nicht schlecht ist, ich habe ein paar Dinge jetzt anders gemacht, aber Funktionalität ist recht mau.

    Funktionen sind implementiert. (Defaultparameter auch, aber keine named Parameter)
    Modulsystem steht die Planung.
    Objektorientierung is theoretisch dabei, Builtin-Typen wie Integer verhalten sich wie Objekte, allerdings fehlt mir noch jedes Konzept wie nutzerdefinierte Klassen umgesetzt werden sollen. Ich möchte es halt schön hinbekommen.

    Eines der Probleme bezüglich Objektorientierung ist dass ich Refcounting und keinen GC verwende. (Und das auch so bleiben soll)
    Jetzt muss ich mir halt genau überlegen wie ich zyklische Referenzen lösen kann.

    Vermutlich werde ich einfach mal eine dumme struct ala C implementieren die nur ein Container für andere Objekte ist.

    Der ganze Krempel ist auf Github oben, wenn Interesse besteht kann ich ja mal nen Link posten.

    ----

    Aus aktuellem Anlass: Wäre es für euch intuitives Verhalten wenn der Ausdruck

    5.sqrt == 2
    

    wahr wäre?
    Ich nutze jetzt GMP für ints/floats und GMP bietet für Integer standardmäßig nur eine Wurzelfunktion bereit, die den abgeschnitten Integer + Rest zurückgibt.

    Bei floats sieht es anders aus, zb. wäre dieser Ausdruck false:

    5.float.sqrt == 2
    

    Bin mir halt nicht sicher ob eine implizite Konvertierung nach float sinnvoller wäre als einen abgeschnittenen Integer zurückzugeben.
    Meinungen?



  • Bei 5.sqrt würde ich 2.23 hoffen. Wer den int haben will, kann ja 5.sqrt.int schreiben.

    Basic mag ich da. 5/2==2.5 aber 5\2==2.



  • Ich habe in dieser Beziehung immer debug (win32) sehr gemocht bzw. die Intellowlevelebene, weil man beim Teilen das Ergebnis im AX Register hat, den Rest im DX Register (und die klassische Registervergrößung mit diesem beiden Registern). Wäre schön, wenn das an Taschenrechner auch könnte, bzw. wenn eine Funktion divmod, die zwei Werte ausspuckt, einfach mal Standard wäre, und nicht getrennt in div und mod oder ungefragt Fließkomma und aufgedrängtes Rundungsverhalten.

    Bei Wurzeln gibt es ja immer mehrere Möglichkeiten. Hier fände ich Transparenz gut, und Auswahlmöglichkeiten (auch Anzahl der Nachkommastellen), wie auch eine, Schätzfunktion bzw. -hilfe.
    Aber wie wäre es, einfach mehrere Werte auszugeben, den Floatwert und den Integerwert mit Rest, Anzahl der Nachkommastellen und Schätzbereich(e). 😉

    Wenn das alles nicht geht, dann würde ich die Funktion selber mit Heron und der FPU machen, also standardmäßig Fließkomma mit maximaler Bitbreite.
    Grammatisch finde ich sqrt 5 mit Fließkommaausgabe am sinnvollsten. FP für Wurzeln ist letzlich auch generell intuitiver, weil die FPU für größere Bitbreiten/Zahlen näher liegt.

    Aber einen C-Sprachtyp als Vorbild/Orientierung empfinde ich nicht unbedingt als gute Wahl. Auch wenn python eine Menge kann und u.a. Hackers Liebling ist, syntaktisch sollte man sich auch Haskell und Fortran(und Basic) gut anschauen, und auch Lisp und (Entwicklung nach) Closure. Aber nicht nur, Programmiersprachen sind selten isoliert, sondern Anwendungsgebunden, hier kommt es auch immer aufs drumherum an, Compilerauswahl und -Installationsmöglichkeiten, Betriebsysteme, Bibliotheken, Plugins, DesktopundGUI, Community, Weiterpflege usw.

    Ansonsten: Zeig mal, (oder probier mal) wie man einfache Sachen angehen kann, wie z.B. Registerwerte manipulieren (für OS Programming), mathematische Funktionen, Kettenbrüche, Analysis, Fakultätsberechnung, Quicksort, Heron-Wurzel (mit Schritt-Liste) und Cäsar-Verschlüsselung oder Konvertierungen zwischen Zahlensystemen (und welche?) eine Bitmap/Farbtabelle für einen Desktop(Betriebsystem) erstellen, oder einen simplen Texteditor o.ä. aber auch wie komplizierte Schleifenverschachtelungen aussehen würden.

    (ach so, damit der Stack nicht vollgeschrieben wird, kann man Jumps machen statt calls (mit ret), grundlegende Funktionen zusammenlegen, und je nach Funktionsaufruf den Navigationswert im Speicher zurücksetzen, also die Startadresse bzw. die Speicheradresse(n) vom (wenn sich hier was bewegt) und im Stack.

    Auf abstrakterer Ebene hilft die Beschäftigung mit Stackoverflows weiter z.B.
    http://en.wikipedia.org/wiki/Stack_overflow )



  • volkard schrieb:

    Bei 5.sqrt würde ich 2.23 hoffen. Wer den int haben will, kann ja 5.sqrt.int schreiben.

    Basic mag ich da. 5/2==2.5 aber 5\2==2.

    Macht Sinn, danke.
    Die Basic-Syntax gefällt mir nicht. Sehen beide zu ähnlich aus.

    Ich habe in dieser Beziehung immer debug (win32) sehr gemocht bzw. die Intellowlevelebene, weil man beim Teilen das Ergebnis im AX Register hat, den Rest im DX Register (und die klassische Registervergrößung mit diesem beiden Registern). Wäre schön, wenn das an Taschenrechner auch könnte, bzw. wenn eine Funktion divmod, die zwei Werte ausspuckt, einfach mal Standard wäre, und nicht getrennt in div und mod oder ungefragt Fließkomma und aufgedrängtes Rundungsverhalten.

    Kommt halt bei einer Skriptsprache doof wenn Ergebnisse von grundlegenden Operationen nicht einfach verwendet werden können. Also zb. bei deinem Divisions-Beispiel.
    Soetwas könnte man natürlich als Library anbieten aber mein /-Operator darf schon ein float zurückgeben.

    Wenn das alles nicht geht, dann würde ich die Funktion selber mit Heron und der FPU machen, also standardmäßig Fließkomma mit maximaler Bitbreite.
    Grammatisch finde ich sqrt 5 mit Fließkommaausgabe am sinnvollsten. FP für Wurzeln ist letzlich auch generell intuitiver, weil die FPU für größere Bitbreiten/Zahlen näher liegt.

    Bei mir sind Integer/Floats multiple-precision da ich GMP für die Implentierung nutze. Erstmal möchte ich da nicht allzuviel selbst implementieren. 😉

    Ansonsten: Zeig mal, (oder probier mal) wie man einfache Sachen angehen kann, wie z.B. Registerwerte manipulieren (für OS Programming), mathematische Funktionen, Kettenbrüche, Analysis, Fakultätsberechnung, Quicksort, Heron-Wurzel (mit Schritt-Liste) und Cäsar-Verschlüsselung oder Konvertierungen zwischen Zahlensystemen (und welche?) eine Bitmap/Farbtabelle für einen Desktop(Betriebsystem) erstellen, oder einen simplen Texteditor o.ä. aber auch wie komplizierte Schleifenverschachtelungen aussehen würden.

    Wie gesagt, im Moment steht noch nicht allzuviel.
    Low-Level Kram kommt in die Sprache garnicht rein, es ist eben ein dynamisch typisierte Scriptsprache. Im Moment ist es relativ leicht nativen Code zu nutzen (Bindings sind leicht zu schreiben (wenn auch noch nicht komfortabel implementiert) und es gibt eingebauten Support für C-Funktionen in DLLs.)

    Faktultät:

    x = 1123
    fak_of_x = x!
    


  • Ethon schrieb:

    volkard schrieb:

    Bei 5.sqrt würde ich 2.23 hoffen. Wer den int haben will, kann ja 5.sqrt.int schreiben.

    Macht Sinn, danke.

    Dann beachte aber, daß es (gut, aber nur in der hand des compilerbauers) allen Deiner Verantwortung unterliegt,
    5.sqrt.int
    und
    5.sqrt
    was vollkommen verschiedenes machen zu lassen! Erstere Version ist evtl viel schneller.
    Kann es möglich sein (besser, in der hand des bibliotheksschreibers!!!!!), daß der Anwender beschreiben kann, daß .sqrt.int vorrangich matcht vor .sqrt ?
    Und wäre das überhaupt tragfähig für viele andere Optimierungen oder nur eine Eintagsfliege?



  • Basic mag ich da. 5/2==2.5 aber 5\2==2.

    Diese Syntax ist irritierend.

    Kaum zu unterscheiden, wobei Code flink lesbar und verständlich sein soll.
    Einen Strich auf verschiedene Seiten zu kippen ist für einen Menschen nicht schnell genug unterscheidbar und kann und wird zu vielen Missverständnissen führen/geführt haben.

    Du hast, beiläufig gesprochen, Ethon falsch zitiert.



  • Sone schrieb:

    Basic mag ich da. 5/2==2.5 aber 5\2==2.

    Diese Syntax ist irritierend.

    Kaum zu unterscheiden, wobei Code flink lesbar und verständlich sein soll.
    Einen Strich auf verschiedene Seiten zu kippen ist für einen Menschen nicht schnell genug unterscheidbar und kann und wird zu vielen Missverständnissen führen/geführt haben.

    Nö, wenn mans ein wenig gewohnt ist, kein Problem.

    Sone schrieb:

    Du hast, beiläufig gesprochen, Ethon falsch zitiert.

    Hab's nur auf die Nicht-Basic-Sache reduziert. Bin sicher, es war in seinem Sinne.



  • volkard schrieb:

    Nö, wenn mans ein wenig gewohnt ist, kein Problem.

    Nun, du wirst es wissen. 🙂

    Sone schrieb:

    Du hast, beiläufig gesprochen, Ethon falsch zitiert.

    Hab's nur auf die Nicht-Basic-Sache reduziert. Bin sicher, es war in seinem Sinne.

    Oh, ich hätte schwören können, du hast die Basic-Syntax zitiert... nun, ich bin blind.

    Wie willst du aber auch die Basic-Syntax auf das Radizieren anwenden?

    Bei 5.sqrt würde ich 2.23 hoffen. Wer den int haben will, kann ja 5.sqrt.int schreiben.

    Das ist nicht so hübsch wie bei C++, wo man das alles auf das Typsystem reduzieren kann. Hat diese Skriptsprache eigentlich ein statisches Typsystem?

    bibliotheksschreibers!!!!!

    Was ist denn da so überaus wichtig, dass du es mit fünf Ausrufezeichen hervorhebst?????



  • volkard schrieb:

    Ethon schrieb:

    volkard schrieb:

    Bei 5.sqrt würde ich 2.23 hoffen. Wer den int haben will, kann ja 5.sqrt.int schreiben.

    Macht Sinn, danke.

    Dann beachte aber, daß es (gut, aber nur in der hand des compilerbauers) allen Deiner Verantwortung unterliegt,
    5.sqrt.int
    und
    5.sqrt
    was vollkommen verschiedenes machen zu lassen! Erstere Version ist evtl viel schneller.
    Kann es möglich sein (besser, in der hand des bibliotheksschreibers!!!!!), daß der Anwender beschreiben kann, daß .sqrt.int vorrangich matcht vor .sqrt ?
    Und wäre das überhaupt tragfähig für viele andere Optimierungen oder nur eine Eintagsfliege?

    Naja, das sind ja Properties.

    Integer(5).sqrt().int()

    wäre es mit Funktionsaufrufen.

    Da zu optimieren würde einiges an statischer Analyse verlangen auf die ich schlichtweg wenig lust habe.
    Machen die wenigsten Scriptsprachen, also versuchen zu erraten was der Nutzer ausdrücken wollte und dementsprechend optimieren.
    Durch die Dynamik ist das auch reichlich schwer.

    Da würde ich zb.

    (5).trunc_sqrt
    

    bevorzugen.

    (Die Zahl muss btw in Klammern da der Parser sonst ein Float-Literal matcht. Hat mich einiges an Verwunderung gekostet 😃 )



  • Sone schrieb:

    Wie willst du aber auch die Basic-Syntax auf das Radizieren anwenden?

    Klappt nicht.
    Kenne Smalltalk!

    Sone schrieb:

    Bei 5.sqrt würde ich 2.23 hoffen. Wer den int haben will, kann ja 5.sqrt.int schreiben.

    Das ist nicht so hübsch wie bei C++, wo man das alles auf das Typsystem reduzieren kann. Hat diese Skriptsprache eigentlich ein statisches Typsystem?

    Letztendlich irrelevant.

    bibliotheksschreibers!!!!!

    Was ist denn da so überaus wichtig, dass du es mit fünf Ausrufezeichen hervorhebst?????

    Um nicht in den PHP-Großnotstand zu fallen.



  • Sone schrieb:

    Bei 5.sqrt würde ich 2.23 hoffen. Wer den int haben will, kann ja 5.sqrt.int schreiben.

    Das ist nicht so hübsch wie bei C++, wo man das alles auf das Typsystem reduzieren kann. Hat diese Skriptsprache eigentlich ein statisches Typsystem

    Nein, dynamisch typisiert, wenn auch mit strengeren Regeln als zb. PHP.
    Es wird nicht allzuviel geraten, manchmal muss man eben explizit sagen was man meint. Damit mit dem Cast nach int ist aber eher ein Hack (da man das Implementierungsdetail ausnutzt dass bei Float -> Integer abgerundet wird), schöner wäre

    (5).sqrt.floor
    

    Um nicht in die PHP-Großnotstand zu fallen.

    Was meinst du damit?
    Den Krempel um die Basistypen herum möchte ich als builtins implementieren (allein schon damit Libraries nicht mit internen Repräsentationen der Grunddatentypen arbeiten müssen - wie hier eben GMP).
    Den Rest komplett als Librarylösungen.



  • Ethon schrieb:

    Um nicht in die PHP-Großnotstand zu fallen.

    Was meinst du damit?

    Da haben es Fremdbibliotheken gelinde gesagt schwer.

    edit: Nicht im Sinne von Fremd, aus einer anderen Sprache, sondern fremd als nicht vom PHP-Vertreiber mitvertrieben.



  • Okay.
    Das habe ich nicht vor. Im Moment spiele ich sogar mit dem Gedanken Grunddatentypen austauschbar zu machen.

    Zb. bei Python funktioniert ja auch soetwas:

    > class Foo:
    ... pass
    ...

    > class Bar:
    ... pass
    ...

    > Foo = Bar
    > Foo()
    <__main__.Bar object at 0x7ffcd675d890>

    Wäre noch eine nette Idee wenn mein Compiler ein

    5
    

    zu

    int(5)
    

    umschreiben würde und

    int = MyInt
    

    möglich wäre?



  • (5).sqrt.floor
    

    Das eh. Wollte ich nennen, war mir aber hier nebensächlich.

    Weil bisher, wo int=>int und double>=double wäre ja
    5.sqrt==2
    5..sqrt==2.23
    Nöö,
    (5).sqrt==2
    (5.).sqrt==2.23
    da würde ich zwingen, daß Zahlenliterale Klammern brauchen, bevor sie vollwerteige Zahlenobjekte sind.
    Aber ist auch bös inkonsequent. Vielleicht nur Klammern verlangen, daß sie Methoden aufrufen können. Macht mir keinen Spaß. Was ist an Zahlenliteralen so besonders? "hallo".reverse muss ja auch gehen, ohne ("hallo").reverse zu schreiben. Locker bleiben, man gewöhnt sich dran. Der . vom Funktionsaufruf bindet einfach viel schwächer als der Dezimalpunkt.
    Ranges wie von 1 bis 10 schreibt man als 1..10
    Naja, da wirds wirr, 1...10 könnte 1..(.10) oder (1.)..10) sein. Würde mir kein early-match wünschen, sondern schlicht einen Fehler, wenn man 1...10 schreibt. 1. ..10 oder 1.. .10 aber nicht 1...10. (In C++ wäre das vielleicht sowas wie - ++i oder -+ +i aber nicht -++i).



  • Natürlich bindet das Dezimltrennzeichen stärker als der Element-Selektor, allein schon weil der Parser das so schon falsch vom Lexer gefüttert bekommt.

    Problem ist aber bereits behoben. Kommt eine Zahl nach dem Punkt ist es ein Float, ansonsten ein Integer + ein Element-Selektor. Offensichtliche Lösung. 🙂


Anmelden zum Antworten