However, not all applications really need that power, and they still get the job done which they were intended for. So plugging in the Lisp-like language interpreter solved the problem at hand, with a minimum of implementation and testing effort. Lua would have provided a much more powerful and well-rounded solution, but I would have had to spend another day or two to get it working properly, and just maybe I wouldn't have used the flexibility and options which Lua would have provided anyway.
It depends on the software, sure, but for some software you shouldn't make such concessions.
For some software, 'limitless power' is part of the design goal. FrexxEd is a good example of that, and it's script language is the main reason why it's so powerful.
My outlook on software quality and how to get it has changed over the years. When I started noodling around with BASIC on whatever home computer I could get my hands on my curiousity was the driving force in getting stuff done. A couple of years down the line I got it into my head that working on a program actually is a task that can always be finished.
At times that even was true when somebody was willing to pay me money for the work I did, or when somebody was very keen on putting my work to good use. That's when you had to make sure that everything you promised or hoped for was accounted for and in the box, before you closed it, tied a bow around it and handed it over.
I've been programming for some odd 30-31 years now, both as a hobby and as a profession, and I couldn't help noticing that there were recurring patterns in the work I did. One important pattern is in that your work is rarely finished, and that you will end up iterating on it. You'll invariably find bugs, understand your own work and working method better, understand what the requirements of the project were better than you did before, and with that insight will come the need to give the job another go, so as to make things better.
This is one of the key insights I gained: your choices, when it comes to designing and implementing software, may not be the best at the time you make them, but that is not the end of the story. You will return to your work, and this time it may improve. Even if it doesn't, then maybe the next iteration will be better.
With this insight you gain a different perspective on how you spend your time on the project. You begin accept that you will be unable to make the best choices, and that the next best thing you can do is focus on specific parts of the task which benefit most from your attention. This is where you'll discover that you have been making trade-offs all the time. Some code may be best in a state in which it's readable and not necessarily optimized for time or space. Some code may be best in a state in which it's optimized. Some code just doesn't benefit from any polishing at all. Turns out that some of the trade-offs you make don't look so good in hindsight, and off you'll go for another round of making better choices.
And that's about it: just because I pick one quirky scripting language that has trouble walking and chewing gum at the same time over an arguably superior alternative it doesn't have to stay that way forever.
I distrust the notion of perfect code or the perfect solution for a problem, as implemented by a program. Perfect code has no bugs and always solves the problem at hand. I've seen that, but the scope such perfect code covers is usually tiny, and if it isn't, it takes a crazy amount of work to produce it. I'm not in the business of producing that kind of work

Trying to get to the perfect solution, that I can agree with as part of a process. But you can only get very, very close (asymptotically close, for the mathematically inclined among us) to it and never quite reach that point. Close enough is good enough for me, as otherwise you'll spend your time chipping away at only one small part of the interesting stuff you might otherwise get a chance to explore instead.