Peinlicherweise habe ich Probleme, dieses Makro richtig zu entwerfen.
Dies ist das Makro, wie ich es geschrieben habe:
%Vor% Es muss zwei Sammlungen oder Seqs aufnehmen, xs
und ys
, und ich brauche es, um mir zu geben ...
... für xs
= [0 1 3 5 7]
und ys
= [1 1 3 6 8]
.
Das funktioniert gut, wenn ich meinem Macro 'n' einfache Vektoren (zB [1 2 3 4]
und [2 3 4 5]
) gebe, aber nicht funktioniert, wenn ich es einem lazy-seq gebe / irgendetwas, das wie% ausgewertet werden muss co_de% und (take 16 (iterate #(+ 0.1 %1) 0))
.
Mir ist klar, dass dies daran liegt, dass diese Werte nicht bewertet werden, und so bekomme ich zum Beispiel (take 16 (cycle [0 -0.1 0 0.1]))))
als mein erstes Ergebnis (glaube ich). Leider hat alles, was ich versucht habe, diese zuerst zu bewerten und dann mein Makro-Neuschreiben durchzuführen, gescheitert / schrecklich hacky ausgesehen.
Ich bin mir sicher, dass ich hier ein paar grundlegende Syntax-Anführungszeichen vermisse - ich würde etwas Hilfe / Hinweise lieben!
Vielen Dank.
BEARBEITEN Ich sollte erwähnen, (vertex take take)
ist ein Makro, und draw-line-strip
erzeugt einen OpenGL-Vertex; Sie sind beide Teil der Penumbra Clojure + OpenGL-Bibliothek .
BEARBEITEN 2 Dies ist für ein benutzerdefiniertes Grafikwerkzeug, das ich brauche, und die Hauptmotivation für die Erstellung war, schneller zu sein als JFreeCharts und die Firma.
EDIT 3 Ich nehme an, ich sollte beachten, dass ich eine Makro-Version funktioniere, es ist einfach schrecklich und hacky, wie ich oben erwähnt habe. Es verwendet vertex
, wie unten gezeigt, aber wie folgt:
Leider bekomme ich ...
eval
... wenn Sie dies mit ein paar langen Listen mit mehreren tausend Elementen verwenden. Dies liegt daran, dass ich viel zu viel in den vorkompilierten Code schreibe, und die Klassendatei kann (so wie ich denke) nicht so viele Daten / Codes verarbeiten. Es sieht so aus, als müsste ich irgendwie eine Funktionsversion von error: java.lang.ClassFormatError: Invalid this class index 3171 in constant pool in class file tl/core$draw_l$fn__9357 (core.clj:14)
erhalten, wie es vorgeschlagen wurde.
Ich bin jedoch immer noch offen für eine elegantere, weniger hackische Makro-Lösung für dieses Problem. Wenn einer existiert!
Warum nicht so etwas, mit Funktion statt Makro:
%Vor%Das sollte einen Draw-Line-Strip mit den benötigten Args aufrufen. Dieses Beispiel eignet sich nicht für Makros, die nicht für Funktionen verwendet werden sollten.
Hinweis: Ich habe es nicht versucht, da ich keinen Schleim auf dieser Box eingerichtet habe.
BEARBEITEN: Wenn ich nochmal schaue, weiß ich nicht, ob Sie den Scheitelpunkt vor dem Aufruf von Draw-Line-Strip auswerten wollen. In diesem Fall sieht die Funktion folgendermaßen aus:
%Vor% Wenn Sie draw-line-strip
wirklich zu einem Makro und benötigen, wollen Sie eine völlig allgemeine Methode, um das zu tun, was der Fragetext beschreibt und , ist Ihnen egal Über einen kleinen Performance-Hit könntest du eval
:
Beachten Sie, dass dies ein schrecklicher Stil ist, es sei denn, es ist wirklich notwendig.
Das sieht wie ein typisches Problem mit einigen der Makrosysteme in Lisp aus. Es gilt die übliche Lisp-Literatur. Zum Beispiel On Lisp von Paul Graham (verwendet Common Lisp).
Normalerweise verwendet ein Makro die umschlossene Quelle und erzeugt eine neue Quelle. Wenn ein Makroaufruf (foo bar) ist und das Makro basierend auf dem Wert von bar etwas anderes erzeugen soll, ist dies im Allgemeinen nicht möglich, da der Wert von bar im Allgemeinen für den Compiler nicht verfügbar ist. BAR hat zur Laufzeit nur einen Wert, nicht wenn der Compiler die Makros erweitert. Man müsste also zur Laufzeit den richtigen Code generieren - was zwar möglich ist, aber meist als schlechter Stil angesehen wird.
In diesen Makrosystemen können Makros nicht angewendet werden. Eine typische Lösung sieht so aus (Common Lisp):
%Vor%Es ist jedoch nicht immer möglich, obige Lösung zu verwenden. Zum Beispiel wenn die Anzahl der Argumente variiert.
Es ist auch keine gute Idee, dass DRAW-LINE-STRIP ein Makro ist. Es sollte besser als eine Funktion geschrieben werden.