it-swarm.dev

Automatische Programmierung: Schreiben Sie Code, der Code schreibt

Nach dem Lesen des Buches The Pragmatic Programmer war eines der Argumente, die ich am interessantesten fand, "Code schreiben, der Code schreibt".

Ich habe versucht, über das Internet nach weiteren Erklärungen oder Artikeln zu suchen, und obwohl ich einige gute Artikel zu diesem Thema gefunden habe, habe ich immer noch keine spezifische Code-Implementierung oder gute Beispiele gefunden.

Ich denke, es ist immer noch kein so verbreitetes Argument, etwas, dem es an Dokumentation mangelt oder das von so vielen Menschen nicht angenommen wird, und ich würde gerne mehr darüber erfahren.

Was denkst du über das Thema? Steigert es wirklich Ihre Produktivität? Was sind einige gute Ressourcen zu diesem Thema, darunter Bücher, Blogs, Diashows usw.?


Einige Codebeispiele wären sehr dankbar, damit ich die Implementierung besser verstehen kann.


Hier ist die Wiki-Seite zu diesem Thema mit verschiedenen relevanten Programmiertechniken wie Meta-Programmierung, generative Programmierung und Code-Generierung.

110
Jose Faeti

In der LISP-Welt ist es durchaus üblich, den Code zu sehen, der Code schreibt, der Code schreibt (und so weiter). Daher ist jedes LISP- oder Schema-Projekt mit angemessener Größe ein gutes Codebeispiel. Ich würde empfehlen, sich die Compiler- und Laufzeitquellen Racket sowie Bigloo anzusehen, deren Bibliotheken einfach brillant sind.

Was die Produktivität betrifft: Ich verwende Metaprogrammierung als dominante Technik in fast allen meiner Entwicklungsarbeiten, und es hilft eindeutig sehr, sowohl die Codegröße zu reduzieren als auch die Lesbarkeit zu verbessern. Der Schlüssel liegt in der Verwendung von Domain Specific Languages , und Metaprogrammierung ist eine der effizientesten Möglichkeiten, sie zu implementieren.

49
SK-logic

Ich gehe lieber etwas weiter und schreibe statt Code, der schreibt Code, Code, der Objekte, Methoden und Funktionen generiert. Dies kann beispielsweise mit LISP-Makros oder Ruby dynamische Programmänderungsfunktionen) erreicht werden.

Der kleine Unterschied besteht darin, dass Sie nicht mit Quelldateien enden, die automatisch generiert wurden. Normalerweise sind diese Dateien nicht für Menschen lesbar und können nicht geändert werden. Warum sollten Sie sich also darum kümmern? Ich mag die Idee nicht, meine Codebasis mit etwas zu erweitern, das ich nicht kontrollieren kann.

Ein Buch, das ich gerne zu diesem Thema gelesen habe, war Metaprogramming Ruby (wenn Sie Ruby Sprache) kennen)


Nach folgender Frage im Kommentar bearbeiten:

Warum sollte es nützlich sein, wenn ich den generierenden Code noch codieren muss? Sollte ich einen Code schreiben, der abhängig von Benutzereingaben unterschiedliche Dinge generieren kann, damit ich ihn immer wieder verwenden kann?

Erstens ist die Metaprogrammierung kein Ziel, sondern ein Werkzeug. Verwenden Sie keine Metaprogrammierung, da "es cool ist" oder "X sagte, jeder Entwickler sollte es verwenden".

Ich denke, ein guter Grund für die Verwendung der Metaprogrammierung besteht darin, ein allgemeines Muster (Muster als etwas, das sich wiederholt) zu verallgemeinern, das Sie in Ihrem Code gefunden haben und das keine andere übliche Programmiertechnik (Vererbung, Entwurfsmuster usw.) erreichen kann.

Wie von Jordan gesagt , ist ein typischer Anwendungsfall die Datenbankbehandlung und ORM (Object Relation Mapping). In Ruby sollten Sie sich noch einmal ActiveRecord ansehen, das ein großartiges Beispiel für die auf ORM angewendete Metaprogrammierung ist.

Als letzte Anmerkung:

