4 ms·
I think part of the problem is that Lisp is an incredibly broad language in terms of its capabilities. The macro system can be extremely powerful and when abus
by adwf 13y ago
I think part of the problem is that Lisp is an incredibly broad language in terms of its capabilities.
The macro system can be extremely powerful and when abused, is a nightmare to decipher. But. In the real world, I've rarely ever encountered someone who has actually programmed in such a bad style. A macro to me is almost no different than a function declaration (ie. (func arg1 arg2)), I just have to bear in mind whether it's being executed at compile or run time. Frequently I find a macro unnecessary and replace it with a straight function definition.
My golden rule is to avoid nesting macros in my own code (libraries are a different matter - wrap 'em in error handlers). If I stick to that, it becomes very simple and very powerful. It's not a very strict rule, but it is a helpful one as it reduces the general level of abstraction to a manageable level, while still being useful. Due to Lisp's flexibility, I think you have to maintain stricter coding standards than you perhaps would otherwise (but also know when to break them). If you create the right macros, you can save hundreds of lines of code and make the codebase far more maintainable.
A good example I had recently was for a website; I had a template macro for all the <doctype>/<head>/css/js and had the navbar, footer, general layout in the template as well. Then I had each webpage defined as a function that called the template macro and then inserted the rest of the <body> into the page. (This saved a ton of code in terms of templating; it could probably be done in other languages too, but you'd have to squeeze it into OO format or something)
This was all well and good, I had about 20 pages done before I ran into a bug. In some other languages, you would then go round adding a debug line/condition handler to every function, but instead I added it to the main template macro just once and it handled all the functions. Even better, the macro system and condition handler allowed me to deal with the code both before and after it had been compiled. I then passed the error up the stack from the function to the macro's handler, had the handler choose a fix (recompile the page function with different params), then send it back to the function (without ever exiting the stack) and carry on as if nothing happened. The users see nothing.
I don't use a lot of the things Lisp can do (eg. I can't remember the last time I made a function generate another function and return it), but it works exceptionally well for what I do use (currying, composing, macros and more).