Я хотел бы смочь определить лямбды с помощью синтаксиса языка Common LISP в Clojure. Например:
(lambda (myarg)
(some-functions-that-refer-to myarg))
Это должно привести к тому же как:
#(some-functions-that-refer-to %)
В моем случае я знаю, что у меня всегда будет точно один аргумент, настолько возможно, который упрощает вещи. (Но это можно назвать чем-либо - "myarg" или что бы то ни было.)
Я подозреваю, что осуществимое решение к" (defmacro лямбда... ". Если так, я не уверен в лучшем способе продолжиться. Как чисто перевести имя аргумента к %? И как закончить с корректной функцией?
Или, есть ли простое решение, чем запись моего собственного макроса, который на самом деле повторно реализует Clojure... лямбда?
# (foo%)
- это просто сокращение для (fn [arg] (foo arg))
. Нет причин писать макрос, который раскрывается в # (...)
. Все %
в конструкции # (...)
в любом случае сразу же расширяются в генсимы.
user> `#(foo % %1 %2)
(fn* [user/p1__1877 user/p2__1878]
(user/foo user/p1__1877 user/p1__1877 user/p2__1878))
Если вы когда-либо пишете макрос, который расширяется для построения анонимных функций, вы можете просто расширить его до форм fn
. В вашем случае вам, вероятно, следует просто использовать fn
напрямую и пропустить макросы. fn
- это лямбда Clojure
.
Разница между (fn [] ...)
и (lambda () ...)
в этом случае состоит в том, что «fn» короче для ввода, чем «lambda». ", а fn
принимает вектор для своих привязок, тогда как lambda
принимает список. Если вы используете Clojure, вам в конце концов придется к этому привыкнуть, потому что векторы всегда используются для коллекций привязок, во всех формах do
и в для
и ] binding
и т. д. Причина этого, насколько я понимаю, в том, что списки используются для вызовов функций или макросов, а векторы используются для вещей, которые не являются вызовами (например, списки символов для привязки). Возможно, это упрощает визуальное сканирование кода, чем использование списков до конца. Clojure - это не Common Lisp, и вы испытаете боль, если попытаетесь заставить его быть.
Если вы действительно, действительно хотели это сделать, просто скажу, что вы это сделали:
user> (defmacro lambda [args & body]
`(fn ~(vec args) ~@body))
user> ((lambda (x) (println x)) "foo")
foo
nil
Это не позволяет вам, помимо прочего, помещать в функцию строку документации или метаданные.Я не думаю, что вы захотите использовать это в реальной программе Clojure.