Сегодня порассуждаю на тему компиляторов. Почему? Потому что стало много вещей непонятных и это бесит, когда не понимаешь что-то :) Подумав про непонятное, пришел к выводу, что чтобы как-то подойти к этому издалека, будет полезно поговорить сначала про компиляторы, а потом плавно перейти к самому вкусному.
Компиляторов много, и их больше, чем 2 или 3 типа, как многие думают (если верить книжке trustworthy compilers):
есть классические компиляторы, которые берут текст программы (написанный на нормальном человеческом высокоуровневом языке программирования, например C, C++, Pascal) и переводят те команды в машинный код, которые понимаются непосредственно железякой. Это нативное компилирование, самое мне родное и понятное, я с таких языков и с таких компиляторов начинал программировать :)
На втором месте - интерпретаторы. Вместо трансляции высокоуровнего кода в бинарник, они берут исходный код и начинают выполнять его по инструкциям языка, в итоге бинарник не рождается, и чтобы что-то исполнить, всегда нужен исходник, написанный на высокоуровневом языке. (Вообще говоря странно, интерпретатор - это не разновидность компилятора, это вообще другая штука по своей природе. Меня учили, что компилятор - это такая штучка, которая один язык программирования переводит в другой, это типа транслятор такой. Интерпретатор же - ленивая хрень, она ничего никуда не транслирует, а просто выполняет)
Следующий вид - кросскомпиляторы. Они берут сурс код и генерят бинарник для других устройств, например для телефона. (телефоны они тупые, они не понимают бинарников компа, поэтому к ним нужен особый подход и вот такие компиляторы создают команды, которые понятны даже телефонам. На месте телефонов может быть любой другой девайс, не понимающий бинарники компа, например какой-нибудь странный микропроцессор).
JIT компиляторы (just in time) - хитрющие компиляторы, которые работают в процессе исполнения программы и компилируют методы при первом их вызове, и при этом компилируют их в бинарный код текущей платформы. Такие компиляторы являются врожденной частью Java и .NET.
AOT компиляторы (ну-ка догадайтесь, как расшифровывается?) - это прекомпиляторы, которые все делают "правильно" и заранее компилируют платформенно независимый код в бинарный код текущей платформы. Зачем они это делают? Для повышения скорости исполнения. Впринципе, походу, это те же самые классические компиляторы.. Но вот решили в отдельный класс отнести. Ну ладно, пусть будет. АОТ так же используются в Java и .NET.
Конверторы - компиляторы, как раз в моём классическом понимании - переводящие один язык программирования в другой. Собственно классический компилятор - это частный случай конвертора, если я не ошибаюсь... Зачем было выводить его в отдельный класс, не понимаю, конвертор и конвертор, но раз товарищи ученые хотят - пусть будет 2 разных класса компиляторов.
Бинарные компиляторы - они прикольные. Они переводят бинарный код одной платформы в бинарный код другой платформы, при этом не требуют исходников на высокоуровневом языке.
Есть Graph compilers - какие-то суперновые компиляторы, зачем нужны и че делают я не понял)
Еще есть incremental compilers (тоже не понял зачем они нужны. Написано, что были популярны в 70ые, видимо до моих лет они не дожили. Ну и слава богу:) не буду забивать себе голову).
Первый шок: интерпретаторы все равно транслируют код в бинарный, пусть и по инструкциям, а не весь сразу. Почему бы сразу весь этот интерпретируемый язык не скомпилировать в бинарник и радоваться жизни, ведь интерпретируемые языки медленные, они при каждом исполнении инструкции должны пропарсить инструкцию, скомпилировать её, и уж только потом уже исполнить, вместо того, чтобы сразу исполнить и не думать вообще. Однако, как пишут в той же книжке, в основном в интерпретируемых языках используется динамическая типизация и это типа их мегафишка.
Языки бывают с разной типизацией, я знаю 4 из них: языки со статической типизацией, с динамической, со строгой и со слабой. А еще есть типизируемые языки, нетипизируемые, сильнотипизируемые и слаботипизируемые. Это упасть и не встать))) И вот мы плавно подходим к тому, что меня бесит и что я не понимаю.. Языки программирования. Зачем их так много придумали? Почему они такие сильно разные? Кроме тех 8 типов, языки еще можно разделить на компилируемые, интерпретируемые и скриптовые. И еще плагины существуют, которые ясности точно не приносяти еще больше все запутывают.
Мне всегда было интересно, почему это Java не совсем скриптовый язык? (или совсем не скриптовый?)) ) А вот Python - настоящий скриптовый язык. Что вообще такое скрипт? Я всегда считал, что это макрос. Просто последовательность действий, самая обычная. И почему же это на Джаве нельзя написать последовательность действий и обозвать то, что получится - скриптом? А C++ это тоже не скриптовый язык? Что же в C++ и Java такого особенного, что они не могут написать макрос? В общем куча непонятностей) Обо всем об этом в следующий раз.
воскресенье, 16 мая 2010 г.
Подписаться на:
Комментарии к сообщению (Atom)
Дим, языков много, потому что парадигм программирования много :)
ОтветитьУдалитьЯ приведу пример, который придумал неделю назад. Вот этот код выполняет разворот списка на C:
struct item *reverse(struct item *head)
{
struct item *p, *q, *r;
p = head;
if (!p) return head;
q = p->next;
if (!q) return head;
while (q)
{
r = q->next;
q->next = p;
p = q;
q = r;
}
head->next = NULL;
return p;
}
Этот тоже:
struct item *reverse_helper(struct item *h1, struct item *h2)
{
struct item *p;
if (!h1) return h2;
p = h1->next;
h1->next = h2;
return reverse_helper(p, h1);
}
struct item *reverse(struct item *head)
{
return reverse_helper(head, NULL);
}
Второй реально проще понять, но C — не тот язык, на котором он реально понятен. А реально понятен он на хаскелле (простой вариант, можно ещё короче):
reverse_helper [] l = l
reverse_helper (x:xs) l = reverse_helper xs (x:l)
reverse l = reverse_helper l []
или на лиспе:
(defun reverse_helper (l1 l2)
(if (null l1) l2
(reverse_helper (cdr l1) (cons (car l1) l2))
)
)
(defun reverse (l) (reverse_helper l nil))
На каждом языке получается писать выразительно что-то одно, а другое не получается :)