In LISP-like languages like Racket, the code is a list. That is, a program is just a list of tokens (a b c), the same data structure one would use for storing any other kind of data (the equivalent of Python’s [a b c]). When programs are themselves just lists, they are easy to manipulate with code. So, in LISP-like languages, it is easy to write code that writes code. That makes them especially suitable for domain-specific languages or LOP. You can write functions that write code, making a new language.
I think PG has some writings on this topic, but I don’t remember if it is online or in his LISP textbooks. His company Viaweb did this, IIRC, using a DSL written in LISP to generate HTML.
If I give GP the benefit of the doubt, I think GP is well aware of this. However, their point is that in these examples, the original input was not in S-Expression form, so the ease of manipulation did not exist until it was parsed.
A list of characters (a string) and a list of tokens are drastically different to work with. If you haven't worked with both and want to write programming languages, I would recommend filling the gap of the one you haven't to see/feel the difference.
Beyond the code being a list, Racket's macro system and syntax parse / creation tools are incredibly powerful and come built in where you could spend years in another language just getting the tooling to write a language, let alone writing it.
LISP code is not a list as you know it traditionally. It's made up of cons cells. The code of other languages is not a cons cell, altho it is a list of characters. Very important distinction.
I think PG has some writings on this topic, but I don’t remember if it is online or in his LISP textbooks. His company Viaweb did this, IIRC, using a DSL written in LISP to generate HTML.