Оказалось, что на RSDN разгорелся нешуточный флейм в духе старых-добрых времен: Конец нересурсов. Что особенно приятно, в нем даже дали ссылку на заметку в моем блоге. В принципе, данный флейм был достоин упоминания только за это :) Но в нем было еще несколько интересных моментов.
В частности, довольно долго участники спора противопоставляли native-приложения managed-приложениям. Но когда дело дошло до выяснения того, чем же native отличается от не-native, ничего путного родиться не смогло (вероятно, тот ламер, который больше всех верещал о доминировании managed, слабо разбирается в этом вопросе, а его более матерые собеседники откровенно стебались и не спешили просвещать человека). Хотя вопрос, как мне думается, не так прост, как может показаться. Я и сам бы с ходу не смог сформулировать что есть native, а что managed.
Когда я в бытность активным RSDN-ером бодался с .NET-евангелистами все казалось просто: .NET и JVM – это managed, С/C++ – это native, Python/Perl/Ruby/PHP/Bash и пр. – это managed, Objective-C – это native и т.д. Вроде бы все интуитивно понятно. Но, как показал упомянутый RSDN-овский флейм, интуиция может быть у каждого своя. Поэтому нужно придумать что-то более-менее формальное.
Так вот, мне представляется, что native-приложение – это такое приложение, для запуска и работы которых достаточно только штатных возможностей ОС и которое работает на “голом железе” (т.е. инструкции приложения сразу же выполняются процессором, а не какой-либо виртуальной машиной). А вот для managed-приложения требуется некий промежуточный слой между кодом приложения и ОС. Таким слоем может быть либо интерпретатор (как в случае со скриптовыми языками вроде Python/Perl/Ruby), либо виртуальная машина (JVM), либо JIT-среда, которая компилирует инструкции VM в нативный код при первом обращении (как в .NET).
Вот такое вот простое разграничение. Никакие сборщики мусора, никакие средства трассировки и контроля за исполнением (вроде проверок выхода за рамки массива), никакие средства рефлексии и предоставления метаинформации о коде в расчет не принимаются. Просто потому, что есть примеры вполне себе native-приложений, у которых есть и GC, и контроль за кодом, и подробная диагностика мест возникновения исключений, и прочая лабуда. Например, у разработанных на Eiffel, OCaml, D или Go приложений.
При этом нужно говорить именно о приложениях. А не о коде. И уж тем более не о языках программирования. Просто потому, что один и тот же язык может иметь транслятор как в native-код, так и в код какой-либо виртуальной машины. Как у Eiffel или OCaml, например. И один и тот же код может работать как в native-, так и в managed-приложении. Хотя, если код затачивается под использование возможностей конкретной managed-платформы, то тогда имеет смысл называть код managed-кодом.
Но самое забавное, что даже такие, казалось бы, низкоуровневые языки, как C++ и C, имеет интерпретаторы! Пусть поддерживающие ограниченное подмножество языков, но тем не менее позволяющие запускать довольно-таки серьезные приложения. Первый из них – это CINT. Второй – Ch. Вот такие дела, и C++ приложения могут быть вполне себе managed. По крайней мере согласно моему определению ;)