Denken Sie nicht "Ich möchte Metaprogrammierung anwenden, wo könnte ich sie in meinem Code anwenden?".

Think "Ich sehe dieses Muster, das sich in meinem gesamten Code wiederholt. Ich kann keinen Weg finden, den Code in etwas Kleineres und Wiederverwendbareres umzugestalten. Vielleicht kann mir Metaprogrammierung helfen? "

67
David

Verwenden Sie noch besser Code, den jemand anderes geschrieben hat und der Ihren Code für Sie schreibt.

Die Codeautomation eignet sich im Allgemeinen gut für ORMs und anderen Datenbankinteraktionscode und natürlich für die wiederholte, aber ähnliche Codeerstellung.

Wenn Sie viele ähnlich aussehende Klassen aufbauen, hätten Sie das vielleicht auch viel früher in einer dynamischen Sprache erreichen können, aber ich schweife ab.

Dies wird von vielen Menschen begrüßt, obwohl die Software häufig als Codegeneratoren gekennzeichnet ist.

Sehen Sie sich Unternehmen und Produkte wie CodeSmith und MyGeneration an oder stöbern Sie in diesem Wikipedia-Artikel: http://en.wikipedia.org/wiki/Comparison_of_code_generation_tools

19
Jordan

Eines der klassischen Beispiele ist Lex und Yacc. Ihr Hauptzweck ist es, die Plackerei zu vermeiden, Parser zu schreiben. Auf dem Weg dorthin machen sie es viel schneller, komplexe Parser mit vielen Regeln und Zuständen zu erstellen, und sie vermeiden auch alle Überraschungsfehler, die von Leuten gemacht werden, die ihre eigenen rollen.

Dies ist auch die Idee hinter c, einem Tool zum Schreiben von Assemblern. Das Gleiche gilt für jede Hochsprache, die Sie benennen möchten. Für Tools, die Code für Sie schreiben, gibt es einige einfache Paradigmen.

Ein korrektes IDE) hilft, indem es Dokumentation zur Hand hat, intelligente automatische Vervollständigung und Codefragmente. IDEs enthalten auch verschiedene Vorlagen, sodass Sie ein Programm nicht von Grund auf neu starten müssen. Es gibt Programme ein Uml-Diagramm zu erstellen und Klassen in einer Hochsprache zu erstellen.

Schließlich können Sie Ihre eigenen Tools zur Codegenerierung innerhalb Ihres Problemsatzes schreiben. So haben Lex und Yacc angefangen. Genau aus diesem Grund gibt es jede Art von domänenspezifischer Sprache. Sie erstellen einige Bausteine, die Ihre Lösung in besser verständlichem Code beschreiben, allgemeine Aktivitäten oder komplizierte Abschnitte mit einfachen Befehlen abschließen. Sie suchen nicht nach einer Lösung für jedes Problem, sondern nur nach einer einfacheren Definition des spezifischen Problems, mit dem Sie sich befassen.

In gewisser Weise ist alles, was Sie über der Binärschicht tun, Code-Automatisierung.

16
Spencer Rathbun

Metaprogrammierung

Metaprogrammierung ist in vielen Geschäften eine umstrittene Technik. Der Grund ist, wie bei jedem mächtigen Werkzeug, dass das Ausmaß der Hilfe oder des Schmerzes groß ist.

Vorteile

  • Ausdrucksstärker, weniger Code zum Schreiben und Verwalten (oft um eine Größenordnung oder mehr)
  • Konsistenz, konsistenteres Verhalten gegenüber der Klasse von Problemen, die Sie mit dem Code lösen
  • Produktivität, weniger Code für eine Lösung für einen größeren Problembereich

Nachteile

  • Komplexität kann sehr kompliziert sein, obwohl weniger Code vorhanden ist
  • Sicherheit, manchmal Typensicherheit und statische Analyse im Allgemeinen werden geopfert
  • Fehler wirken sich mehr aus, kleine Fehler haben größere Auswirkungen

