По сравнению с другими виртуальными машинами JVM на самом деле не особенно универсальна . Он напрямую поддерживает статически типизированный ОО. Во всем остальном вы должны увидеть, какие части вы можете использовать, и как вы можете построить все остальное, что нужно вашему языку, поверх этих частей.
Например, до тех пор, пока Java 7 не представила invokedynamic
байт-код, было очень трудно реализовать динамически типизированный ОО-язык на JVM - вам приходилось использовать сложные обходные пути, которые плохо влияли на производительность и приводили к ужасно раздутым следам стека.
И все же до этого в JVM была реализована группа динамических языков (Groovy, Jython, JRuby и др.).
Не потому, что JVM настолько универсальна, а потому, что она широко распространена, а также потому, что она имеет очень зрелые, хорошо поддерживаемые и высокопроизводительные реализации.
И, возможно, даже более важно, потому что существует огромное количество кода Java, который делает практически все, и если ваш язык работает на JVM, вы можете легко предложить средства для интеграции с этим кодом. По сути, использование вашего языка в JVM - это версия 21-го века, предлагающая взаимодействие с C.