Seite 1 von 1

Meta-Programmierung

Verfasst: 30.07.2009, 13:54
von Bergmon
interessiert sich hier jemand für reine metaprogrammierung?
gruß bergmon

Re: Meta-Programmierung

Verfasst: 30.07.2009, 14:52
von Zudomon
Ich kann mir nicht wirklich vorstellen, wie Metaprogrammierung funktioniert...

Re: Meta-Programmierung

Verfasst: 30.07.2009, 15:00
von klickverbot
Was ist »reine Metaprogammierung«? Du schreibst nur Code, der anderen Code generiert, der anderen Code generiert, der anderen … ;)

Re: Meta-Programmierung

Verfasst: 30.07.2009, 15:39
von Schrompf
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

Verfasst: 30.07.2009, 15:43
von klickverbot
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 :-)
So etwas gibts auch in D: http://h3.team0xf.com/ctrace/. Der Typ macht im Graphikbereich so ziemlich alles, nur keine normalen Sachen… ;)

Re: Meta-Programmierung

Verfasst: 30.07.2009, 17:27
von Bergmon
@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:

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};
};
<--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.

Re: Meta-Programmierung

Verfasst: 30.07.2009, 17:49
von Bergmon
ja ne, geht nicht, dass ich wüsste. braucht "compile-time constant expression", es geht ja nicht mal das:

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
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.

Re: Meta-Programmierung

Verfasst: 30.07.2009, 18:21
von Zudomon
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?

Re: Meta-Programmierung

Verfasst: 30.07.2009, 18:37
von dv
Konkreten Einsatz findet Metaprogrammierung z.B. in Fällen, in denen man Code nur bedingt "einschalten" will. Beispiel:

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)
{
  ..
}
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 ...

Re: Meta-Programmierung

Verfasst: 30.07.2009, 18:55
von Zudomon
Das klingt alles nach Teufelszeug... ;)

Re: Meta-Programmierung

Verfasst: 30.07.2009, 19:30
von klickverbot
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.
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.

Re: Meta-Programmierung

Verfasst: 30.07.2009, 21:47
von Bergmon
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.

Re: Meta-Programmierung

Verfasst: 30.07.2009, 22:21
von Aramis
echtzeit-kompilierung gibt es ja auch in der java vm
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 ...

Re: Meta-Programmierung

Verfasst: 30.07.2009, 23:01
von Zudomon
@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.

Re: Meta-Programmierung

Verfasst: 30.07.2009, 23:14
von klickverbot
ja, das was dort gemeint war, war nur die dmd-skriptsprache, wobei die ganz flott sein soll...
Meinst du auf der Website von h3r3tic? Wäre mir nicht aufgefallen…

Re: Meta-Programmierung

Verfasst: 30.07.2009, 23:50
von Bergmon
klickverbot hat geschrieben:
ja, das was dort gemeint war, war nur die dmd-skriptsprache, wobei die ganz flott sein soll...
Meinst du auf der Website von h3r3tic? Wäre mir nicht aufgefallen…
da hab ich mich verguckt. bei den ganzen abkürzungen bin ich dann irgendwie bei dmdscript gelandet und dachte das hätten die benutzt. :)
Aramis hat geschrieben:
echtzeit-kompilierung gibt es ja auch in der java vm
... Zugegebenermaßen sind für solche Tricks interpretierte Sprachen wie Java, D oder Python deutlich besser geeignet ...
ist D wirklich eine 100%ige skriptsprache? dann ist dmdscript eine geskriptete skriptsprache, toll oder?

Re: Meta-Programmierung

Verfasst: 31.07.2009, 00:29
von Aramis
Ähm, negativ, D ist natürlich nicht interpretiert. Mein Fehler.

Re: Meta-Programmierung

Verfasst: 31.07.2009, 10:57
von kimmi
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

Re: Meta-Programmierung

Verfasst: 02.08.2009, 20:44
von Bergmon
kimmi hat geschrieben: Ansonsten rate ich auch zu C++ bzw. D.
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.

mal eine kleine frage:

wenn mein leeres element mit bezeichnet wird und meine liste von der form:

Code: Alles auswählen

template<typename H, typename T>
class L
ist, dann bezeichnet

Code: Alles auswählen

L<nilT, nilT>
meine leere liste.
ist dann eine gültige listen-definition, welche nur einen int-typ enthält:
a)

Code: Alles auswählen

L<int, nilT>
oder
b)

Code: Alles auswählen

L<int, L<nilT, nilT>>
?

gruß bergmon

Re: Meta-Programmierung

Verfasst: 02.08.2009, 21:45
von dv
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.

Re: Meta-Programmierung

Verfasst: 04.08.2009, 18:30
von Bergmon
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.
geht man allerdings von der struktur einer liste mit List=(Head, Tail) wobei Tail wieder eine liste ist, dann muss es b.) sein.
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.