1 Punkte von GN⁺ 2023-08-09 | 1 Kommentare | Auf WhatsApp teilen
  • Raku wurde als möglicher Taschenrechner-Sprache in Betracht gezogen, um die Lücken von Python, J, Frink und Excel bei mathematischen Aufgaben zu schließen, und schon nach kurzen Experimenten wirkte es wie eine sehr mächtige, aber eigenwillige Sprache
  • Mit Unicode-Symbolen, alphanumerischen Infix-Operatoren, Listenprodukt·Zip·Reduce·Akkumulation, dem Matcher ~~ und Sequenzen mit ... bietet es eine große operatorzentrierte Ausdrucksstärke
  • Nutzer können nicht nur Infix-Operatoren, sondern auch Circumfix-/Postcircumfix-Operatoren definieren, und bei der Assoziativität sogar über links- und rechtsassoziativ hinaus Ketten- und Listenassoziativität festlegen
  • Multiple Dispatch verzweigt nicht nur über Typsignaturen, sondern auch über where-Laufzeitprädikate; außerdem lassen sich Funktionssignaturen und die darin enthaltenen Parameter als First-Class-Werte behandeln
  • Für die Wartung großer Codebasen wirkt es eher belastend, aber für kleines Programmieren wie Einwegskripte, Berechnungen und persönliche Tools ist es attraktiv; zentrale Hürden sind Dokumentation, der Windows-REPL, die Kompiliergeschwindigkeit und Fehler mit Sigils

Warum ich mir Raku angesehen habe und mein erster Eindruck

  • Raku ist die Sprache, die früher als Perl 6 bekannt war
  • Nachdem der Autor über seine Unzufriedenheit mit dynamischen Sprachen geschrieben hatte, empfahlen einige Nutzer Raku; deshalb wurde geprüft, ob es sich als Taschenrechner-Sprache für mathematische Aufgaben eignet
  • Bisher wurden Python, J, Frink und Excel kombiniert, aber alle hatten größere Nachteile
  • Nach einigen Tagen des Experimentierens war der Eindruck am ehesten: „eine Sprache, die von wirklich klugen Gremlins entworfen wurde, die sehr viel Feedback anderer Gremlins eingesammelt haben“

Ein ungewöhnliches Operatorsystem

  • Raku setzt aktiv auf Unicode-Operatoren
    • Ob ein Element zu einer Menge gehört, wird mit geprüft
    • Es gibt auch , und
  • Auch alphanumerische Infix-Operatoren sind erlaubt
    • Der Operator für String-Wiederholung ist x
    • Funktionskomposition ist o
  • Auch Listenkombinationen lassen sich mit kurzen Symbolen ausdrücken
    • X bildet das kartesische Produkt von Listen
    • Xf wendet f auf jedes Element des kartesischen Produkts an
    • Zf macht dasselbe im Zip-Stil
  • Für einen Infix-Operator f reduziert [f] eine Liste und [\\f] erzeugt die akkumulierten Zwischenergebnisse
    • [+] <1 2 3 4 5> ist 15
    • [\\+] <1 2 3 4 5> ist (1 3 6 10 15)

Der Matcher ~~ und Sequenzen mit ...

  • ~~ wird als Matcher verwendet, der verschiedene Arten von Vergleichen in einer Syntax zusammenfasst
    • "abc" ~~ "abc" prüft String-Gleichheit
    • "abc" ~~ Str prüft, ob es sich um den String-Typ handelt
    • "abc" ~~ {.chars == 3} prüft, ob die Länge 3 ist
    • "abc" ~~ /^b/ prüft, ob abc mit b beginnt
  • ... erkennt ein Muster in den vorherigen Werten und erzeugt daraus eine Sequenz
    • 0,1,2...10 erhöht sich von 0 bis 10 jeweils um 1
    • 0,2,4...10 ergibt eine Folge gerader Zahlen
    • 1,2,4...10 folgt einem Wachstumsmuster wie 1 2 4 8

