Open luontola opened 6 months ago
Macros are evaluated from the outside in, so we could certainly look through the syntax tree and do something to reduce the nesting. There may also be a better solution to the problem, but keeping the API backward compatible ties our hands somewhat.
If html
receives an options map with :mode
and :escape-strings?
, will it then generate only one code variant? Could then the outermost html
insert matching options maps to the nested html
forms?
Alternatively, create a new internal function similar to compile-html-with-bindings
, but for generating only one code variant, and replace the nested html
forms with that.
Wouldn't it be helpful to be able to optionally disable all the preprocessing at compile time and do everything at runtime? Then the evaluation happens inside-out, and everything becomes easier. If someone has code like in this issue, he may not want an optimisation at compile time.
I think ideally I want to separate out compilation entirely, but that will require some consideration and probably a hiccup3
namespace.
This is similar to https://github.com/weavejester/hiccup/issues/205 but less common. Consider the following code:
In the generated code, foo will appear 8 times, bar 64 times, and gazonk 512 times.
If you try to evaluate this code normally (i.e. without macroexpand-all), it will throw "IndexOutOfBoundsException: Method code too large!"
Each level of nesting multiplies the code by 8, because every
h/html
checkshiccup.util/*html-mode*
andhiccup.util/*escape-strings?*
again and generates the 8 code paths.Is there a way for a Clojure macro to recognize that it's nested within itself? Then those 8 code paths could be generated at only the outermost
h/html
, and the inner macros could use the same html and escape mode as the outermost macro.Hiccup version 2.0.0-RC3
Workaround
Extract the inner
html
macro call to a function, so that you won't have many nestedhtml
macros.