Lisp leaves most things up to the programmer's taste.
I don't entirely disagree, but I think there's more to it than that. While the language certainly does offer some free choices, more often there are advantages and disadvantages to each, so that in any particular situation, some choices are better than others. Becoming an expert Lisp programmer requires learning about these tradeoffs, which takes experience and, usually, guidance from existing experts.
That's true of any language, of course, but some of the facilities Lisp offers are rare among other languages, so that people coming to Lisp from some other language are unlikely to have experience with them.
Oh, one point about macros in particular. If you have to resort to reading the implementation of a macro to understand what it does, the person who wrote it screwed up. Macros should always have documentation strings explaning their syntax and semantics. If you find yourself in that situation, the best thing to do is to go to the REPL and use `macroexpand' interactively to see the expansions of the macro calls you're interested in.
I don't entirely disagree, but I think there's more to it than that. While the language certainly does offer some free choices, more often there are advantages and disadvantages to each, so that in any particular situation, some choices are better than others. Becoming an expert Lisp programmer requires learning about these tradeoffs, which takes experience and, usually, guidance from existing experts.
There is a saying 'perfection is the enemy of done.' In any particular situation, there is probably not a solution that is both optimally efficient and also optimally elegant. (This is true in any programming language). If you work towards that goal too much, you will likely miss your deadline.
But the point is, the little advantages and disadvantages don't matter until they do. There isn't going to be a big difference in most programs between using a loop to iterate a sequence, and using map nil with a lambda, and using do* (for example). In fact, whether there is any difference at all in the resultant assembly or byte code will depend entirely on the compiler implementation. It is a style thing... so try to be consistent, and work within what you are comfortable with.
That's true of any language, of course, but some of the facilities Lisp offers are rare among other languages, so that people coming to Lisp from some other language are unlikely to have experience with them.
Currently, the only thing I can really think of that is actually really unique is the macro facility (and that is only because, as soon as a language adopts the macro facility, it becomes a lisp.
As a programmer, the focus of my job is learning new things. I am basically a mechanism for translating the new things that I have learned into computer code. If I can't learn a few measly language features, what good am I going to be as a 'thing I just learned to computer' translator. And like I said, use what you are familiar with, until you are faced with something someone else wrote, or you have the time to learn new things. But don't punt.
If someone doesn't have experience with a given piece of the language that has been used, I expect them to pick up a book or online resource about it (and then, possibly most importantly, play with it). It is not hard, but it does take effort. There is nothing in common lisp that requires genius level intellect. (God knows, I'm certainly not that bright). No one requires that fresh-faced C interns be pointer arithmetic gods, but i'm sure they are expected to learn it if it is part of the job.
Oh, one point about macros in particular. If you have to resort to reading the implementation of a macro to understand what it does, the person who wrote it screwed up. Macros should always have documentation strings explaning their syntax and semantics. If you find yourself in that situation, the best thing to do is to go to the REPL and use `macroexpand' interactively to see the expansions of the macro calls you're interested in.
I'll add that in addition to doc strings for syntax and semantics, there should also be assertions written into the macro about the syntax and semantics. If I am passing a number or list where the macro is expecting a symbol, an error should get thrown during the macro-expansion phase. Macros are programs like anything else. Validating inputs and throwing an error at the earliest possible time is a good rule to go by.
So, macroexpand-1 is a good start, if the macro is implemented correctly, does what its documentation says, and you are simply flubbing the syntax. (Of course, it should be yelling at you for flubbing the syntax).
However, when there is a bug in a macro, the only thing that macroexpand-1 will tell you is that the macro doesn't work. You'll macro-expand it and say 'yup that's the wrong generated code.' It doesn't really tell you anything about how to actually fix the macro unless you are already familiar with the macro's code. Having examples of inputs with bad outputs will aid in pinpointing the problem, but not unless I already understand how the program works.
Macros are lisp programs, and can be as complicated as any arbitrary lisp program. Writing a more complicated macro is not screwing up (I think this is an important distinction to make)... inadequately documenting, explaining, and bulletproofing it is. Someone might have to debug it later, so strive to write readable macro code. It isn't hard as you are just constructing lists and writing normal lisp code with minimal efficiency requirements.
So I guess that was a roundabout way of me saying "I agree, mostly."
I don't entirely disagree, but I think there's more to it than that. While the language certainly does offer some free choices, more often there are advantages and disadvantages to each, so that in any particular situation, some choices are better than others. Becoming an expert Lisp programmer requires learning about these tradeoffs, which takes experience and, usually, guidance from existing experts.
That's true of any language, of course, but some of the facilities Lisp offers are rare among other languages, so that people coming to Lisp from some other language are unlikely to have experience with them.
Oh, one point about macros in particular. If you have to resort to reading the implementation of a macro to understand what it does, the person who wrote it screwed up. Macros should always have documentation strings explaning their syntax and semantics. If you find yourself in that situation, the best thing to do is to go to the REPL and use `macroexpand' interactively to see the expansions of the macro calls you're interested in.