I know that Lisp and Scheme programmers usually say that eval should be avoided unless strictly necessary. I’ve seen the same recommendation for several program
Eval is not evil. Eval is not complicated. It is a function that compiles the list you pass to it. In most other languages, compiling arbitrary code would mean learning the language's AST and digging around in the compiler internals to figure out the compiler API. In lisp, you just call eval.
When should you use it? Whenever you need to compile something, typically a program that accepts, generates or modifies arbitrary code at runtime.
When shouldn't you use it? All other cases.
Why shouldn't you use it when you don't need to? Because you would be doing something in an unnecessarily complicated way that may cause problems for readability, performance and debugging.
Yeah, but if I'm a beginner how do I know if I should use it? Always try to implement what you need with functions. If that doesn't work, add macros. If that still doesn't work, then eval!
Follow these rules and you'll never do evil with eval :)