Ich bin ein großer Fan von Metaprogrammierung, aber ich mache das schon lange. Für mich macht der Kompromiss zwischen reduzierter Codegröße und konsistentem Verhalten die Risiken mehr als wett. Weniger Code bedeutet weniger Fehler, weniger Code, der gewartet werden muss, und ich kann normalerweise sehr schnell große Funktionen hinzufügen.

Dies bedeutet jedoch nicht, dass ich denke, dass sich alle Programmierer darauf einlassen sollten. Ich habe große Probleme gesehen und musste sie beheben, die durch Metaprogrammierung entstanden sind. Normalerweise ab dem Zeitpunkt, an dem Personen, die das Konzept nicht verstehen und versucht haben, die Funktionalität zu erweitern oder einfach nur einen Fehler zu beheben. Es bedarf einer bestimmten Denkweise, die zumindest detailorientiert ist. Die Frage zur Verwendung von Metaprogrammiertechniken sollte eine Teamentscheidung sein. Wenn Sie Teammitglieder haben, die nicht verstehen, nicht das Temperament dafür haben oder einfach dagegen sind, sollte kein Team Metaprogrammierung verwenden.

13
dietbuddha

Der meiste Code schreibt Code. Zum Beispiel hilft PHP-Code beim Schreiben von HTML. Die PHP-PDO-Bibliothek hilft beim Schreiben von SQL-Aufrufen. Die Datei-E/A-Funktionen schreiben Code für die Kommunikation mit dem Betriebssystem. Selbst ein regulärer Funktionsaufruf verweist auf einen anderen Codeblock, der ausgeführt wird. Ihre Funktionsaufrufe schreiben also Code.

Im Allgemeinen können wir uns das Rechnen als Schreiben von Codes vorstellen, die Codes rekursiv schreiben und einen Stapel bilden, der endet, wenn er gegen die physikalische Realität von in Hardware verdrahteten Codes läuft.

9
Ben Haley

In unserem Unternehmen verwenden wir einige Tools, die tatsächlich C++ - oder C # -Klassen mit aus dem Internet heruntergeladenen Daten generieren. Diese Klassen sind Datencontainer und enthalten eine große Anzahl von Objekten in Listen.

5
Holli

Metaprogrammierung ist seit langem Teil der Programmierung. Betrachten Sie nicht nur Tools wie SWIG oder WYSIWYG-Designer, die Code erstellen, sondern auch Tools in der Sprache wie den Präprozessor von C oder sogar die Vorlagen von C++ und die Generika von C #/Java - ganz zu schweigen von Reflection.

In der Tat könnte man argumentieren, dass jeder Compiler nur ein anderes Metaprogramm ist - sie nehmen Programmtext und Ausgabemaschine oder VM Code. Und, Leben ohne Compiler? Owch.

5
DeadMG

Hier ist ein konkretes Beispiel aus meiner Vergangenheit.

Ich habe an einem Standort mit etwa 50 MB Delphi-Quellcode gearbeitet und die BDE für den Datenzugriff verwendet. Sie wollten auf Direct Oracle Access umsteigen, um ein Oracle-Upgrade nach der höchsten von der BDE unterstützten Version zu ermöglichen (8i, wenn ich mich richtig erinnere).

Anstatt ein Team von Programmierern dazu zu bringen, jedes Formular- und Datenmodul zu bearbeiten und jede Komponente manuell zu ändern, habe ich ein Perl-Skript geschrieben, das:

  1. Analysierte das DFM (Formulardatei) und identifizierte alle TQuery-, TTable-, TStoredProcedure- und TDatabase-Objekte. Dabei wurden die Elemente in einer Liste gespeichert.

  2. Analysierte den PAS (Code) und identifizierte die Verwendung der Objekte - führten die TQueries Aktualisierungen oder Auswahlen durch? Außerdem wurden alle im Code erstellten Objekte identifiziert, anstatt in einem Formular in der IDE abgelegt zu werden.

  3. DFM & PAS wurden neu geschrieben, indem die Objekttypen entsprechend geändert wurden (z. B. TTable -> TOracleDataSet mit der SQL-Eigenschaft "select * from" usw.) und die Methodenaufrufe. Außerdem wurden zusätzliche Methodenaufrufe hinzugefügt, um Parameter zu schließen, zu öffnen und festzulegen.

