Две большие вещи, которые делают макросы, это управление оценкой их аргументов и преобразование кода во время компиляции.Вы можете сделать и то и другое с функциями, требуя, чтобы вызывающий код заключал их аргументы в кавычки.
Например, вы можете написать версию defn
, которая будет называться следующим образом:
(defn 'name '[arg1 arg2]
'(expression1)
'(expression2)
'etc)
Затем выможет eval
аргументировать по своему желанию, оценивать их или нет, изменять порядок выполнения или изменять формы перед их оценкой, именно для этого и нужны макросы.
Что могут делать макросы, которые не могут выполнять функцииэто получить эту способность без какого-либо сотрудничества с вызывающим кодом.Пользователи могут вызывать макросы, как если бы они были простыми функциями, и им не нужно обрабатывать свои аргументы иначе.
Вот так макросы позволяют расширять язык: вам не нужно обрабатывать код макроса иначе, чемобычный код, в отличие, скажем, от JavaScript, Ruby или Python, где язык можно расширить только с помощью новых конструкций потока управления, выполнив то, что вы сделали в своем примере, заключив код в блок, лямбду или функцию.