Чтобы прояснить ситуацию с представлением кода, учтите, что в каждый код языка - это данные: все, что вам нужно, это строки. (И, возможно, несколько файловых операций.) Размышление о том, как это поможет вам имитировать преимущества Lisp от наличия макросистем, является хорошим способом для просветления. Еще лучше, если вы попытаетесь реализовать такую макросистему. Вы столкнетесь с преимуществами наличия структурированного представления по сравнению с плоскостностью строк, необходимостью сначала выполнить преобразования и определить «синтаксические хуки», чтобы указать, где их применять и т. Д. И т. Д.
Но главное, что вы увидите во всем этом, - это то, что макросы - это, по сути, удобное средство для зацепки компилятора - зацепки с недавно созданными ключевыми словами. Таким образом, единственное, что действительно необходимо, - это способ взаимодействия пользовательского кода с кодом компилятора. Плоские строки - один из способов сделать это, но они предоставляют настолько мало информации, что программе записи макросов остается задача реализации синтаксического анализатора с нуля. С другой стороны, вы можете представить некоторую внутреннюю структуру компилятора, например предварительно проанализированные AST-деревья, но они, как правило, предоставляют слишком много информации для удобства и , это означает, что компилятор должен каким-то образом иметь возможность анализировать новое синтаксическое расширение, которое вы намереваетесь реализовать. S-выражения - хорошее решение для последнего: компилятор может анализировать все что угодно, поскольку синтаксис одинаков. Они также являются решением первой проблемы, поскольку представляют собой простые структуры с широкой поддержкой языка для их разделения и повторного объединения по-новому.
Но, конечно, это не конец истории. Например, интересно сравнить простые символьные макросы, как в CL, и гигиенические макросы, как в реализациях Scheme: они обычно реализуются путем добавления дополнительной информации к представленным данным, что означает, что вы можете делать больше с этими макросистемами. (Вы также можете сделать больше с макросами CL, так как дополнительная информация также доступна, но вместо того, чтобы сделать ее частью представления синтаксиса, она передается в качестве дополнительного аргумента среды макросам.)