de-vraag
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
Matt Fenwick
Matt Fenwick
Вопрос

Послесловие Clojure не выполняется из-за ошибки синтаксиса - почему?

В этой функции:

(defn my-post 
  [a] 
  {:post (number? %)}
  a)

Постословие не выполняется (или, по крайней мере, не вызывает ошибку утверждения). Теперь я знаю, что это должно было быть:

(defn my-post 
  [a] 
  {:post [(number? %)]} ;; note the square brackets around the expression
  a)

На самом деле это работает правильно.

Проблема в том, что это терпело неудачу, и потребовалось некоторое время, чтобы выяснить, что случилось. Нет синтаксических ошибок, исключений во время выполнения.

I would like to understand what Clojure does with this code, in order to understand why Clojure didn't complain. Macro expansions? Destructuring? Does the code just disappear if it doesn't see square braces?

3 2011-10-27T13:42:04+00:00 1
Программирование
clojure
compilation
compiler-errors
compiler-warnings
post-conditions
Brian Carper
27-го октября 2011 в 7:01
2011-10-27T19:01:56+00:00
Дополнительно
Источник
Редактировать
#56789402

http://clojure.org/special_forms documents that the condition-map for fn (thus also defn) should be of the form:

{:pre [pre-expr*]
 :post [post-expr*]}

{:post (number? %)} will result in (number? %) being treated as a sequence of assertions, which means it's interpreted as two separate assertions: number? and %.

user> (macroexpand-1 '(fn [a] {:post (number? %)} a))
(fn*
 ([a]
  (clojure.core/let [% a]
   (clojure.core/assert number?)
   (clojure.core/assert %)
   %)))

(assert number?) always passes as long as number? is defined and has a true value, which being a core function, it probably does. (clojure.core/assert %) passes if % has a true value. It's bound to the value of your argument a via the let, so it passes if a has a true value. Try calling (my-post nil) with your first function definition and it'll fail the assertion.

user> (my-post nil)
; Evaluation aborted.
; Assert failed: %
;  [Thrown class java.lang.AssertionError]

Если вы правильно поместите свое пост-условие в вектор, он будет расширяться следующим образом:

user> (macroexpand-1 '(fn [a] {:post [(number? %)]} a))
(fn*
 ([a]
  (clojure.core/let [% a]
   (clojure.core/assert (number? %))
   %)))
5
0
Похожие сообщества 3
Clojure — русскоговорящее сообщество
Clojure — русскоговорящее сообщество
782 пользователей
Общаемся на темы, посвященный Clojure. Решаем проблемы, обмениваемся опытом и делимся новостями. Вакансии и поиск работы: @clojure_jobs Вам могут быть интересны: @javascript_ru, @nodejs_ru, @ruby_ru, @devops_ru, @devops_jobs
Открыть telegram
Clojure — вакансии и поиск работы
Clojure — вакансии и поиск работы
420 пользователей
Публикуем вакансии и запросы на поиск работы по Clojure. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @javascript_jobs, @mobile_jobs, @devops_jobs, @qa_jobs
Открыть telegram
Clojure Pro
Clojure Pro
171 пользователей
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Roxana Elizabeth CASTILLO Avalos
Зарегистрирован 4 дня назад
2
Hideo Nakagawa
Зарегистрирован 5 дней назад
3
Sergiy Tytarenko
Зарегистрирован 1 неделю назад
4
shoxrux azadov
Зарегистрирован 1 неделю назад
5
Koreets Koreytsev
Зарегистрирован 1 неделю назад
© de-vraag 2022
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией