Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The first part of this is not true.

You can execute arbitrary code at macro-expansion time.

You can also recompile while the process is running, which would include re-macroexpanding.



I think you misunderstood what I'm saying. Typically, the macroexpansion is a compile time process that uses different machine resources than the runtime processes of the same language.


Not in a lisp it isn't, compiling very often happens at runtime, in which case you're compiling in the same process as the code that is running at that time, in which case the same resources are available to both.

This is how you get a REPL and other forms of runtime evaluation.

This is kind of the nub of being a dynamic programming language, if it can't do this, it isn't a dynamic programming language. Lisps are generally dynamic programming languages.

Clojure-script might be an exception because of how it is implemented, but Clojure proper on the JVM certainly supports this type of behavior.


There must be a setting in regular Clojure on the JVM for controlling how much recursion or memory usage is available during macro expansion, because I've hit that limit very easily in the past. It's been about a year since I used Clojure much, but I doubt that's changed.


That makes more sense. It's possible that this is a design decision by Rich Hickey, I'm not aware of the intricacies of how the Clojure macro-expansion works. However, that sounds a lot like you hit a bug in the Clojure compiler (or in general needed to beef up the allowed memory of the JVM it was running on, compilation obviously isn't cheap... everything should all be in the same resident memory).

I would expect to be able to do (eval `(defun ,function_name () (complicated_macro ,@args))) or (compile `(defun ,function_name () (complicated_macro ,@args)))) at runtime in Common Lisp, without even really considering the consequences beyond whether it is necessary.

It's supposed to work a little bit like if you had an implementation of GCC in the same process as your C program, and you could call GCC from a function to compile some new C code for you to add features or replace existing code. It's powerful + dangerous.


In my case, it was definitely a problem of resource limits during compilation only, since the same logic would work fine if not a macro and run at runtime, so not a general case of the JVM not setup to handle the work, but specifically macros not able to handle the work.

C++ obviously has a limit on template depths as well, but they are so high that rarely does anyone get close to the defaults. Clojure probably has very limited defaults (assuming that defaults are the cause).




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: