Meta-Programmierung
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Meta-Programmierung
interessiert sich hier jemand für reine metaprogrammierung?
gruß bergmon
gruß bergmon
Re: Meta-Programmierung
Ich kann mir nicht wirklich vorstellen, wie Metaprogrammierung funktioniert...
-
- Establishment
- Beiträge: 191
- Registriert: 01.03.2009, 19:22
- Echter Name: David N.
Re: Meta-Programmierung
Was ist »reine Metaprogammierung«? Du schreibst nur Code, der anderen Code generiert, der anderen Code generiert, der anderen … ;)
- Schrompf
- Moderator
- Beiträge: 5156
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Meta-Programmierung
Ich habe vor kurzem auf GameDev.net von einem Raytracer gelesen, der komplett in C++-Templates geschrieben war und sein Ergebnis zur Compile Time ausgegeben hat... das ist so ziemlich das meta-iste, was ich mir vorstellen kann :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
-
- Establishment
- Beiträge: 191
- Registriert: 01.03.2009, 19:22
- Echter Name: David N.
Re: Meta-Programmierung
So etwas gibts auch in D: http://h3.team0xf.com/ctrace/. Der Typ macht im Graphikbereich so ziemlich alles, nur keine normalen Sachen… ;)Schrompf hat geschrieben:Ich habe vor kurzem auf GameDev.net von einem Raytracer gelesen, der komplett in C++-Templates geschrieben war und sein Ergebnis zur Compile Time ausgegeben hat... das ist so ziemlich das meta-iste, was ich mir vorstellen kann :-)
Re: Meta-Programmierung
@zudomon:
also im falle von c++ besteht dein programmgerüst ja aus funktionen und klassen-definitionen welche durch eine weitere art zu parametrisieren beschrieben werden können - das ist die template-parametrisierung. diese wird zur kompilierzeit dynamisch aufgelöst(genauso wie vererbungen), welche dann zur laufzeit ein statisches resultat liefert.
ein einafches beispiel, ist zum beispiel das exponieren a^b mit a,b€Z:
<--alles grün :lol: ?
wenn ich micht nicht irre, verhält sich bei c++ die template-parametrisierung wie eine funktionale programmiersprache.
@klickverbot:
ja, das sieht einfach ziemlich gut aus, was es dort zu sehen gibt. :) ich glaub, ich muss mir auch mal wieder D anschauen. anscheinend unterstützt der compiler mitlerweile echtzeit-rekompilierung - hab ich mal aus einem kommentar von der seite entnommen.
so ein raytracer ist schon ne lustige sache, ich glaub ich bekomm gerade mal ne kugel gezeichnet - ohne raytracing...
kennt vielleicht zufällig jemand einen kompilierzeit-zugriff auf eine dynamische zahl? dann könnte man sich mit jeder kompilierung ein neues programm generieren. ich glaub mich gerade an einen timestamp erinnern zu können...gleich mal nachschau geh.
also im falle von c++ besteht dein programmgerüst ja aus funktionen und klassen-definitionen welche durch eine weitere art zu parametrisieren beschrieben werden können - das ist die template-parametrisierung. diese wird zur kompilierzeit dynamisch aufgelöst(genauso wie vererbungen), welche dann zur laufzeit ein statisches resultat liefert.
ein einafches beispiel, ist zum beispiel das exponieren a^b mit a,b€Z:
Code: Alles auswählen
template <int a, int b>
class exp
{
public:
enum{_r = a * exp<a, b-1>::_r};
};
template <int a>
class exp<a, 0>
{
public:
enum{_r = 1};
};
wenn ich micht nicht irre, verhält sich bei c++ die template-parametrisierung wie eine funktionale programmiersprache.
@klickverbot:
ja, das sieht einfach ziemlich gut aus, was es dort zu sehen gibt. :) ich glaub, ich muss mir auch mal wieder D anschauen. anscheinend unterstützt der compiler mitlerweile echtzeit-rekompilierung - hab ich mal aus einem kommentar von der seite entnommen.
so ein raytracer ist schon ne lustige sache, ich glaub ich bekomm gerade mal ne kugel gezeichnet - ohne raytracing...
kennt vielleicht zufällig jemand einen kompilierzeit-zugriff auf eine dynamische zahl? dann könnte man sich mit jeder kompilierung ein neues programm generieren. ich glaub mich gerade an einen timestamp erinnern zu können...gleich mal nachschau geh.
Re: Meta-Programmierung
ja ne, geht nicht, dass ich wüsste. braucht "compile-time constant expression", es geht ja nicht mal das:
wenn man c global definiert kommt:
"an expression involving objects with internal linkage cannot be used as a non-type argument"
heißt also, dass der compiler sich zu sehr "verbiegen" müsste um es aufzulösen. mit dem neuen c++-standard geht es dann wohl, und mit D sowieso.
Code: Alles auswählen
template <char T> class C{};
const char c[] = {'a', 'b'};
C<c[0]> _c //gibt den fehler, obwohl der compiler es durch substitution auflösen könnte
"an expression involving objects with internal linkage cannot be used as a non-type argument"
heißt also, dass der compiler sich zu sehr "verbiegen" müsste um es aufzulösen. mit dem neuen c++-standard geht es dann wohl, und mit D sowieso.
Re: Meta-Programmierung
Hmmm... und was bringt das ganze letztendlich? Was kann man tun, was man nicht auch so programmieren könnte? Oder ist das garnicht das Ziel, etwas zu machen, was man nicht auch anders lösen könnte?
- dv
- Beiträge: 51
- Registriert: 15.09.2002, 17:46
- Benutzertext: Ugauga.
- Alter Benutzername: dv
- Wohnort: Südamerikanischer Dschungel
- Kontaktdaten:
Re: Meta-Programmierung
Konkreten Einsatz findet Metaprogrammierung z.B. in Fällen, in denen man Code nur bedingt "einschalten" will. Beispiel:
Das erste foo wird nur dann angedreht, wenn T ein Skalar ist. (Das zweite wird dann abgedreht.)
Andere Einsatzgebiete sind zB das Zusammenstoppeln von Datentypen. Ein praktisches Beispiel sind Vertexaccessors. Du gibst das Vertexformat als Compile-Time-Sequenz an (zB ein MPL-Vector), und mittels Metaprogrammierung entsteht daraus ein Datentyp, mit dem du typsicher auf die Inhalte der Vertices zugreifen kannst (anstatt andauernd unsichere Casts auf void-Pointer zu machen).
Ein weiteres Beispiel sind Expression Templates, die mittels Metaprogrammierung einen algebraischen Ausdruck automatisiert aufrollen. Z.B. new_pos = old_pos + delta * time_diff; hat dann keine temporären Werte, sondern ist nur eine einzige ausgerollte Berechnung. Das kann erhebliche Performancevorteile liefern, ohne dass man diesen Ausdruck optimieren muss bis er unkenntlich wird. Basierend auf Expression Templates habe ich schon Code gesehen, der sehr komplexe Ausdrücke evaluiert, und zwar so performant, da kommt man auch mit hardcore C nicht so leicht ran.
Noch ein Beispiel sind Fälle, in denen du für N Typen code generieren willst. Ich hab zB einen Fall gehabt, bei dem ich pro Datentyp eine Qt-Editor-UI erstellen musste. Anstatt jetzt manuell N mal ein Template zu instantiieren, habe ich mir einen MPL-Vector erstellt, mit allen Typen die ich brauche, und für jedes das Template dann instantiiert. Mittels Templatespezialisierung hatte ich einen generischen Editor für Typen, die zu einem String konvertierbar sind, und für einige andere Datentypen hatte ich spezielle Editoren (z.B. Farbauswahls-GUI für RGB-Tripel, Zeileneingabe mit Pfeilen rechts für double ...) Somit reduzierte sich der Codeaufwand auf ein Minimum.
Richtig wild wird es mit Sachen wie DSEL's, aber das ist schon sehr weit weg. Der Spirit-Parser ist auch noch ein Beispiel, genauso wie Boost.Lambda und Boost.Fusion, Phoenix 2 ...
Code: Alles auswählen
template < typename T >
void foo(T const &t, boost::enable_if < boost::is_scalar < T > > ::type *dummy = 0)
{
..
}
template < typename T >
void foo(T const &t, boost::disable_if < boost::is_scalar < T > > ::type *dummy = 0)
{
..
}
Andere Einsatzgebiete sind zB das Zusammenstoppeln von Datentypen. Ein praktisches Beispiel sind Vertexaccessors. Du gibst das Vertexformat als Compile-Time-Sequenz an (zB ein MPL-Vector), und mittels Metaprogrammierung entsteht daraus ein Datentyp, mit dem du typsicher auf die Inhalte der Vertices zugreifen kannst (anstatt andauernd unsichere Casts auf void-Pointer zu machen).
Ein weiteres Beispiel sind Expression Templates, die mittels Metaprogrammierung einen algebraischen Ausdruck automatisiert aufrollen. Z.B. new_pos = old_pos + delta * time_diff; hat dann keine temporären Werte, sondern ist nur eine einzige ausgerollte Berechnung. Das kann erhebliche Performancevorteile liefern, ohne dass man diesen Ausdruck optimieren muss bis er unkenntlich wird. Basierend auf Expression Templates habe ich schon Code gesehen, der sehr komplexe Ausdrücke evaluiert, und zwar so performant, da kommt man auch mit hardcore C nicht so leicht ran.
Noch ein Beispiel sind Fälle, in denen du für N Typen code generieren willst. Ich hab zB einen Fall gehabt, bei dem ich pro Datentyp eine Qt-Editor-UI erstellen musste. Anstatt jetzt manuell N mal ein Template zu instantiieren, habe ich mir einen MPL-Vector erstellt, mit allen Typen die ich brauche, und für jedes das Template dann instantiiert. Mittels Templatespezialisierung hatte ich einen generischen Editor für Typen, die zu einem String konvertierbar sind, und für einige andere Datentypen hatte ich spezielle Editoren (z.B. Farbauswahls-GUI für RGB-Tripel, Zeileneingabe mit Pfeilen rechts für double ...) Somit reduzierte sich der Codeaufwand auf ein Minimum.
Richtig wild wird es mit Sachen wie DSEL's, aber das ist schon sehr weit weg. Der Spirit-Parser ist auch noch ein Beispiel, genauso wie Boost.Lambda und Boost.Fusion, Phoenix 2 ...
Re: Meta-Programmierung
Das klingt alles nach Teufelszeug... ;)
-
- Establishment
- Beiträge: 191
- Registriert: 01.03.2009, 19:22
- Echter Name: David N.
Re: Meta-Programmierung
Der Compiler unterstützt Echtzeit-Rekompilierung im direkten Sinne nicht, aber es hält dich nichts davon ab, den Compiler aus deinem Programm heraus aufzurufen und das Kompilat zu laden. Das ganze gibts auch schon nett verpackt (siehe etwa den zweiten Teil von http://petermodzelewski.blogspot.com/20 ... -talk.html), diese Library (DDL) unterstützt aber im Moment nur Windows, wenn ich mich richtig erinnere. D ist mittlerweile wirklich benutzbar, die Toolchain ist aber nach wie vor nicht unbedingt einsteigerfreundlich. Bei Problemen zahlt sich ein kurzer Besuch in #d auf freenode meistens aus.Bergmon hat geschrieben:@klickverbot:
ja, das sieht einfach ziemlich gut aus, was es dort zu sehen gibt. :) ich glaub, ich muss mir auch mal wieder D anschauen. anscheinend unterstützt der compiler mitlerweile echtzeit-rekompilierung - hab ich mal aus einem kommentar von der seite entnommen.
Re: Meta-Programmierung
ja, das was dort gemeint war, war nur die dmd-skriptsprache, wobei die ganz flott sein soll...
echtzeit-kompilierung gibt es ja auch in der java vm, oder? stell mir das als eine art skript- zu byte-code streaming vor.
echtzeit-kompilierung gibt es ja auch in der java vm, oder? stell mir das als eine art skript- zu byte-code streaming vor.
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Meta-Programmierung
Echtzeitkompilierung gibt es auch in C++, der Trick beruht darauf einen Compiler mitzuliefern und den erzeugten Code dynamisch zu laden :-) Zugegebenermaßen sind für solche Tricks interpretierte Sprachen wie Java, D oder Python deutlich besser geeignet ...echtzeit-kompilierung gibt es ja auch in der java vm
Re: Meta-Programmierung
@Echtzeitkompilierung
Möchte da einmal das Turbo Delphi loben! Das normale kompilieren ist so schnell, dass ich das benutze um durch den Code zu navigieren. Es ist sogar schneller, wenn man mal woanders hin schrollen muss und die Stelle nicht verlieren möchte, da einfach ein Buchstabe reinzutippen, zu scrollen und dann kompilieren, um an die Stelle zurückzukommen, wo der Fehler auftaucht. Das ist schneller, als eine Quellcodemarkierung zu setzen.
Falls es mal sein muss, den kompletten Code zu kompilieren, also ohne auf das fertige Kompilat zurückzugreifen, dann dauert es je nachdem, ob Warnungen vorhanden sind oder nicht im ersten Fall knapp eine Sekunde, ansonsten bis zu 4 oder 5.
Möchte da einmal das Turbo Delphi loben! Das normale kompilieren ist so schnell, dass ich das benutze um durch den Code zu navigieren. Es ist sogar schneller, wenn man mal woanders hin schrollen muss und die Stelle nicht verlieren möchte, da einfach ein Buchstabe reinzutippen, zu scrollen und dann kompilieren, um an die Stelle zurückzukommen, wo der Fehler auftaucht. Das ist schneller, als eine Quellcodemarkierung zu setzen.
Falls es mal sein muss, den kompletten Code zu kompilieren, also ohne auf das fertige Kompilat zurückzugreifen, dann dauert es je nachdem, ob Warnungen vorhanden sind oder nicht im ersten Fall knapp eine Sekunde, ansonsten bis zu 4 oder 5.
-
- Establishment
- Beiträge: 191
- Registriert: 01.03.2009, 19:22
- Echter Name: David N.
Re: Meta-Programmierung
Meinst du auf der Website von h3r3tic? Wäre mir nicht aufgefallen…ja, das was dort gemeint war, war nur die dmd-skriptsprache, wobei die ganz flott sein soll...
Re: Meta-Programmierung
da hab ich mich verguckt. bei den ganzen abkürzungen bin ich dann irgendwie bei dmdscript gelandet und dachte das hätten die benutzt. :)klickverbot hat geschrieben:Meinst du auf der Website von h3r3tic? Wäre mir nicht aufgefallen…ja, das was dort gemeint war, war nur die dmd-skriptsprache, wobei die ganz flott sein soll...
ist D wirklich eine 100%ige skriptsprache? dann ist dmdscript eine geskriptete skriptsprache, toll oder?Aramis hat geschrieben:... Zugegebenermaßen sind für solche Tricks interpretierte Sprachen wie Java, D oder Python deutlich besser geeignet ...echtzeit-kompilierung gibt es ja auch in der java vm
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Meta-Programmierung
Ähm, negativ, D ist natürlich nicht interpretiert. Mein Fehler.
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Meta-Programmierung
Wirklich gute Metaprogrammierung soll wohl mit Dylan möglich sein. ich habe damit aber persönlich keine Erfahrung. Dazu ist der Anwenderkreis von Dylan meines Wissens nach recht überschaubar. Wer es etwas härter mag, kann sich ja auch mal Lisp anschauen ( der Emacs hat einen integrierten Lisp-Interpreter, so zum Üben ). Dafür sollte man aber Klammern mögen.
Ansonsten rate ich auch zu C++ bzw. D.
Gruß Kimmi
Ansonsten rate ich auch zu C++ bzw. D.
Gruß Kimmi
Re: Meta-Programmierung
der meinung bin ich im moment auch. was d betrifft...hat da jemand schon mal ein kleines projekt erstellt? nach dem was es hier: http://h3.team0xf.com/devlog/ zu lesen gibt, scheint d noch etwas in den kinderschuhen zu stecken - wenn ich da schon wieder an auftretende random-bugs denke...ohoh.kimmi hat geschrieben: Ansonsten rate ich auch zu C++ bzw. D.
mal eine kleine frage:
wenn mein leeres element mit
Code: Alles auswählen
nilT
Code: Alles auswählen
template<typename H, typename T>
class L
Code: Alles auswählen
L<nilT, nilT>
ist dann eine gültige listen-definition, welche nur einen int-typ enthält:
a)
Code: Alles auswählen
L<int, nilT>
b)
Code: Alles auswählen
L<int, L<nilT, nilT>>
gruß bergmon
- dv
- Beiträge: 51
- Registriert: 15.09.2002, 17:46
- Benutzertext: Ugauga.
- Alter Benutzername: dv
- Wohnort: Südamerikanischer Dschungel
- Kontaktdaten:
Re: Meta-Programmierung
Ich würde L<int, nilT> nehmen. Der erste typename ist somit entweder ein Typ, oder nilT. Der zweite ist entweder ein Typ, nilT, oder ein weiteres L.
I.A. würde ich aber bei Dingen wie diesen boost.mpl oder boost.fusion nehmen.
I.A. würde ich aber bei Dingen wie diesen boost.mpl oder boost.fusion nehmen.
Re: Meta-Programmierung
geht man allerdings von der struktur einer liste mit List=(Head, Tail) wobei Tail wieder eine liste ist, dann muss es b.) sein.dv hat geschrieben:Ich würde L<int, nilT> nehmen. Der erste typename ist somit entweder ein Typ, oder nilT. Der zweite ist entweder ein Typ, nilT, oder ein weiteres L.
alternativ kann man sich auch überlegen, wie eine liste aussehen muss, wenn ich ein nilT-element speichern möchte, dann muss es auch b) sein, da es sonst nicht mehr unterscheidbar von der leeren liste ist. keine ahnung wie es boost implementiert, bei loki ist es nicht korrekt.