Ich lerne gerade Lisp, und zwar aus einer Sprachentwicklung, die Locomotive BASIC -> Z80 Assembler -> Pascal -> C -> Perl -> C # -> Ruby ist. Mein Ansatz ist es, gleichzeitig:
- Schreiben Sie einen einfachen Web-Scraper mit SBCL, QuickLisp, closure-html und drakma
- Sehen Sie sich die SICP-Vorlesungen an
Ich denke, das funktioniert gut. Ich entwickle eine gute "Lisp-Brille", da ich Lisp jetzt einigermaßen leicht lesen kann. Ich bekomme auch ein Gefühl dafür, wie das Lisp-Ökosystem funktioniert, z. B. Quicklisp für Abhängigkeiten.
Was mir jedoch wirklich fehlt, ist ein Gefühl dafür, wie ein erfahrener Lisper tatsächlich funktioniert .
Wenn ich für .NET codiere, habe ich Visual Studio mit ReSharper und VisualSVN eingerichtet. Ich schreibe Tests, ich implementiere, ich refactor, ich begebe. Wenn ich dann genug davon getan habe, um eine Geschichte fertigzustellen, schreibe ich ein paar AUATs. Dann starte ich ein Release-Build auf TeamCity, um die neuen Funktionen dem Kunden zum Testen und hoffentlich zur Genehmigung zur Verfügung zu stellen. Wenn es sich um eine App handelt, die ein Installationsprogramm benötigt, verwende ich entweder WiX oder InnoSetup und erstelle das Installationsprogramm offensichtlich über das CI-System.
Meine Frage lautet also: Wie sieht Ihr Workflow als erfahrener Lisper aus? Arbeiten Sie hauptsächlich im REPL oder im Editor? Wie machst du Unit-Tests? Kontinuierliche Integration? Verpackung & Bereitstellung? Wenn Sie sich an Ihren Schreibtisch setzen, eine Tasse Kaffee auf die eine und ein gerahmtes Foto von John McCarthy auf die andere Seite dämpfen, was machen Sie dann ?
Momentan habe ich das Gefühl, dass ich mich mit Lisp-Codierung auseinandersetze, aber nicht mit der Lisp-Entwicklung ...
Antworten:
Die meisten Leute auf comp.lang.lisp und Lisp Forum empfehlen eine Kombination aus Emacs und SLIME, vorausgesetzt, Sie möchten nicht für eine kommerzielle Implementierung wie Allegro oder LispWorks bezahlen. Das SLIME-Video zeigt den Arbeitsprozess. Ich benutze Emacs und SLIME, um zu Hause persönliche Programme zu entwickeln, und die Kombination kann sehr effizient sein.
SLIME ermöglicht Ihnen die Integration zwischen Emacs und dem REPL. Normalerweise lade ich alle meine Dateien und öffne dann die, an der ich arbeite, in Emacs. Nachdem ich die einzelnen Funktionen
C-x C-e
eingegeben oder geändert habe, drücke ich , um die Funktionsdefinition in der REPL auszuführen. Dann kann ich in den REPL-Puffer wechseln und die Funktion ausprobieren. Die gesamte REPL-Historie ist mit Standard-Emacs-Tastenkombinationen verfügbar und bearbeitbar, sodass Funktionsaufrufe mit verschiedenen Parametern einfach wiederholt werden können.quelle
Ich arbeite hauptsächlich mit Clojure und hier ist mein Setup:
Der Workflow beim Codieren sieht im Allgemeinen folgendermaßen aus:
Insgesamt unterscheidet es sich nicht allzu sehr von einem regulären Java / C # -Workflow, abgesehen von der interaktiveren Verwendung von REPL während der Entwicklung.
quelle
Ergänzend zu den anderen Antworten führe ich eine Kombination aus der Art der Entwicklung "Überlege dir das Problem genau und schreibe dann die Lösung auf" und dem Stil "Beginne mit einer Antwort und bringe dein Programm iterativ in Form". Es ist normalerweise in der Mitte. Ich beginne mit einer allgemeinen Vorstellung davon, wie mein Programm aussehen soll, und beginne dann damit, es zu schreiben. Dabei versuche ich, mir im Laufe der Zeit neues Wissen über die Problemdomäne anzueignen, um meinen Ansatz zu überarbeiten. In der Praxis bedeutet das, dass ich viel experimentiere und viel Code schreibe. Ich versuche verschiedene Ansätze und kann sehr schnell die Richtung wechseln. Lisp ist gut für diese Art von Entwicklung. Deshalb mag ich TDD nicht so sehr, ich muss erst wissen, was ich tun möchte, um TDD effektiv zu machen.
Eine andere wichtige Sache, die ich versuche, ist, mehr über das Protokoll zwischen den verschiedenen Teilen eines Programms nachzudenken. Im Gegensatz zu anderen OO-Sprachen konzentriert sich CLOS in Common Lisp mehr auf das Konzept einer generischen Funktion, IOW-Methoden befinden sich außerhalb von Klassen und stehen im Mittelpunkt der Entwicklung. Manchmal beginne ich einfach mit einer Reihe von GFs, die das gewünschte Protokoll definieren. Ich schreibe eine einfache Implementierung und benutze sie, um das Protokoll zu konkretisieren, bevor ich eine echte Implementierung schreibe. Angenommen, ich schreibe eine Ebene, in der eine Reihe von Blog-Posts gespeichert sind, ich habe möglicherweise eine Reihe von GFs, die definieren, wie Blog-Posts erstellt, bearbeitet und durchsucht werden, und ich würde eine einfache Implementierung schreiben, mit der Blog-Posts in einer Liste im Speicher gespeichert werden und nachdem ich mit meinem Protokoll zufrieden bin, schreibe ich eine Implementierung, die Blog-Posts in einer Datenbank speichert oder in Dateien schreibt.
Lisp macht es so einfach, die Richtung zu ändern und einen anderen Ansatz zu wählen, wenn Sie wissen, dass Ihre aktuelle Lösung nicht optimal ist, und ich versuche, sie zu maximieren.
Ein weiterer wichtiger Punkt: Verwenden Sie Ihre Umgebung optimal, lernen Sie die Verwendung verschiedener Kompilierungseinstellungen, um Ihren Code mit mehr Debugging-Informationen zu kompilieren, und machen Sie sich die Tatsache zunutze, dass lisp sowohl kompiliert als auch interpretiert werden kann. Verwenden Sie lisps-introspektive Funktionen wie MOP, verwenden Sie Schleimfunktionen, um die Dokumentation nachzuschlagen, verwenden Sie den Inspektor, um Objekte zu untersuchen, konsultieren Sie regelmäßig die Hyperspezifikation, behandeln Sie Ihr System eher wie ein Betriebssystem als wie einen statischen Compiler für Ihren Code, es ist viel mehr mächtiger als das.
Für einen Anfänger ist Lisp nicht gerade ein Gewinn gegen Python und Ruby, aber wenn Sie mehr Erfahrung damit haben, erhalten Sie enorme Gewinne gegen kleinere Umgebungen.
Am wichtigsten ist, dass Sie Spaß haben und diese Sprache lieben. Manchmal ist es einfach zu einfach, sich entmutigen zu lassen und die derzeit beliebten Blub-Sprachen zu verwenden. Wenn du bei lisp bleibst, wird es dich zurückzahlen.
quelle
Ich arbeite normalerweise in einem Editor, der eine Verbindung zu einer REPL hat (normalerweise in Emacs bearbeitet und SLIME als Brücke zu einer Common-Lisp-Umgebung verwendet). Ich tendiere dazu, sowohl "unten" als auch "oben" zu beginnen, arbeite in Richtung der Mitte und überarbeite das Design, während ich gehe.
Zum Testen habe ich eine REPL. Ich finde, dass es hilft, Code zu testen, während ich gehe. Ich schreibe manchmal formellere Tests oder Benchmarks (normalerweise, sobald ich mich in der Optimierungsphase befinde). Lassen Sie eine langsamere, bekanntermaßen gute Implementierung einer Funktionalität durchführen, experimentieren Sie (in einem Editorfenster) mit Code für eine optimierte Version, senden Sie diesen an den zugrunde liegenden Lisp-Code und überprüfen Sie, ob er schneller ist und dieselben Ergebnisse wie der langsamere zurückgibt Code.
Was das Packen betrifft, habe ich Dienstprogrammcode, mit dem ich ASDF-installierbare Projekte packen, in ein Download-Repository einfügen und die Versionsverwaltung durchführen kann.
quelle