Ответ 1
Основная причина заключается в том, что Clojure был разработан как homoiconic, то есть код выражается в основных структурах данных языка. Все Lisps разделяют это свойство, но мало других языков. В результате на весь языковой дизайн Lisps находится сильное влияние этого решения.
Выбор был сделан в начале дизайна Lisp, чтобы списки использовались для вызова функции в форме:
(function arg1 arg2 arg3) => some result
Это имеет множество преимуществ:
- Вызов функции выражается как единый объект данных, известный как "форма" (в этом случае форма представляет собой список, но также может быть вектором, хэш-картой, литеральным значением и т.д.). Вы можете передать его, изменить его и преобразовать по мере необходимости перед выполнением.
- Легко построить такие вызовы функций, используя стандартные операции с списком - например.
(cons function-symbol list-of-args)
- Синтаксис очень легко разобрать - все между двумя круглыми скобками - это самодостаточное выражение. Это упрощает составление парсеров, а также помогает с инструментами (см., Например, невероятный массив команд обработки символов в emacs).
Имя функции могло быть помещено вне круглых скобок:
function (arg1 arg2 arg3) => some result
Но у этого было бы много недостатков:
- Вы больше не можете выражать вызов функции в одной форме. Вам нужно будет передать два отдельных объекта данных, имя функции и список аргументов.
- Это упростит синтаксис - вам потребуются дополнительные правила синтаксиса, чтобы распознать это как вызов функции (например, дополнительные разделители типа "," между аргументами)
- Было бы сложнее создать код. Lisp был разработан с самого начала, чтобы обеспечить эффективное генерирование кода - с другой стороны, если вы когда-либо пробовали генерировать исходный код С++, тогда вы будете знать, как сильно это может быть на языке, не разработанном таким образом.
- Это фактически не уменьшает число круглых скобок в целом. Фактически, из-за очень сжатого языка Clojure обычно заканчивается меньшими скобками, чем эквивалентный код в Java/С#