Ответ 1
Это один из фундаментальных уроков SICP и одна из самых мощных идей в области информатики. Он работает следующим образом:
То, что мы считаем "кодом", на самом деле не имеет силы ничего делать самостоятельно. Код определяет программу только в контексте интерпретации - вне этого контекста, это всего лишь поток символов. (На самом деле поток бит, который на самом деле является потоком электрических импульсов. Но пусть это будет просто.) Значение кода определяется системой, в которой вы его запускаете, и эта система просто рассматривает ваш код как данные, которые сообщают это то, что вы хотели сделать. Исходный код C интерпретируется компилятором C как данные, описывающие файл объекта, который вы хотите его создать. Объектный файл обрабатывается загрузчиком как данные, описывающие некоторые машинные инструкции, которые вы хотите поставить в очередь для выполнения. Машинные инструкции интерпретируются ЦП как данные, определяющие последовательность переходов состояний, которые должны пройти.
Интерпретированные языки часто содержат механизмы обработки данных как кода, что означает, что вы можете передавать код в функцию в какой-либо форме, а затем выполнять ее - или даже генерировать код во время выполнения:
#!/usr/bin/perl
# Note that the above line explicitly defines the interpretive context for the
# rest of this file. Without the context of a Perl interpreter, this script
# doesn't do anything.
sub foo {
my ($expression) = @_;
# $expression is just a string that happens to be valid Perl
print "$expression = " . eval("$expression") . "\n";
}
foo("1 + 1 + 2 + 3 + 5 + 8"); # sum of first six Fibonacci numbers
foo(join(' + ', map { $_ * $_ } (1..10))); # sum of first ten squares
Некоторые языки, такие как схема, имеют понятие "первоклассные функции", что означает, что вы можете рассматривать функцию как данные и передавать ее без оценки, пока вы действительно не захотите.
Результат состоит в том, что разделение между "кодом" и "данными" довольно произвольно, функция только перспективы. Чем ниже уровень абстракции, тем "умнее" код должен быть: он должен содержать больше информации о том, как он должен выполняться. С другой стороны, чем больше информации предоставляет интерпретатор, тем глубже может быть код, пока он не начнет выглядеть как данные без каких-либо умственных способностей.
Один из самых мощных способов написания кода - это простое описание того, что вам нужно: данные, которые будут преобразованы в код, описывающий, как получить то, что вам нужно, в контексте интерпретации. Мы называем это "декларативное программирование" .
Для конкретного примера рассмотрим HTML. HTML не описывает полный язык программирования Turing. Это просто структурированные данные. Его структура содержит некоторые умственные способности, которые позволяют контролировать поведение интерпретационного контекста, но не так много умнов. С другой стороны, он содержит больше smarts, чем абзацы текста, которые появляются на средней веб-странице: это довольно немые данные.