I agree that they are important in a full Common Lisp, but I’m not convinced they are necessary for the applications that uLisp is targeted at. Can you give some examples of applications that you need macros for?
I believe macros are essential to be able to clearly and concisely formulate good programs, no matter what the application is. I don’t think the size or type of application makes any difference to this. Macros allow you to create your own “syntactical sugar” and create things like custom with-* blocks, or implement doarray similar to dolist and all sorts of things you just can’t do with plain functions. Sure, you can implement the functionality of doarray as a function, but you can’t make the resulting function take the arguments in the same way as dolist without it being a macro, so the code would be uglier and less readable without macros, and it could not be implemented in a consistent way.
It would also improve interop of Common Lisp code in uLisp. Since uLisp is mostly a compatible subset of Common Lisp a lot of code can already be reused directly from CL. Adding macros would increase the amount of code reuse/interop that is possible. Not only directly from supporting defmacro and allowing to reuse existing CL code that uses macros, but it would also make it possible to use macros to quickly implement CL language features that are missing from uLisp in order to use CL code that depends on some missing language features.
I think that you are either underestimating what people are using uLisp for, or not really understanding the power of macros. Any program that is not simply a blinking LED “hello world” example is sufficiently advanced that it could potentially benefit from macros, so I do not agree at all that macros are not necessary for the type of applications uLisp is targeted at. Also, this type of reasoning becomes self-fulfilling, since the type of applications people are using uLisp for might be limited by missing features such as macros and interrupts, not the other way around.
I think that macros (and quasiquote and unquote) are possibly the biggest bang-for-the-buck addition to uLisp currently. It requires very little effort from your part to add one of the existing implementations to the language, but it gives a very big improvement to the power and expressiveness of the language. I don’t see any downsides or reasons why it shouldn’t be included.
I don’t see how this would work. I’m assuming from what you said (“not just the polling variant you suggested”) you want an interrupt to be able to run Lisp code, or even a Lisp function. This implies that eval has to be reentrant, and I’m not sure how that would be possible.
I don’t know too much about threads and thread safety, and I’m not familiar with how things are implemented in uLisp so I might be missing something obvious here. Could you explain what you mean by “eval has to be reentrant”?