Kurz gesagt, 3 Wochen Arbeit, um das Skript so zu optimieren, dass es an verschiedenen Anwendungen arbeitet, die von verschiedenen Teams mit unterschiedlichen Codierungsstilen geschrieben wurden, anstatt der ursprünglichen Schätzung von 5+ Entwicklern, die 6 Monate lang arbeiten.

Und der Grund, warum ich überhaupt daran gedacht habe, diesen Ansatz zu verwenden, war das Lesen von The Pragmatic Programmer

5
mcottle

Wie Sie dies tun, hängt von Ihren Anforderungen ab. Angenommen, Sie verwenden statische Codegenerierung, können Sie die gesamte Infrastruktur selbst schreiben oder einen vorhandenen Generator wie CodeSmith oder MyGeneration verwenden. Mit diesen müssen Sie nur die erforderlichen Vorlagen schreiben.

Mein letztes Projekt, das dies beinhaltete, waren einige grundlegende ASP.NET CRUD-Bildschirme (Codegenerierung ist dafür gut). Der Prozess definierte Entitäten als Metadaten in XML-Dateien. Schreiben Sie Vorlagen, um die verschiedenen erforderlichen Artefakte abzudecken (Entitätsklassen, Repositorys, Serviceklassen, asp.net-Steuerelemente, asp.net-Seiten usw.). Führen Sie den Generierungsprozess aus und formatieren Sie die Ausgabe.

Das Schreiben der Vorlagen ist mit einem gewissen Aufwand verbunden, kann jedoch für nachfolgende ähnliche Projekte wiederverwendet werden. In ähnlicher Weise werden Änderungen an den zugrunde liegenden Daten behandelt, indem die Metadaten geändert und die Generierung erneut ausgeführt werden, wodurch Änderungen einfacher und schneller zu implementieren sind.

Wie zum Testen. Da es sich um ein System mit Vorlagen handelt, müssen Sie einige Zeit damit verbringen, die Ausgabe des Prozesses zunächst zu überprüfen. Wenn Ihre Vorlage falsch ist, sind alle Ausgaben dieser Vorlage ähnlich falsch. Wenn Sie damit zufrieden sind, können Sie mit den Codegeneratoren auch grundlegende Tests aus den XML-Metadaten erstellen, die Sie dann auf Sonderfälle ausweiten können. Denken Sie jedoch daran, dass Sie möglicherweise noch Codetests durchführen müssen, um bestimmte Dinge zu berücksichtigen. Die Codegenerierung reduziert Ihre Arbeit und beseitigt sie nicht vollständig.

5
CdMnky

Sie fragen nach Beispielen ....

Wenn Sie mit SQL arbeiten, sollten Sie die Datenbank nicht direkt ändern, sondern Skripte ausführen, die alle gewünschten Änderungen vornehmen, einschließlich struktureller Änderungen an der Datenbank (Hinzufügen von Tabellen, Spalten, Primärschlüsseln, Einschränkungen usw.). . Sehr häufig müssen Sie dieselbe Aktion für viele Tabellen oder Spalten gleichzeitig ausführen, und es wäre mühsam, sie einzeln auszuführen. Ein kurzes Skript, das ein größeres Skript ausgibt, das das tut, was Sie wollen, kann real sein Zeitersparnis.

Bevor beispielsweise der Datentyp DATE in MS SQl Server eingeführt wurde, war die einzige Auswahl für eine Datumsspalte DATETIME, die einen Zeitteil enthält - einen Zeitteil, der den Umgang mit den Daten etwas erschwert. Nach dem Upgrade auf eine Version mit dem Datentyp Datum möchten Sie möglicherweise die Spalten aktualisieren, in denen die Uhrzeit immer 00:00 ist. In einer Datenbank mit Dutzenden oder sogar Hunderten von DateTime-Spalten wäre dies ziemlich zeitaufwändig. Es ist jedoch einfach, ein Skript zu schreiben, das alle Tabellen abfragt und jede Spalte mit dem Datentyp DATETIME überprüft, um festzustellen, ob die Zeit jemals etwas anderes als 00:00 ist, und wenn nicht, eine ALTER-Anweisung für die zu ändernde Tabelle/Spalte zu erstellen der Datentyp zu DATE. Presto, Code, der Code schreibt.