Benutzerdefinierte Operatoren

  • Raku beschränkt sich nicht wie manche Sprachen auf benutzerdefinierte Infix-Operatoren, sondern erlaubt auch Circumfix- und Postcircumfix-Operatoren
  • Zum Beispiel kann man mit sub circumfix:<[∀ zz>($inner){sum($inner)} einen umschließenden Operator definieren, der die enthaltenen Werte aufsummiert
  • Auch ein Postcircumfix-Operator, der wie ein Vektor-Skalarprodukt aussieht, ist definierbar
    • sub postcircumfix:<| ⟩>(@left, @inside){[+] (@left Z* @inside)}
    • <1 2 3>|<4 5 6>⟩ ist 32
  • Auch die Operator-Assoziativität lässt sich vielfältig festlegen
    • Gewöhnliche links- und rechtsassoziative Infix-Operatoren sind definierbar
    • Es lässt sich Kettenassoziativität festlegen, sodass x < y < z als x < y && y < z interpretiert wird
    • Auch Listenassoziativität wird unterstützt, bei der a op b op c zu op(a, b, c) wird

Multiple Dispatch und Verzweigung über Laufzeitbedingungen

  • Raku unterstützt Multiple Dispatch und wählt damit unter mehreren Funktionsdefinitionen mit unterschiedlichen Typsignaturen die passende aus
  • Die Beispiel-Funktion f verhält sich je nach Argumentkombination unterschiedlich
    • Bekommt sie einen Skalar und ein Array, addiert sie den Skalar zu jedem Array-Element
    • Der Fall Array und Skalar wird ebenfalls unterstützt
    • Bei zwei Arrays werden die jeweiligen Elemente mit Z+ addiert
  • Noch ungewöhnlicher ist, dass Dispatch auch über Laufzeitprädikate der Werte erfolgen kann
    • multi my_abs(Int $x where {$x > 0}) {$x}
    • multi my_abs(Int $x) {-$x}
  • Die Signatur einer Funktion ist ein First-Class-Wert, und auch die Parameter innerhalb dieser Signatur sind First-Class-Werte

Kleine Features mit großer Oberfläche

  • Definiert man eine MAIN-Funktion, werden deren Parameter automatisch in CLI-Flags umgewandelt
  • Objekte bringen sehr viele vordefinierte Methoden mit
    • Das List object bietet Methoden für alle Permutationen, alle k-Kombinationen und alle Sliding Windows
  • Junctions sind eine ungewöhnliche Wertform, mit der mehrere Vergleiche gleichzeitig möglich werden
    • 1|2 expandiert zu any(1, 2), sodass 1 < 1|2 gilt
    • 1&2 expandiert zu all(1, 2), sodass 1 !< 1&2 gilt
  • Jeder Infix-Operator kann durch ein vorangestelltes ! zu einem negierten Operator werden
  • Raku wirkt wie eine Sprache, die gleichzeitig $kebab-case-Namen und Infix-Subtraktion besitzt; vermutlich sorgt das Sigil dafür, dass x-y unterschieden werden kann
  • Die Regex-Syntax ist nicht abwärtskompatibel zu Perl 5
    • Obwohl Sprachen 30 Jahre lang dem PCRE-„Standard“ gefolgt sind, hat Perl 6 damit gebrochen

Noch ungesehene Bereiche und der Reiz im Kleinen

  • Das Gesehene ist nur ein Teil der Funktionen, vor allem aus Sicht der Taschenrechner-Nutzung
  • Das Objektsystem, Pakete und grammars wurden noch nicht gelernt
  • Es fehlen noch viele Features, etwa samewith, das innerhalb eines Funktionskörpers dieselbe Funktion mit neuen Argumenten erneut aufruft
  • Eine Legacy-Codebasis in Raku pflegen zu müssen, wäre vermutlich sehr hart, aber für Programming In The Small wirkt die Sprache stark
    • Einwegskripte
    • Berechnungen
    • Persönliche Tools
    • Genau die Art von Aufgaben, die ursprünglich gesucht war

Kritik und Hoffnung

  • Die Dokumentation ist sehr dünn, und wegen der starken Symbolabhängigkeit ist das Suchen schwierig
    • Selbst für jemanden, der mehrere schlecht dokumentierte Sprachen gelernt hat, kann Raku wegen seiner viel größeren Komplexität die Motivation senken
  • Unter Windows stürzt der REPL ab, wenn man Unicode eingibt
  • Auch der Compiler ist ziemlich langsam; selbst kleine Dateien brauchen mehr als 0,5 Sekunden, was iterative Arbeit schmerzhaft macht
  • Das Sigil-System ist unkomfortabel
    • Es gab einen Fall, in dem 30 Minuten für das Debugging eines Problems verloren gingen, weil versehentlich $x statt @x verwendet wurde
  • Insgesamt gefällt dem Autor Raku, und er hofft auf seinen Erfolg; zugleich hofft er, dass sich mit der Zeit Kompilierzeiten und Dokumentation verbessern

1 Kommentare

 
GN⁺ 2023-08-09
Hacker-News-Kommentare
  • Wenn man Programmiersprachen in einen zweidimensionalen Raum einordnen würde, könnten die Achsen lauten: wie sehr sie überraschen und, wenn sie überraschen, ob das angenehm oder schrecklich ist.
    Von normalen Sprachen erwartet man stillschweigend, dass sie meist unten links liegen: „überrascht kaum, aber wenn doch, dann angenehm“. Raku wirkt dagegen wie eine seltene Sprache, die ganz bewusst den sonst eher leeren Bereich oben links anstrebt. Eher nach dem Motto: „Seltsam, oder? Ist das nicht cool?“

    • Das Problem ist, dass diese Achsen subjektiv sind. Etwas kann zugleich angenehm und schrecklich sein: Ich habe früher einmal JavaScript wie document.write = function ... geschrieben, und es hat zwar getan, was nötig war, was erfreulich war, war aber gleichzeitig ziemlich schrecklich.
    • Als ich für eine Uni-Aufgabe einen Parser bauen musste, entdeckte ich Rakus Grammar-Funktion. Sie nahm mir fast alles ab und fühlte sich wie ein Cheat-Code an, machte aber trotzdem Spaß.
    • Da es ursprünglich Perl 6 war, ist es nicht überraschend, dass Perl-Entwickler eine Sprache wollten, die keiner anderen Sprache wirklich ähnelt.
      Auch Perl hatte viele „angenehme Überraschungen“, und ich sehe Raku vor allem als Design, das die schrecklichen Überraschungen von Perl beseitigen sollte.
    • Bei der Stelle, an der prüft, ob etwas in einer Menge enthalten ist, verstehe ich, worauf das hinausläuft.
      0,2,4...10 wird zu (0 2 4 6 8 10), aber dass 1,2,4...10 zu (1 2 4 8) wird, lässt einen denken: „Sucht es die nächste Zahl in der OEIS?“
    • Raku schien mit jedem Absatz immer weiter in den oberen rechten Bereich zu wandern, also in die Zone von überraschend und schrecklich.
  • Raku ist als Sprache interessant, aber einige Idiome gehen mir nicht richtig in den Kopf.
    Ähnlich wie AppleScript, das wie natürliche Sprache wirken wollte und dadurch seltsam wurde, mischt Raku natürlichsprachlich anmutende Elemente wie my, say, sub, gather mit Symbolen wie @, Moduldeklarationen und anderen Syntaxentscheidungen, die für Außenstehende byzantinisch wirken. Das 99-bottles-Beispiel kann man logisch nachvollziehen, aber intuitiv entdecken lässt es sich schwer. Es gibt viele Symbole, die je nach Kontext überladen wirken, sodass ich Raku selbst für Aufgaben, bei denen es optimal sein könnte, etwa Natural-Language-Parser, nicht direkt verwenden wollen würde.
    https://examples.raku.org/categories/module-management/Fletc...

    • Du scheinst Perl nicht ausprobiert zu haben. Mit Perl-Hintergrund wirkt ein großer Teil dieser Syntax ziemlich vertraut, besonders das Sigil @ für Arrays.
    • Bei Bash habe ich genau dasselbe Gefühl.
  • Meine Lieblingsfunktion in Raku ist, dass Ganzzahldivision und Dezimal-Literale beide Rat zurückgeben, einen rationalen Zahlentyp.
    Alle wissen, dass Gleitkommazahlen nicht ideal sind, aber kaum eine Sprache versucht wirklich, davon wegzukommen; in Raku wird ein Literal erst mit wissenschaftlicher Notation zu einem Gleitkomma-Literal.

    • Noch ältere Sprachen wie Common Lisp und Scheme warten ebenfalls darauf, von Leuten entdeckt zu werden, die IEEE-754-Gleitkommazahlen nicht mögen.
      Sie haben eine Zahlenhierarchie, die rationale Zahlen und sogar komplexe rationale Zahlen umfasst, und Zahlen mit beliebiger Genauigkeit werden selbstverständlich ebenfalls unterstützt. Die Kombinierbarkeit ist hervorragend.
    • In der Praxis ist das eher eine schlechte Funktion. Wenn die Rat-Darstellung zu groß wird, wird sie nämlich automatisch in eine Gleitkommazahl umgewandelt.
      1/10 ist Rat, aber 1/100000000000000000000 wird zu Num. Es gibt auch FatRat, das nicht hochgestuft wird, aber das ist nicht der Standard.
    • Schemes Zahlenhierarchie verarbeitet exakte Darstellungen seit Jahrzehnten korrekt.
      Daher ist es weniger so, dass man sich „davon entfernt hat, ungenaue Gleitkommazahlen zu verwenden, obwohl man sie nicht explizit angefordert hat“; vielmehr war Scheme nie in diesem Zustand.
    • Racket würde dem ebenfalls widersprechen. Es funktioniert richtig.
      (/ 1.0 3.0) ergibt 0.3333333333333333, (/ 1 3) ergibt 1/3, und (- (+ 0.1 0.2) 0.3) ergibt 5.551115123125783e-17.
    • Ich bin mir nicht sicher, ob das gut ist. Ich weiß, wann man Dezimal-/Rationaltypen und wann Gleitkommazahlen verwenden sollte, aber in meinem privaten Python-Code gibt es deutlich mehr float()- als Decimal()-Aufrufe.
      Wenn man nicht direkt mit Geld arbeitet, sind Gleitkommazahlen fast immer die gewünschte Wahl.
  • Ich hatte nicht den Eindruck, dass die Raku-Dokumentation „wirklich furchtbar“ ist; im Gegenteil, die offizielle Dokumentationsseite fand ich beeindruckend, weil sie Konzeptdokumentation und API-Dokumentation als zentrale Anlaufstelle vereint.
    https://docs.raku.org/
    Als Einstiegspunkt in die Konzeptdokumentation ist diese Seite sehr gut: https://docs.raku.org/language

    • Ich nutze Raku seit einigen Jahren, und die Dokumentation ist großartig und zugleich unvollständig.
      Das meiste, was vorhanden ist, ist gut geschrieben und enthält nützliche Beispielcodes, aber gelegentlich stößt man auf Dinge, die gar nicht dokumentiert sind oder nur einfache Fälle behandeln. Besonders problematisch war das Modulsystem; die Unterscheidung zwischen Modulen und Paketen ist allein durch Lesen der Modules-Seite schwer zu verstehen. Importierte Namensräume und deklarierte Namensräume können unterschiedlich sein, aber damit der Compiler sie findet, muss die Verzeichnisstruktur zum Namensraum passen. Das ist nützlich und auf seltsame Weise logisch, aber ich musste es durch Ausprobieren lernen.
    • Das liegt an der Perl-Kultur. Die Perl-FAQ und die Manual-Pages waren dank der Mentalität der Programmierer, die Perl nutzten, erstklassig: geistreich, knapp und skurril.
    • Die Perl-Manual-Pages waren immer hervorragend.
  • Für Rakus coole Unicode-Operatoren gibt es alle ASCII-Ersatzschreibweisen.
    Zum Beispiel sind die Ersatzschreibweisen für , , , jeweils (elem), !(elem), (cont), !(cont).
    https://docs.raku.org/language/unicode_ascii#Other_acceptabl...

    • Ich würde definitiv die ASCII-Version verwenden.
  • Es scheint, als würden die typischen Kritiken, die auftauchen, bevor man eine Sprache wirklich kennt, immer noch wiederholt. Früher war es bei Perl das „Line Noise“, jetzt heißt es, Raku verwende ohne Hemmungen Unicode-Operatoren
    Das ist aber optional, und ich habe sie selbst verwendet, um Code auf dem Bildschirm kompakt und ausdrucksstark wirken zu lassen. Für einen bedachten und kreativen Einsatz von Unicode passt das gut. Auch die Abneigung gegen Sigils ist eine häufige Reaktion, aber ich habe Raku/Perl 6 genutzt, weil ich die Ausdrucksstärke von Perl mag, diese Schweizer-Armee-Kettensäge; Raku fühlt sich an wie Perl hoch zwei, in besonders Perl-typischer Form. Es ist aufgeräumt und ausdrucksstark, mit einem riesigen Haufen Funktionen auf dem guten alten Perl. Die Dokumentation ist ebenfalls gut, muss aber weiter gepflegt werden, und verglichen mit der Perl-Dokumentation liegt die Messlatte sehr hoch

    • Ich frage mich, wie man Nicht-ASCII-Operatoren eingibt. Ob das ein spezielles Tastaturlayout ist, ob der Editor bestimmte Sequenzen automatisch umwandelt oder ob man rohe Unicode-Escapes schreibt, weiß ich nicht
      Nur um ein paar Zeichen zu sparen, wirkt das kompliziert und nicht besonders sinnvoll
  • Ich habe mich manchmal gefragt, wie eine Programmiersprache aussehen würde, die voll von Syntax Sugar ist, und jetzt weiß ich es
    Es fühlt sich an wie: „Schrecklich, aber seltsam anziehend, ich kann nicht wegsehen, zeig mir mehr“

    • Vielleicht gefällt dir die Hobby-Sprache noulith, die von der Person entwickelt wurde, die in letzter Zeit mehrere Advent of Code gewonnen hat
      In der GitHub-Beschreibung heißt es: „slaps roof of [programming language]* this bad boy can fit so much [syntax sugar] into it.“ Auch den jüngsten Advent of Code hat diese Person mit dieser Sprache gewonnen: https://github.com/betaveros/noulith
    • Warte nur, bis du Raku-Grammars kennenlernst
    • Bei modernem C++ habe ich jedes Mal dieselbe Reaktion
  • Es ist erwähnenswert, dass Raku ursprünglich als Perl 6 begann und viele Designphilosophien aus der Perl-Denkweise stammen
    Daran, dass der Autor sofort auf den x-Operator für String-Wiederholung anspringt, sieht man, dass er die Geschichte von Perl und Raku offenbar nicht besonders gut kennt; das gibt es in Perl seit Jahrzehnten

    • Im Text steht: „Die Regex-Syntax ist nicht abwärtskompatibel mit Perl 5. 30 Jahre lang folgten Sprachen dem PCRE-‘Standard’, und Perl 6 hat das einfach alles weggeworfen“, also scheint zumindest ein gewisses Wissen vorhanden zu sein
    • In der ersten Fußnote steht, dass Raku früher als Perl 6 bekannt war
    • Die Übertreibung „Perl6/Raku ist völlig anders als Perl 5“ ist viel zu aufgeblasen
      Es hieß nicht ohne Grund Perl 6, und es wurde von fast demselben Perl-Team entwickelt. Wer Perl 5 halbwegs ausgiebig genutzt hat, sieht das Erbe in Perl6/Raku deutlich. Auch das gesamte Objektmodell von Raku ist im Grunde eine etwas leistungsfähigere Version von Moose.pm, einem Perl-5-Modul aus CPAN
  • Ehrlich gesagt ist die Regex-Syntax von Perl 5/PCRE furchtbar
    Der einzige Grund, warum sie existiert, ist, dass (? in der alten Regex-Syntax ein Syntaxfehler war und man es deshalb beliebig neu definieren konnte. Raku ist der Versuch, von Anfang an eine vernünftige Regex-Sprache zu entwerfen, jetzt, da man weiß, was Regex ausdrücken können sollte. Die Alternative ist, für weitere 30 Jahre in Dingen wie (?:this|(?>or that)) festzustecken

    • Nicht furchtbar, eher unentzifferbare Schwarzmagie, und wenn man sie verstanden hat, ist sie großartig
      Ich habe Perl schon lange nicht mehr angefasst, aber Regex verwende ich immer noch häufig
    • Einverstanden, aber sie ist wirklich nützlich
  • In einem bestimmten Sinn ist es definitiv ein Gremlin. Ich mag seltsame und komplexe Werkzeuge, die die Produktivität erhöhen
    Der Gegenüberstellung „große Programme vs. kleine Programme“ stimme ich allerdings nicht zu. Weniger kluge Leute könnten das so verstehen, dass es für große Aufgaben eine schlechte Sprache sei, dabei kann sie in Wirklichkeit genauso gut wie andere Sprachen sein oder sogar besser. Das Problem ist, wie bei anderen Gremlin-Sprachen auch, dass man Weisheit braucht, um sie gut einzusetzen. Zum Beispiel verwechselt kaum jemand $x und @x, wenn er genügend Erfahrung mit ähnlichen Sprachen hat. Sigils machen das Lesen von Code sogar angenehmer, weil sie sofort den einfachen Typ einer Variable, in Raku das Interface, anzeigen, und man denselben Variablennamensraum mit unterschiedlichen Sigils sinnvoll nutzen kann. Es wirkt seltsam, sieht wie unnötige Zeichen aus und man muss die Bedeutung kennen, aber es kann das Leben leichter machen: https://www.perl.com/article/on-sigils/
    Probleme entstehen bei Leuten, die nicht genau wissen, was sie tun. Für solche Leute kann diese Gremlin-Sprache ein lebender Albtraum sein, und sie brauchen viele Schutzvorrichtungen wie Bowling-Banden, Schwimmflügel, Kevlar-Handschuhe, Schutzhelme und GPS. Das heißt nicht, dass man mit einer Gremlin-Sprache keinen Wolkenkratzer bauen kann; nur unfallanfällige Nicht-Gremlins können es nicht, ein weiser Gremlin schon

    • Die Denkweise „Dieses Werkzeug kann nur von Leuten benutzt werden, die gut genug sind“ halte ich für einen massiven Design Smell
      Werkzeuge existieren, um Teams dabei zu helfen, die nötige Arbeit besser oder schneller zu erledigen. Wenn man ein unnötig kompliziertes Werkzeug einsetzt, um Juniors auszusieben oder das eigene Ego zu streicheln, ist dieses Werkzeug für den Rest der Organisation eher eine Waffe als eine Hilfe