Ответ на ваш прямой вопрос заключается в том, что при вызове функции не возникает никаких накладных расходов просто потому, что эта функция имеет несколько элементов. В Clojure все вызовы функций компилируются в вызов метода. Точный вызываемый метод зависит от количества аргументов — что касается JVM, каждая арность компилируется как отдельный метод. Определение того, какой метод вызывать, производится во время компиляции, поэтому во время выполнения нет накладных расходов.
При этом есть некоторые накладные расходы на выполнение вложенных вызовов функций. В частности, каждый вызов увеличивает стек вызовов на постоянную величину, пока этот вызов не вернется. Однако эти накладные расходы минимальны и вряд ли окажут ощутимое влияние на производительность в данном случае.
@ToniVanhala Сначала я сделал let, но друг сказал, что let это плохо и не функционально (он разработчик erlang), я новичок в функциональных языках ... другое, что он сказал, это то, что это странно, что clojure не без стека
Кажется, это настоящий вопрос. Так что стоит заняться этим.
let
— это просто выражение, которое позволяет нам привязывать значения к переменным. Эти привязки неизменны. Кроме того, хорошо известно, что let
можно реализовать как макроабстракцию над лямбдой (или, в словаре Clojure, fn
). Так что в let
нет ничего такого, что делало бы его «нефункциональным».
Также нет ничего «странного» или загадочного в том, что Clojure не является бесстековым. Clojure — это язык JVM, и стек вызовов глубоко встроен в абстрактную вычислительную модель JVM. Хотя есть способы обойти это (например, стиль передачи продолжения), эти методы требуют либо отказа от глубокого взаимодействия с JVM, либо снижения производительности. Clojure — это в первую очередь прагматичный язык, и это прагматичная уступка.
Кроме того, Clojure (будучи Лиспом) на самом деле является языковой структурой, с помощью которой вы создаете язык, который хотите. Ваш язык может пойти на разные компромиссы. Например, ваш язык может быть "stackless". Или он может иметь первоклассные продолжения (отказ от ответственности: я автор pulley.cps
) . Или у него может быть совершенно другая парадигма (например, логика против функциональности). Но это также может быть очень просто. С Clojure вы можете выбирать, за что платить.
Как ни странно, ваш друг прав в том, что код не работает. Однако это не из-за let
. Скорее, почти все, кроме let
, не работает. Например, (save company options)
явно является побочной операцией. Однако это не обязательно означает, что ваш код плохой — даже самая чистая функциональная программа должна в какой-то момент взаимодействовать с реальным миром, если она хочет иметь какую-либо практическую ценность.
person
Nathan Davis
schedule
19.08.2017