4
jmoreno

Während sich viele Antworten hier auf das beziehen, was allgemein als Metaprogrammierung bekannt ist, gab es tatsächlich ein Feld, das der KI zugeordnet war und als automatische Programmierung bekannt war und sich mit Programmen = befasste Verständnis oder Synthese Programme [1].

Jeder Compiler (oder Metaprogramm, Codegenerator, Übersetzer, Makrosystem, ...) arbeitet mit Transformationen und generiert eine Ausgabe aus einer Eingabe, indem er seinen festen Transformationsalgorithmus ausführt. Ein herkömmlicher Compiler oder ein Metaprogramm erstellt jedoch keinen Sortieralgorithmus, wenn eine Definition, Beschreibung oder ein Beispiel für die Sortierung einer Liste gegeben ist (z. B. [5, 3, 9] => [3,5,9]). Solche Probleme waren von Interesse für dieses Feld der "automatischen Programmierung".

[1] - Fortschrittsbericht über Programmverständnissysteme ftp://db.stanford.edu/pub/cstr/reports/cs/.../CS-TR-74-444.pdfShare

3
Thiago Silva

Ich habe ein PHP Modul, das eine Webseite mit JavaScript-Code ausgibt, der HTML generiert. Das sind genau dort drei Ebenen. Junge war so schwer zu lesen!

In einer Programmierklasse mussten wir ein Programm schreiben, das dem Benutzer eine Formelzeichenfolge entnahm, diese analysierte und den Wert anzeigte. Der beeindruckendste Löser nahm einfach die Benutzereingabe, packte sie in main () {printf ("% d", ...);} und führte ein Skript aus, um sie zu kompilieren, zu verknüpfen und auszuführen. Er hat keinen Parser geschrieben! Heute können Sie dies in einer SQL SELECT-Anweisung tun.

Es ist ein Werkzeug, mit dem Sie spielen und es dann für einen zukünftigen Tag aufbewahren sollten, an dem es nützlich sein wird.

3
Andy Canfield

Ich habe ordentliche Meta-Programmierung Lösungen mit Prolog entwickelt. Wobei die Hauptanwendung (z. B. in C++) zur Laufzeit eine abstrakte Definition eines Problems in eine Prolog-Anwendung übersetzt, an die dann delegiert wird. Oft würde das Schreiben gleichwertiger Funktionen in C++ ewig dauern.

Ich denke, dieses Szenario ist ein ausgezeichneter Fall für das Argument Code-Writing-Code.

3
user16410

Was denkst du über das Thema?

Metaprogrammierung wird am häufigsten mit nicht dynamischen Sprachen in Verbindung gebracht, da es schwieriger ist, bestimmte Verhaltensweisen (z. B. die Implementierung eines ORM) ohne viele unproduktive und nicht intelligente Codezeilen zu erreichen.

Aber auch in dynamischeren Sprachen wie PHP kann die Codegenerierung wirklich lebensrettend sein und die Produktivität enorm steigern. In modernen Frameworks ist es sehr üblich, ein Gerüst zu haben, das die meisten gängigen Modelle, Formen, Tests und Aktionen für ein bestimmtes Geschäftsobjekt generiert, das Sie deklarieren. Dies ist einer der Gründe, warum Frameworks wie Symfony oder RoR so erfolgreich sind, dass diese Tools zur Codegenerierung sehr schnell konsistenten Code erstellen und die Produktivität der Programmierer steigern.

Auf Websites dreht sich der größte Teil der Interaktion um vier Hauptaktionen:

  • Erstellen Sie ein Element
  • Abrufen einer Reihe von Elementen (mit möglicher Filterung)
  • Aktualisieren Sie ein Element mit neuen Attributen
  • Löschen Sie eine Reihe von Elementen

Zumindest alles, was sich um diese 4 Hauptaktionen dreht, könnte und sollte meiner Meinung nach mithilfe von Tools zur Codegenerierung erreicht werden, um maximale Produktivität zu erzielen.

In meinem Unternehmen verwenden wir Symfony, und sein Admin-Generator ist ein außergewöhnliches Tool, das sogar zur Laufzeit Code generiert (und zwischenspeichert), was bedeutet, dass wir nicht einmal irgendeine Aufgabe oder ein externes Tool verwenden müssen Wenn Sie neuen Code generieren, müssen Sie nur unseren Cache bereinigen. Ich rate dringend dazu, diese Art von Tool für CRUD-Operationen zu verwenden.

Aber es ist keine leichte Aufgabe, das zu tun, was großartige Mitwirkende von symfony getan haben. Ich habe selbst einige Aufgaben zur Codegenerierung implementiert, und es ist nicht einfach, etwas zu tun, das wirklich konsistent ist und eine umfassende Implementierung für die meisten Eckfälle bietet.

Steigert es wirklich Ihre Produktivität?

Ich glaube, dass Metaprogrammierung in niedrigeren Arbeitsebenen (Frameworks, Caching, Compiler usw.) sehr wichtig ist, aber etwas, das wir mit äußerster Vorsicht angehen müssen, wenn wir Dinge auf der Business-Ebene tun.

Die Verwendung der Codegenerierung ist ohne Frage ein wesentlicher Produktivitätssteigerer. Implementieren Sie Ihre eigenen Tools zur Codegenerierung, nicht so sehr, es sei denn, Sie erstellen selbst ein Framework.

Was sind einige gute Ressourcen zu diesem Thema, unter Büchern, Blogs, Diashows usw.?

Die beste Ressource zum Verständnis der Programmierung ist immer guter und gut kommentierter Quellcode. Ich würde sagen, dass es eine gute Idee ist, sich mit RubyOnRails und Symfony Admin-Generatoren zu befassen.

3
luisfaceira

Schauen Sie sich die CL-Makros (Common Lips) an. Meiner Meinung nach ist das genau das, was Sie wollen. Lippen sind perfekt in der Metaprogrammierung.

Außerdem schlage ich Nemerle vor, wenn Sie .NET-Funktionen mit perfekter Metaprogrammierungsunterstützung (einschließlich Makros) haben möchten.

Aber wenn Sie eine echte Code-Generierungs-Engine wollen, schauen Sie sich Apache Thrift an

3
cnd

Ich arbeite gerade an einem solchen Werkzeug. In unserem speziellen Fall generieren wir den VB.NET-Code basierend auf der Datenschicht basierend auf den Signaturen der Funktionen in der Datenbank.

Beginn der Arbeit Ein und mit der Codegenerierung ist zunächst schwierig, da Sie keine Ahnung haben, wie der Code generiert werden soll, aber sobald Sie einen festgelegten Satz von Regeln haben und der Code, der generiert werden muss, kann Immer basierend auf diesen Regeln generiert werden, ist die Arbeit mit diesem Code nicht so schwierig. Abhängig von der Komplexität der Codegenerierung und der Anzahl der Regeln kann die Aufgabe natürlich schwieriger werden. Im Wesentlichen wird die automatische Codegenerierung jedoch für sich wiederholende Codierungsaufgaben verwendet und nicht für erweiterten Code, der stark variiert.

Testen Die Ausgabe ist zweifach. Zuerst müssen Sie sicherstellen, dass der Code kompiliert wird, und das ist einfach. Dann müssen Sie sicherstellen, dass die Ausgabe das tut, was Sie beabsichtigt haben, basierend auf den Parametern, mit denen sie generiert wurde. Die Schwierigkeit hängt von der Komplexität des von Ihnen generierten Codes ab.

Meine aufrichtige Empfehlung lautet: wenn Sie das Gefühl haben, Code wiederholt zu schreiben, und Sie können sich die Zeit leisten. Versuchen Sie zu überlegen, ob das, was Sie tun, nicht durch generierten Code erledigt werden kann. Und wenn ja (wenn es sich um sich wiederholenden Code handelt, als dies fast immer der Fall ist), überlegen Sie, wie oft Sie ihn erweitern müssen, ändern Sie diesen Code leicht und wie oft müssen Sie genau diesen Code schreiben. Wenn die Antwort auf eine dieser Fragen "viele" lautet, dann Sie sollten ernsthaft in Betracht ziehen, einen Generator für diesen Code zu erstellen.

