Просветите дилетанта и помогите внести хотя бы малую ясность в таком вопросе. Я до последнего времени жил в представлениях, что есть ОЗУ/ЕЕПРОМ с линейной адресацией и определенной разрядностью, набор регистров и система команд процессора. И все было просто и понятно - навалил кучу байт - это ДАННЫЕ, трактуешь их как хочешь, загружаешь в регистры, ИЗМЕНЯЕШЬ командами, пишешь обратно... Последовательность псевдокоманд в ОЗУ - это тоже ДАННЫЕ, хоть и можно их последовательно считывать и в зависимости от содержимого выполнять разные инструкции, изменяющие другие данные... И всякие Си/Паскали и т.п. воспринимались как ОБЕРТКИ над этой стройной картиной - наш друг компилятор, который нафигачит кучу инструкций для кратких абстракций в коде, ну появились ТИПЫ - некоторые соглашения как мы интерпретируем байты ДАННЫХ, параметры/возвращаемые значения функций - но стек то и так уже был...
Несколько месяцев назад эта идиллия несколько трансформировалась с открытием "функций как объектов первого класса" - ну допустим это понятно, чанки - те же паттерны кодирования инструкций в ячейках памяти данных/стеке. Всякий страх из серии "ТИПЫ - это неподвижные точки специальных объектов, называемых алгебрами функторов" пока вообще не ассоциируется ни с какой концепцией, и отложен до лучших времен. Но вчера взялся за простую книжку "для юных сурков" - SICP, до определенного момента было все понятно и хорошо, но разрыв шаблона случился при прочтении следующего откровения:
Цитата:
Мы ведь ни разу не сказали, что такое пара, и указывали только, что для работы с
парами язык дает нам процедуры cons, car и cdr. Но единственное, что нам надо
знать об этих процедурах — это что если мы склеиваем два объекта при помощи cons,
то с помощью car и cdr мы можем получить их обратно. То есть эти операции удовле-
творяют условию, что для любых объектов x и y, если z есть (cons x y), то (car
z) есть x, а (cdr z) есть y. Действительно, мы упомянули, что три эти процедуры
включены в наш язык как примитивы. Однако любая тройка процедур, которая удовле-
творяет вышеуказанному условию, может использоваться как основа реализации пар.
Эта идея ярко иллюстрируется тем, что мы могли бы реализовать cons, car и cdr без
использования каких-либо структур данных, а только при помощи одних процедур. Вот
эти определения:
(define (cons x y)
(define (dispatch m)
(cond ((= m 0) x)
((= m 1) y)
(else (error "Аргумент не 0 или 1 -- CONS" m))))
dispatch)
(define (car z) (z 0))
(define (cdr z) (z 1))
Такое использование процедур совершенно не соответствует нашему интуитивному по-
нятию о том, как должны выглядеть данные. Однако для того, чтобы показать, что это
законный способ представления пар, требуется только проверить, что эти процедуры
удовлетворяют вышеуказанному условию.
Это что теперь - все можно, режь-коли, души гусей? (С) Если функции как данные и как объекты первого класса я еще могу представить как чанки в ОЗУ, а тут данные как функции или аргументы, спрятанные в их параметрах... Зачем тогда в том же Haskell есть АТД как основа всего сущего? Если там тоже функции - объекты первого класса, можно ли там также реализовать данные как функции без АТД и другие функции на них? В общем, помогите непротиворечиво совместить в голове все эти концепции...