четверг, 12 ноября 2009 г.

[comp.prog.thoughts] Язык с GC – это уже платформа?

Неожиданно подумалось: код с ручным управлением памятью можно внедрить практически в любой язык с GC. Например, биндинги к C-ным и даже C++ным библиотекам есть для большого количества языков с GC (см., например, биндинги к libcurl). Тогда как объединение в одном приложении нескольких языков с GC – это уже сложнее. Скажем, часто ли вам приходилось видеть комбайны, в которых в рамках одного процесса работали Java, C, Python и Ruby? Сколько клея (glue code) нужно написать, чтобы на объект из Ruby-новой части можно было ссылаться из Python и Java частей и наоборот?

Получается, что для эффективного использования нескольких языков с GC в одном процессе необходимо, чтобы все эти языки делили общий GC. Т.е., чтобы они работали на общей платформе. Каковыми сейчас являются, пожалуй, только JVM и .NET.

PS. Вспоминается старый афоризм: Java – это не кроссплатформенный язык, Java – это платформа.

14 комментариев:

Skynin комментирует...

Java – это не кроссплатформенный язык, Java – это платформа.
Очень правильный афоризм.

А первое упоминание о .NET мне запомнилось указанием на то что 1. теперь можно писать на разных языках но взаимодействовать они будут просто, 2. теперь программист будет отделен от API OCи а работать с "родными" для выбранного языка библиотеками.

Если задуматься о термине кроссплатформенность с практической, а не академической стороны, то забавная штука получается. Недавно шеф устроил очную ставку по поводу ПО для эмбедедд устройств - между мной и линуксоидом, которого привел наш разработчик железа. Линуксоид мне - да если выбрать линух, то программы на С/С++ переносимы! Я ему - то есть если я напишу обработку вывод карты под GTK, на KDE тоже будет работать? "Ну... если поставить GTK" - так где ж переносимость если мне нужно и платформу переносить - GTK ( не говоря о выходе за пределы линуха), или с каким-нить Cygwin'ом? (я уж не стал его тиранить по поводу траблем с двоичной совместимостью, и заикаться о Mac'ах)

То есть, с практической стороны, что кроссплатформенность, что переносимость заключается в том что мы тащим платформу для "кроссплатформенности", или прослойку, которая обеспечит нам переносимость (пусть даже она компактна как скажем wxWidgets)

(Мое ИМХО)
Кроссплатформенность - это разработка на такой платформе что может работать над другими, несочетаемыми платформами.
Переносимость - это использование таких библиотек, фреймворков, прослоек, реализации которых существуют на тех платформах куда собираемся "переносить"

И часто эти слова - просто маркетинговые фишки. Типа "Легкое масло!" - да маргарин это, не надо нас дурить!

Quaker комментирует...

Неожиданно подумалось: код с ручным управлением памятью можно внедрить практически в любой язык с GC.
Если ради достижения наибольшей производительности, то можно GC динамически отключать или переключать в разные режимы, как это сделано в Eiffel:
- allocate compact (Enter ``memory'' mode: will try to compact memory
before requesting more from the operating system)
- allocate fast (Enter ``speed'' mode: will optimize speed of memory
allocation rather than memory usage)
- allocate tiny (Enter ``tiny'' mode: will enter ``memory'' mode after having freed as much memory as possible)
- collection off (Disable garbage collection)
- collection on (Enable garbage collection)
Ссылка: http://docs.eiffel.com/static/libraries/base/memory_flatshort.html

eao197 комментирует...

2Skynin

>Кроссплатформенность - это разработка на такой платформе что может работать над другими, несочетаемыми платформами.

Да, это самый распространенный случай. Менее распространенный -- это когда язык позволяет писать уникальный код под каждую платформу и сочетать фрагменты этого кода в общей кодовой базе (aka #ifdef-ы в C++, version-секции в D).

Кроме того, для нативных языков кроссплатформенность -- это кроссплатформенность на уровне исходников.

eao197 комментирует...

2Quaker:

>Если ради достижения наибольшей производительности, то можно GC динамически отключать или переключать в разные режимы, как это сделано в Eiffel

Ну да. В Ruby, кажется, была возможность запрещать GC на определенные моменты времени. Да и в Java было что-то подобное.

Но вот в чем фокус: когда мы объединяем один язык с GC и один язык без GC, то все просто. Но стоит попробовать объединить два языка с GC (Ruby и Python, к примеру) -- вот тогда что?

Skynin комментирует...

#ifdef-ы , -- это кроссплатформенность на уровне исходников.
Да, еще одно "легкое масло" :)

