• Diese Seite verwendet Cookies. Indem du diese Website weiterhin nutzt, erklärst du dich mit der Verwendung von Cookies einverstanden. Erfahre mehr

Erfahrungen mit Racket

R

ralli

Guest
Themenstarter #251
Zur Abwechslung habe ich heute Nachmittag mal die Datenbankprogrammierung mit sqlite3 durchgearbeitet. Hier das Ergebnis:

#lang racket

(require db)

; Prüfen, ob sqlite3 verfügbar ist (liefert #t, wenn wahr)

; (sqlite3-available?)

; Verbindung zur Datenbank probe.db öffen
; Datenbank probe.db wird im mode create neu erstellt

(define verbindung (sqlite3-connect
#:database "probe.db"
#:mode 'create))

; Abfrage erstellt Tabelle adressen

(query-exec verbindung "CREATE TABLE adressen(
nachname VARCHAR(30) NOT NULL,
vorname VARCHAR(30) NOT NULL)")

; Alle Tabellen der Datenbank probe.db anzeigen

;(displayln (query-rows verbindung "select * from sqlite_master"))

; Tabelle adressen löschen (query-exec verbindung "DROP TABLE adressen"

;Tabelle adressen Datensätze hinzufügen

(query-exec verbindung "INSERT INTO adressen (nachname,vorname) VALUES
('Duck','Donald')")

(query-exec verbindung "INSERT INTO adressen (nachname,vorname) VALUES
('Mouse','Micky')")

; Alle Datensätze der Tabelle adressen anzeigen

displayln (query-rows verbindung "select * from adressen")

; Verbindung schließen

(disconnect verbindung)

Ich habe das script kommentiert, es ist selbsterklärend, es wird eine Verbindung zu sqlite3 aufgebaut und eine neue Datenbank probe.db erstellt. Danach wird mittels einer query eine neue Tabelle adressen erstellt, 2 Datensätze hinzugefügt und danach angezeigt. Schlußendlich wird die Verbindung geschlossen. Ich hänge mal die das Script hier an.
Es ist ein erster kleiner Einstieg in die Datenbankprogrammierung und es funktioniert:

habe fun:)
 

Anhänge

R

ralli

Guest
Themenstarter #252
Hab mal versucht, ein kleines Datenbankfrontend (GUI) für sqlite3 zu erstellen. Leider gibt es kein Tabellen Widget.... ob es möglich wäre, eine Listbox zu mißbrauchen für die Anzeige von ausgeführten Querys oder die Datensätze in einem Text Widget angezeigt werden können, hab ich noch nicht angetestet, das wären aber wohl alles (faule) Kompromisse.
 

Andy_m4

Well-Known Member
R

ralli

Guest
Themenstarter #254
Immerhin hatte offenbar jemand ein ähnliches Problem und hat daraufhin so etwas erstellt. Ein Panel namens table-panel%:
http://docs.racket-lang.org/table-panel/index.html

Kannst Du einfach nachinstallieren via:
raco install table-panel

Für die Tabellenzellen kannst Du beliebige Widgets nehmen. text-field%, message% oder was immer Du brauchst.
Hallo Andy, das ist ja erfreulich und wirklich nützlich. Danke! Das werde ich mal ausprobieren, installiert ist es schon.
 
C

CrimsonKing

Guest
Themenstarter #255
Bastle gerade wieder ein wenig und stelle fest:
Die Racketsyntax verwirrt mich. (Liegt wahrscheinlich daran, dass mich Common Lisp so verdorben hat...)

Funktionen, die Pfeile im Namen haben (z.B. "number->string" und "string->number"). Komme ich nicht drauf klar. :confused:
Mein Hirn schaltet dann automatisch in den C-Modus und dann wundere ich mich über Fehler. Gnah.

Beispiel:

Code:
(string->number(number->string 123))
Ich habe ewig gebraucht, bis ich verstanden habe, wieso das nicht gehen kann.

Wie kommen die auf solche Funktionsnamen?
 
R

ralli

Guest
Themenstarter #256
Bastle gerade wieder ein wenig und stelle fest:
Die Racketsyntax verwirrt mich. (Liegt wahrscheinlich daran, dass mich Common Lisp so verdorben hat...)
Da bist Du nicht alleine, mir geht es ebenso. Mir kommen Zweifel, ob ich meine Lebenszeit (die ja anders als wie bei jungen Menschen) durchaus begrenzt ist, damit zu vergeuden, die API zu erlernen und zu durchschauen. Wahrscheinlich werde ich bei einem Wissenstand von 60 bis 70% stehen bleiben. Das ist aber nicht tragisch, sondern es reicht mir, um die Dinge mit Racket GUI zu tun, die ich mir vorstellte. Und meine wirkliche Leidenschaft gilt nun mal der Schriftstellerei.:)
 
Bastle gerade wieder ein wenig und stelle fest:
Die Racketsyntax verwirrt mich. (Liegt wahrscheinlich daran, dass mich Common Lisp so verdorben hat...)
Ich denke das ist weniger der Syntax als die jeweiligen Idiome und Konventionen. Das ist die Kehrseite der großen Freiheit der s-expr die (nahezu) nichts festlegen und alles über Konventionen regeln. Und die werden eben von der Tradition und dem Geschmack der jeweils aktuellen Community bestimmt, befinden sich in stetigem Fluss und Unterscheiden sich auch zwischen den Dialekten und Implementierungen.

Mit dem Syntax komme selbst ich langsam klar, wenn auch immer noch etwas holprig, - aber immerhin! Der Rest ist Kennenlernen der Biblotheken und Idiome. Bei Chicken kommt im Falle das es nicht als binary vorliegt, das Problem der recht unkonventionellen Kompilation und Installation hinzu. Außerdem befinden die sich gerade im Übergang von Version 4 nach 5 und es macht wenig Sinn sich als Neuling noch mit den V4 Biblotheken zu befassen, insbesondere da einige von denen eh nicht mehr funktionieren wie z.B. IUP.

Wahrscheinlich werde ich bei einem Wissenstand von 60 bis 70% stehen bleiben. Das ist aber nicht tragisch, [...]
Bei mir wird das wohl bei 20-30% bleiben. Es ist wohl so dass man als Amateur nicht mehr als 2-3 Sprachen wirklich (!) bewältigen kann, als Profi nur wenig mehr. Und das Lisp für mich eine dieser Sprachen werden wird kann ich nach diesem Ausflug wohl ausschließen. Immerhin habe ich einiges gelernt und ich finde insbesondere die Implementierungen von Lisp/Scheme höchst spannend.

Nach einem mehrjährigem Ausflug in höhere Sprachen, von Erlang über C++ nach Rust, werde ich mich zurück zu den Wurzeln bewegen, also zu C und meinem spreziellen Freund (g)make. Ich werde wohl nicht darum herumkommen Make wirklich zu erlernen, was ja auch eine Sprache ist. Bedauerlicherweise führt da kein Weg daran vorbei. :-(

NB: Meine Leidenschaft ist Spielen und Lernen... :-)
 
R

ralli

Guest
Themenstarter #258
Nach einem mehrjährigem Ausflug in höhere Sprachen, von Erlang über C++ nach Rust, werde ich mich zurück zu den Wurzeln bewegen, also zu C und meinem spreziellen Freund (g)make. Ich werde wohl nicht darum herumkommen Make wirklich zu erlernen, was ja auch eine Sprache ist. Bedauerlicherweise führt da kein Weg daran vorbei. :-(
Ganz genau so sehe ich das auch .... da bin ich ganz nah bei Dir.
 
C

CrimsonKing

Guest
Themenstarter #259
Ich werde wohl nicht darum herumkommen Make wirklich zu erlernen, was ja auch eine Sprache ist. Bedauerlicherweise führt da kein Weg daran vorbei
Doch, der über andere Buildsysteme. Plan 9 hätte Mk statt make...
Und für Cross-platform-Gedöns hatte ich mir fest vorgenommen, nach dem Abschluss meiner beiden unfertigen Projekte was mit Meson zu machen. Bisher hatte ich dafür CMake, aber CMake nervt.
 

Andy_m4

Well-Known Member
Ich habe ewig gebraucht, bis ich verstanden habe, wieso das nicht gehen kann.
Wieso?`Geht doch.

Wie kommen die auf solche Funktionsnamen?
Das sind Umwandlungsfunktion von einem Datentyp zum anderen. Finde ich selbst auch eingängiger als number-To-String und Ähnliches. Wenn ein Pfeil drin vor kommt, weiß man gleich, es geht um Typumwandlung.
Was übrigens auch die Suche erleichtert.

Ist vielleicht gewöhnungsbedürftig. Aber wenn man sich einmal dran gewöhnt hat, dann ists eigentlich vollkommen logisch.

Ist halt so ähnlich wie mit anderen Konventionen auch. Eine Funktion die auf ein Fragezeichen endet gibt immer ein Wahrheitswert zurück.

Die Racket-Syntax oder allgemein die Lisp-Syntax ist eigentlich sehr klar, dadurch das sie durchgehend ist. Es gibt halt (vereinfachft gesprochen) nur Funktionsaufrufe. Es gibt keine speziellen Operatoren die dann (wie in C/C++ halt dieses ->) ne spezielle Bedeutung haben und dann irgendwie was anderes machen als ne Funktion.

Genauso wie es aus Sicht anderer Sprachen eher ungewöhnlich erscheint, wie man Objektmethoden aufruft. Aber auch hier ists halt konsequent. Keine spezielle Syntax. Dafür aber die Funktion send zum Methodenaufruf.
Und selbst der Name ist eigentlich passend. Denn im OOP-Sprech ruft man ja nicht irgendwie was auf, sondern sendet Objekten Botschaften.
Und genau das bildet das Konstrukt ab:
Sende Objekt obj Botschaft msg wird zu
(send obj msg)

Da bist Du nicht alleine, mir geht es ebenso.
Wobei die wirklich spannenden Sachen in Racket ja eher in den Features wie Makros, Continuations und Implementierung eigener Programmiersprachen sind.
Wodurch sich dann auch neue Abstraktionsmöglichkeiten ergeben.

All das ist in anderen Sprachen nicht möglich oder sehr kompliziert.
 
Und für Cross-platform-Gedöns hatte ich mir fest vorgenommen, nach dem Abschluss meiner beiden unfertigen Projekte was mit Meson zu machen. Bisher hatte ich dafür CMake, aber CMake nervt.
Yep, CMake nervt. Aber ich habe mich nicht allzu lange damit aufgehalten.

Meson scheint mir interessant, erscheint mir aber nach einer ersten Durchsicht als allzu kompliziert. Außerdem stören mich die Abhängigkeiten: Python3 und Ninja. Berichte wenn du damit erste Erfahrungen hast!

Am besten von allen hat mir bislang Premake5 gefallen, das allerdings noch im alpha/beta Stadium ist und gelegentlich noch Fehler produziert weshalb ich es momentan nicht einsetze. Klarer und flexibler kann man so etwas wohl kaum machen. Von den generierten Makefiles habe ich aber eine Menge gelernt. Vor allem hat es keinerlei weitere Abhängigkeiten da es einen internen (embedded) Lua Interpreter benutzt. Und mit ~200 kb größe ist es wirklich leichtgewichtig. Bei Premake4 fehlen mir einige Features.

Bei solchen Sachen kommt es auch immer darauf an wer das in welchem Umfang unterstützt. Und gmake gibt es wohl überall wo es auch einen gcc gibt, und das dürfte sehr weit reichen. Bis auf weiteres also gmake...
 
C

CrimsonKing

Guest
Themenstarter #265
Premake5 kannte wiederum ich noch nicht. Es sieht zwar ganz putzig aus, aber:

Currently supporting Visual Studio and GMake only (additional targets are available via modules).
Das schränkt die Benutzbarkeit ein wenig ein. Und Lua statt Python 3 ist nun auch keine kleine Abhängigkeit - Lua habe ich sonst nämlich normalerweise nicht einfach so rumliegen, um Python komme ich schon etwas schwerer herum.

Aber mir scheint, das ist wieder eine dieser Diskussionen, die in einem eigenen Thema besser aufgehoben wären. ;)
 
Und Lua statt Python 3 ist nun auch keine kleine Abhängigkeit
Etwas genauer lesen würde helfen! Das ist keine Abhängigkeit, vielmehr ist der Lua Interpreter Teil des Programmes selbst und das ist insgesammt (!) nur ~200kb groß. Mich würde interessieren wie groß CMake oder Meson (incl. python und ninja ) sind.

Aber ok, das ist eine andere Baustelle, - back to Racket, Scheme and Lisp!
 

Andy_m4

Well-Known Member
Das sich bezüglich make noch keine vernünftige Lösung durchgesetzt hat, ist ja doch schon ähm ... interessant.
Ich meine, wie lange gibts C jetzt schon und irgendwie ist das eine never-ending story.
 
R

ralli

Guest
Themenstarter #268
Wollte nur noch anmerken, das ich nicht racket oder C möchte, sondern C nicht gänzlich aus den Augen verlieren will. Trotz "milder" Kritik an der Racket API ist dies doch eher der Frustation geschuldet, die manchmal entsteht, allerdings redlicherweise auch durch eigene Defizite und die müssen halt nach und nach aufgearbeitet werden. Racket hat mich trotz meiner eigenen Unzulänglichkeiten sehr überzeugt.
 

Andy_m4

Well-Known Member
Wobei "ging nicht" ohnehin eine schlechte Fehlerbeschreibung ist.
Was ging denn konkret nicht (gabs ne Fehlermeldung, passierte nix oder was?)? Oder anders gefragt: Was hast Du erwartet, was passiert und was passierte stattdessen?

Bei mir machte
(string->number(number->string 123))
genau das was ich ertwartete. 123 wurde in einen String gewandelt und danach wieder in eine Zahl. Konkret gab der Funktionsaufruf 123 zurück.

Es gibt viele Lösungen dafür - nur noch keine gemeinsame. :)
Ja. Eben keine, die sich durchgesetzt hat. Die alle oder zumindest die Meisten verwenden.
 
Ich meine, wie lange gibts C jetzt schon und irgendwie ist das eine never-ending story.
Na ja, das hat Gründe: "Its all about choice" und eine riesige Community von substanzielleren Änderungen zu überzeugen ist oft unmöglich. Traditionen haben ihre Vorzüge, aber eben auch Nachteile. Wer jemals mit Rusts crate gearbeitet hat, weiss was Vorgaben für das Ordner layout für Vorzüge hat. Aber make soll eben universell sein, eine Eierlegende Wollmilchsau, was auch nicht so schlecht ist. Man bezahlt halt für alles einen Preis...
 

Yamagi

Possessed With Psi Powers
Mitarbeiter
Ach, ausnahmslos alle Build-Systeme sind warzig... Nach Jahren der Erfahrung würde ich, wenn nichts anderes durch die Sprache, die Umgebung oder das Projekt vorgegeben ist, immer GNU Make nehmen. Ja, GNU Make hat wie alle Make-Dialekte eine recht eklige Syntax und einige Dinge sind nur mit dem Kopf durch den Hintern möglich. Und auch wenn GNU Make eine der schnelleren Make-Implementierungen ist, ist es im Vergleich zu neueren Systemen wie Ninja einfach lahm. Aber: GNU Make gibt es auf praktisch allen Plattformen, die einen C-Compiler haben. Und ein sauber geschriebenes GNU Makefile funktioniert auf all diesen Plattformen einfach. Im Gegensatz zu all den hippen Lösungen, die oft schon auseinanderfallen, wenn der Entwickler Debian nutzt und man es auf CentOS bauen will. Außerdem ist GNU Make über die Jahre sehr stabil, ein Makefile von 1998 ist heute noch valide und wird es 2038 wahrscheinlich auch noch sein. Bei der Konkurrenz muss man oft schon nach 3 Jahren und 5 Unterversionen nachfrickeln, weil sich irgendwas am Syntax geändert hat oder es sich dann doch irgendwo subtil anders verhält.
 
C

CrimsonKing

Guest
Themenstarter #273
Was ging denn konkret nicht (gabs ne Fehlermeldung, passierte nix oder was?)?
Es gab eine recht kryptische Fehlermeldung, dass eine Prozedur statt "123" erwartet wurde. - Stimmt, ich hatte oben Klammern um "123" vergessen ... so, wie der Code oben steht, geht er natürlich. Das passiert, wenn man 235 Sachen gleichzeitig macht, pardonnez-moi. :o

Was mich zu der Frage führt, wieso beides geht:

Code:
(string->number(number->string 123))
(string->number (number->string 123))
Ich dachte bislang, da sei ein Leerzeichen nötig. Stelle fest: Ist es in Common Lisp auch nicht. Nie ausprobiert. Wieder was gelernt. :)

Ja. Eben keine, die sich durchgesetzt hat. Die alle oder zumindest die Meisten verwenden.
Normalerweise "den Compiler" "des Systems", würde ich annehmen. Vielleicht sollte mal jemand - analog zu Microsofts früherer "Browserauswahl" (erinnert sich noch wer?) - eine Art Tool schreiben, das bei der Einrichtung eines Systems das Standardbuildsystem zur Auswahl stellt.

Bei der Konkurrenz muss man oft schon nach 3 Jahren und 5 Unterversionen nachfrickeln, weil sich irgendwas am Syntax geändert hat oder es sich dann doch irgendwo subtil anders verhält.
CMake hätte ja aus genau diesem Grund gern eine Versionsnummer oben in der Projektdatei. Ich vermute, es besitzt inzwischen haufenweise Fallbackcode.
 

Andy_m4

Well-Known Member
Es gab eine recht kryptische Fehlermeldung, dass eine Prozedur statt "123" erwartet wurde.
Das ist keine Fehlermeldung. Er gibt immer den evaluierten Wert des Ausdrucks oder des Symbols welches Du angibst zurück.
Und string->number ist nun mal eine "procedure" a-ka Funktion.

Das ist auch alles vollkommen korrekt so, weil ja in Lisp auch Funktionen Parameter sein können. Du kannst also an eine Funktion eine andere Funktion übergeben (zum Beispiel an die Sortierfunktion eine Funktion, die zwei Elemente vergleicht). Manche Funktionen geben auch Funktionen als Return-Wert zurück.

Damit ist es dann möglich quasi eine Funktion vorzukonfigurieren und diese vorkonfigurierte Funktion im weiteren Programmablauf zu nutzen.
Denkbar wäre zum Beispiel eine Zählerfunktion die man mit einer Startzahl vorkonfiguriert die bei jedem Aufruf der Funktion einen um 1 erhöhten Wert zurückgibt.

Mal ein ganz einfaches Beispiel:
Code:
(define (erzeuge-zaehler startwert)
  (lambda()
    (set! startwert (add1 startwert))
    startwert))
Jetzt rufe ich die Funktion mal auf:
> (erzeuge-zaehler 0)
#<procedure>


Ok. Dann definiere ich mir mal einen Zähler der von 1 beginnend hochzählen können soll:
(define zaehler (erzeuge-zaehler 0))

Gucken wir uns sicherheitshalber noch mal zaehler direkt an:
> zaehler
#<procedure>


Jetzt rufen wir ihn mal auf:
> (zaehler)
1


und noch mal:
> (zaehler)
2


und noch mal:
> (zaehler)
3


Jetzt kann ich mir noch ein weiteren Zähler holen:
(define neuer-zaehler (erzeuge-zaehler 0))

Jetzt rufe ich den mal auf:
> (neuer-zaehler)
1


Sicherheitshalber noch mal den Anderen:
> (zaehler)
4


Normalerweise "den Compiler" "des Systems", würde ich annehmen.
Zumindest als Standard, wenn nicht explizit etwas anderes angegeben wurde.

zu Microsofts früherer "Browserauswahl" (erinnert sich noch wer?)
Klar.

eine Art Tool schreiben, das bei der Einrichtung eines Systems das Standardbuildsystem zur Auswahl stellt.
Das nützt mir nur nix für Programme die ich kompilieren will und die ggf. ihr eignes Süppchen kochen. Gerade für plattformübergreifend verfügbare Software kann ich nicht davon ausgehen, dass die ausgerechnet das "make" meines Systems verwenden.

Aber: GNU Make gibt es auf praktisch allen Plattformen, die einen C-Compiler haben. Und ein sauber geschriebenes GNU Makefile funktioniert auf all diesen Plattformen einfach.
Bei einigen Make-Alternativen fällt ja auch ein normales Makefile hinten raus was man dann ganz normal auf GNU make werfen kann.

Außerdem ist GNU Make über die Jahre sehr stabil, ein Makefile von 1998 ist heute noch valide und wird es 2038 wahrscheinlich auch noch sein.
Ja. Das ist auf jeden Fall ein großer Vorteil.