One can document sublanguages, too. The Common Lisp standard for example defines sublanges like LOOP, FORMAT, the Pretty Printer, CLOS, etc.
The better embedded languages in Lisp often follow conventions: see for example CLOS and the various conventions it follows from naming to integration.
The actual problem is that defining sublanguages for most developers is not something they have learned. The result is a multitude of languages for similar tasks with their own infrastructure. For many programmers it is normal to wait for new language constructs for several years - while they work around this by combining language built-in constructs (extreme: creating lots of bloat - see Java), by using preprocessors (upto transpilers of different languages - see Java and Javascript for languages transpiling to those).
There is some complexity in Lisp providing features for embedding languages.
But there is also complexity in working around that with languages not very good in embedding. See for example Clojure, a language which provides functional programming idioms on top of Java - the integration is great - but many developers are not satisfied about the integration when it comes to debugging - see the complexity for example of stack traces in a layered language design.
The better embedded languages in Lisp often follow conventions: see for example CLOS and the various conventions it follows from naming to integration.
The actual problem is that defining sublanguages for most developers is not something they have learned. The result is a multitude of languages for similar tasks with their own infrastructure. For many programmers it is normal to wait for new language constructs for several years - while they work around this by combining language built-in constructs (extreme: creating lots of bloat - see Java), by using preprocessors (upto transpilers of different languages - see Java and Javascript for languages transpiling to those).
There is some complexity in Lisp providing features for embedding languages.
But there is also complexity in working around that with languages not very good in embedding. See for example Clojure, a language which provides functional programming idioms on top of Java - the integration is great - but many developers are not satisfied about the integration when it comes to debugging - see the complexity for example of stack traces in a layered language design.