eao197 комментирует...

>Да, еще одно "легкое масло" :)

Это не масло, это станок, для выжимки подсолнечного масла, который при желании может выжимать оливковое.

Местами востребованный (когда приходится работать на низком уровне, вроде Wireshark-а).

Quaker комментирует...

Но стоит попробовать объединить два языка с GC (Ruby и Python, к примеру) -- вот тогда что?
Тогда действительно эти языки, как Вы уже отметили, должны иметь общий GC. Вопрос в другом: есть ли практическая необходимость (кроме just for fun) в получении такого винегрета из ruby и python? Можно ли придумать реальные задачи, которые требуют именно такого объединения? Как мне представляется, объединеием ruby/python/java с c/c++ можно достичь чего угодно.

eao197 комментирует...

>Вопрос в другом: есть ли практическая необходимость (кроме just for fun) в получении такого винегрета из ruby и python?

Не знаю пока. Но мало ли что кому-то может взбрести в голову. Захочет объединить в одном приложении написанных на Ruby агентов (скажем, RubyAgent) и реализованные на Python DocUtils. Или сделать то же самое, но в сочетании Erlang+Python.

Skynin комментирует...

Это не масло, это станок, для выжимки подсолнечного масла

Я к тому что на деле кроссплатформенность и переносимость напоминают слова Форда - "Вы можете выбрать Форд-Т любого цвета, при условии что он будет черным"

Местами востребованный
Да это понятно что лучше уж как-нибудь чем никак.

Переносимый код - это шутка такая. На деле эту фразу следует читать:
Есть в коде соотвествующие платформе ifdef'ы и нужные на этой платформе библиотеки.

Что же "объединение в одном приложении нескольких языков с GC" то причина сложности, как мне думается, в том что в каждом ЯП поиск ненужных ссылок на области памяти серьезно завязан на свойствах самого ЯП. Если же ЯП на разных платформах (читай у каждого своя ВМ) то в случае обмена ссылками - ни отдавшая ВМ не знает что там с ее ссылкой делают, ни принявшая ссылку ВМ не знает - а можно ли освобождать память.

Кстати, не так просто и ЯП с GC интегрируется с чем-то написанном с ручным распределением памяти. "Внешние ресурсы" приходится также вручную освобождать.

eao197 комментирует...

>то в случае обмена ссылками - ни отдавшая ВМ не знает что там с ее ссылкой делают, ни принявшая ссылку ВМ не знает - а можно ли освобождать память.

Ага, про это я и говорю. Поэтому ситуация значительно упрощается, когда все языки разделяют общий GC. Скажем, интерграцию Ruby MRI и CPython сделать сложно. А вот JRuby и Jython должны интегрироваться значительно проще.

>Кстати, не так просто и ЯП с GC интегрируется с чем-то написанном с ручным распределением памяти. "Внешние ресурсы" приходится также вручную освобождать.

Ну это хоть как-то решается.

Skynin комментирует...

Ну это хоть как-то решается.
Да, согласен, проще чем между ВМами.

Наверное как в жизни - без автоматики жить пусть сложно, но можно. Но если есть только автоматика, и нештатная ситуация - а рычажка нет, то...

Skynin комментирует...

по словам Алексея Куканова из Intel "...сейчас языки не делают погоды. Рулят платформы. ... Всю масса библиотек, разработанных для C/С++, тоже можно расценивать как платформу.
Куда мы теперь Go?

Анонимный комментирует...

кажется, в этом смысле самым кроссплатформенным языком является haXe ( http://haxe.org/ )

C# успешно, кстати, получается компилировать под много разных платформ тоже, хотя солидные куски стд библиотек приходится носить с собой.

eao197 комментирует...

>кажется, в этом смысле самым кроссплатформенным языком является haXe ( http://haxe.org/ )

В свете анонса Chromium OS языки такого плана получают вполне реальный шанс (видел его когда-то, сейчас глянул еще раз в доку, сразу не понравилось, что в качестве исключений можно бросать что угодно).

>C# успешно, кстати, получается компилировать под много разных платформ тоже, хотя солидные куски стд библиотек приходится носить с собой.

Правильно я понимаю, что речь идет о Mono?