JVM поддерживает так много языков, кроме Java, как и Groovy,Clojure,Scala
т. Д., Которые являются функциональными языками в отличие от Java (я имею в виду Java до Версии 8, где Lambda's
они не поддерживаются), которые не поддерживают функциональные возможности. На высоком уровне, что делает JVM настолько универсальной, что она может поддерживать как объектно-ориентированные, так и функциональные языки?
18
Ответы:
По сравнению с другими виртуальными машинами JVM на самом деле не особенно универсальна . Он напрямую поддерживает статически типизированный ОО. Во всем остальном вы должны увидеть, какие части вы можете использовать, и как вы можете построить все остальное, что нужно вашему языку, поверх этих частей.
Например, до тех пор, пока Java 7 не представила
invokedynamic
байт-код, было очень трудно реализовать динамически типизированный ОО-язык на JVM - вам приходилось использовать сложные обходные пути, которые плохо влияли на производительность и приводили к ужасно раздутым следам стека.И все же до этого в JVM была реализована группа динамических языков (Groovy, Jython, JRuby и др.).
Не потому, что JVM настолько универсальна, а потому, что она широко распространена, а также потому, что она имеет очень зрелые, хорошо поддерживаемые и высокопроизводительные реализации.
И, возможно, даже более важно, потому что существует огромное количество кода Java, который делает практически все, и если ваш язык работает на JVM, вы можете легко предложить средства для интеграции с этим кодом. По сути, использование вашего языка в JVM - это версия 21-го века, предлагающая взаимодействие с C.
источник
JVM была написана так, чтобы в основном действовать как процессор, есть набор инструкций, вроде сборки, которые виртуальная машина выполняет, называемые байт-кодами. Если вы можете написать компилятор, который генерирует допустимый набор байт-кодов, то JVM может запустить их.
В Википедии есть список байт-кодов:
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
а также объяснение того, как JVM загружает байтовые коды:
http://en.wikipedia.org/wiki/Java_virtual_machine
Используя байт-коды в стиле invoke, функциональный язык может выполнять код независимо от того, как выглядит исходный код. Кроме того, с добавлением invokevirtual языковые реализации, такие как jruby, дали некоторую гибкость в том, как они работают.
источник
Я добавлю, что JVM поддерживает четко определенную и довольно приличную модель памяти ( JMM ), что означает хорошую поддержку согласованного (хотя и низкого уровня) поведения потоков. Он также имеет мощный компилятор Just In Time (больше не полезен для динамических языков благодаря MethodHandles и invokedynamic).
И последнее, но не менее важное - это подсистема сбора мусора в JVM, которая (с правильной настройкой) управляет памятью независимо от языка наверху.
источник
someField = new int[]{42};
единственные способы гарантировать, что любой поток, который видит новый массив, увидит значение 42 должны либо сделать полеfinal
илиvolatile
. Если поле генерируется лениво, но к нему часто обращаются, то его создание неfinal
будет работать, и его созданиеvolatile
может налагать излишние штрафы за синхронизацию при каждом обращении к нему. Даже в самой свободной модели .NET ...Ключевым элементом в этом является отделение компиляции от фазы выполнения. Таким образом можно написать другие компиляторы, компилирующие другие языки для байт-кода.
Байт-код действует аналогично машинному коду ЦП - у вас есть все небольшие операции, необходимые для запуска программы - вы можете получить переменную, выполнить математическую обработку, выполнить условные операции и т. Д.
Ява тоже не особенная. В Java существование нескольких языков не было даже целью проектирования, в отличие от других виртуальных машин. Для Microsoft .Net CIL способность работать на нескольких языках (C #, VB.Net, ...) была ключевым элементом дизайна, а также ParrotVM из проекта Perl6, предназначенного для создания универсальной виртуальной машины.
Для удовольствия я однажды создал доказательство того, что даже Zend Engine PHP это допустит.
И, честно говоря, в этом нет ничего нового - даже на реальном оборудовании вы можете использовать несколько языков - например, C или Fortran.
Разница в этом отделении от компиляции и выполнения заключается в классических интерпретаторах, таких как некоторые формы Basic, сценарии оболочки и т. Д. Они часто работают таким образом, что выполняют код более или менее построчно, не приводя его в непосредственную форму. между.
источник
JVM - первая из известных мне виртуальных машин, в которой сочетаются сборка мусора, производительность и работоспособная модель песочницы. Появление многих языков для поддержки JVM, вероятно, является не столько результатом его «универсальности», сколько тем, что в языке Java отсутствуют некоторые важные функции, которые нужны людям в языке программирования. Например, хотя большинство машинных языков имеют только полдюжины или около того типов данных (например, байт, полуслово, слово, двойное слово, с плавающей запятой одинарной точности и с плавающей запятой двойной точности), подавляющее большинство языков программирования позволяют использовать код произвольное количество пользовательских типов данных. JVM распознает несколько примитивных типов, аналогичных типам на типичной машине, плюс еще один тип: Ссылка на разнородные объекты. Язык Java также распознает эти примитивы, и беспорядочные ссылки на объекты. Хотя переменная может быть ограничена, чтобы не хранить ссылки на что-либо, что не является конкретным классом, язык не делает различий между любыми из следующих типов полей типа
List<String>
это может быть проведеноMyThing
классом экземпляраMyClass
:Ссылка на что-то код знает, что является неизменной реализацией
List<String>
Ссылка на экземпляр типа изменяемого списка, который никогда не будет подвергаться воздействию чего-либо, что может его изменить.
Ссылка на изменяемый список, на который, кроме как во время выполнения
MyThings
методов, никакая другая ссылка не может существовать где-либо в юниверсе.Ссылка на изменяемый список, который принадлежит другому объекту , который этот другой объект хотел бы
MyThing
использовать каким-либо образом.Ссылка на изменчивый список, которому
MyThing
принадлежит, но который он также выставил некоторым другим объектам, чтобы они могли что-то с ним сделать.Хотя все эти поля могут иметь тип
List<String>
, они содержат разные вещи. Выразительный язык может допускать различие между этими значениями, но Java этого не делает. Поскольку язык может придавать смысл таким вещам (по крайней мере, вне общего контекста) и работать на JVM, это оставляет много места для языков, нацеленных на JVM, для выражения концепций, которые Java не может.источник