Ich hoffe, das hilft,
IPP

3
Ioan Paul Pirau

Die Meta-Programmierung kann sehr schwierig zu warten sein. Zuerst sieht es elegant aus, aber wenn Sie auf Eckfälle stoßen, werden die Fehler spät abgefangen (auf dem generierten Code), und das Ganze wird zu einem Albtraum, den Sie verwenden/debuggen müssen.

Ich habe hauptsächlich python Code) geschrieben, und meiner Erfahrung nach ist Meta-Programmierung mit dieser Sprache immer eine schlechte Wahl. Sie können immer Dinge umgestalten, um dies mit langweiligen normalen Sprachfunktionen zu tun. Das Ergebnis ist weniger funky , aber leichter zu leben.

2
Simon Bergot

Siehe Philip Greenspuns Problemsatz 4 aus MIT Kurs 6.916: Softwareentwicklung innovativer Webdienste ( http://philip.greenspun.com/teaching/psets/ps4/ps4.adp)) ).

Das Ziel lautet: "Bringen Sie den Schülern die Vorzüge von Metadaten bei. Insbesondere lernen sie, die Anforderungen eines Webdienstes formal darzustellen und anschließend ein Computerprogramm zu erstellen, um die Computerprogramme zu generieren, die diesen Dienst implementieren."

Dies ist eines der Probleme, die potenzielle ArsDigita-Rekruten ( http://en.wikipedia.org/wiki/ArsDigita ) während der ersten Blase lösen mussten.

Das Buch "SQL für Web-Nerds", auf das Philip im pset verweist, wurde nach ( http://philip.greenspun.com/sql/ ) verschoben.

2
espeed

OP fragt nach Ressourcen.

Vielleicht fanden Sie unser DMS Software Reengineering Toolkit interessant. Es ist ein reines Metaprogrammierwerkzeug, mit dem man benutzerdefinierte Programmanalyse- und Transformationswerkzeuge erstellen kann.

[Um einem Kommentar zu OPs Frage zu folgen, ist DMS beim Erstellen eines bestimmten Transformationstools eine Produktlinie, die Code schreibt, die Code schreibt:]

DMS erreicht dies, indem es agnostisch (aber nicht unabhängig) von Zielprogrammiersprachen ist. DMS bietet die Standarddienste, die für eine Vielzahl von Metaprogrammieraufgaben benötigt werden, ebenso wie ein Betriebssystem eine Vielzahl von Diensten für Standardprogrammieraufgaben bereitstellt. Diese Dienste umfassen starkes Parsen, automatisches Erstellen von Abstact-Syntaxbäumen, Mustervergleich und Umschreiben von Bäumen sowie Symboltabellenbibliotheken, mit denen Sprachen mit unangenehmen Gültigkeitsregeln wie Mehrfachvererbung, Kontrollfluss, Datenfluss, Point-to und Call einfach verwaltet werden können Graphanalyse. Nichts davon ist sinnvoll, wenn keine spezifischen Sprachen zu verarbeiten sind. Daher akzeptiert DMS Sprachdefinitionen, die an diese allgemeinen Maschinen gebunden sind, was zu sprachspezifischem Parsen führt. AST Konstruktion, Zielsprache-) spezifischer Mustervergleich/Umschreiben unter Verwendung der Zielsprachensyntax, zielsprachenspezifischer Analysatoren usw.

Und wie ein Betriebssystem ist DMS so konzipiert, dass es nur sehr wenige Meinungen oder Einschränkungen zu den (Meta-) Programmen hat, die Sie schreiben möchten. Dies bedeutet, dass es für eine Vielzahl von Zwecken verwendet werden kann: Extrahieren von Metriken, Auffinden von totem Code, Implementieren von Aspektwebern, Übersetzen Sprachen, Generieren von Codes aus DSLs, Neuarchitektur großer Anwendungen. (DMS wurde bereits für alle diese Aufgaben verwendet).

Man braucht robuste Sprachdefinitionen, wenn man nicht seine Zeit damit verbringen möchte, alles im Sprachhandbuch zu codieren (überlegen Sie, was dies für Java und C++) bedeutet. DMS löst dieses Problem, indem es a hat Bibliothek mit vollständigen Sprachdefinitionen verfügbar. Das Analoge hier ähnelt einer Datenbank, die für Ihr Betriebssystem verfügbar ist. Sie müssen keine davon implementieren, um mit dem Schreiben Ihrer datenbankzentrierten Anwendung fortzufahren.

2
Ira Baxter

In oder um 2001 begann ich an einem Projekt zu arbeiten, bei dem Geschäftsobjekte und Datenobjekte in großem Umfang verwendet wurden. Ich sollte die Front-End-Website erstellen, musste aber mit den Daumen drehen, weil die Geschäftsschicht und die Datenzugriffsschicht nicht vollständig entwickelt waren. Nach ein paar Wochen begann ich mir genau anzusehen, was diese Schichten taten. Im Grunde machten sie Daten, die von gespeicherten Prozeduren zurückgegeben wurden, als Sammlungen von Objekten mit Eigenschaften verfügbar, die den Feldern in den Daten entsprechen, oder nahmen Eingabeparameter und sendeten sie an gespeicherte Prozeduren, um sie in Datenbanktabellen zu speichern. Zwischen den beiden Ebenen fand eine Menge Serialisierung/Deserialisierung statt, es handelte sich um Microsoft Transaction Server, eine IDL/ODL-Typbibliothek ... aber alles passte zu einem Muster.

2 Wochen später ließ ich einen Codegenerator ausarbeiten, der IDL/ODL und auch die Geschäfts- und Datenobjekte auslagerte. Der Typ, der die Geschäfts- und Datenschichtobjekte erstellt hatte, hatte zwei Jahre gebraucht, um diese Objekte zu debuggen und zu testen. In 2 Wochen hatten wir mit der Codegenerierung die gleiche Ausgabe, aber da alles generiert wurde, war es ziemlich fehlerfrei.

Dieser Codegenerator (untergeordnetes CASE-Tool) hat mich 8 bis 10 Jahre lang durch viele verschiedene Iterationen begleitet, weil das Prinzip so einfach war: Sie tun etwas, das getan werden muss, wenn Sie mit Datenbanken sprechen, es ist hübsch viel repetitive Codierung, und sobald Sie es richtig gemacht haben, müssen Sie sich nicht mehr darum kümmern.

Also ja: Verwenden Sie einen Codegenerator, insbesondere wenn sich die Codierung wiederholt und zu einem genau definierten Muster passt.

Ich kenne Leute, die RegX-Makros verwenden, um ähnliche Dinge zu tun, oder Excel-Formeln, um ähnliche Dinge zu tun (ich mache das auch).

2

Ein Metaprogrammierungsbeispiel

Ich habe eine Ruby Autorisierungsbibliothek namens Authority . Sie ermöglicht Entwicklern, Fragen in ihrer App mit Methoden wie current_user.can_read?(@post) und @post.readable_by?(current_user) zu stellen. Diese Fragen werden von zentralisierten Autorisierungsklassen beantwortet.

Dies ist der entscheidende Teil: Die Behörde weiß nicht, welche Methoden definiert werden sollen, bis sie die Konfiguration des Benutzers sieht . Die Benutzerkonfiguration kann Folgendes enthalten:

config.abilities =  {
  ...
  :read      => 'readable',
  :microwave => 'microwavable',  # user-defined
  ...
}

In diesem Fall muss es eine Methode wie current_user.can_microwave?(@post) geben.

Die Metaprogrammierung macht dies möglich: Nachdem ich die Konfiguration gelesen habe, weiß ich welche Methoden zu definieren sind :

Authority.verbs.each do |verb|
  class_eval <<-Ruby, __FILE__, __LINE__ + 1 # allows for a Nice bracktrace
    def can_#{verb}?(resource)
      resource.#{Authority.abilities[verb]}_by?(self)
    end
  Ruby
end
2
Nathan Long