В clojure 1.1 все вызовы были динамическими, что означает, что вы можете переопределить функцию в REPL, и она будет автоматически включена в работающую программу.Это было также хорошо для таких вещей, как dotrace.
В clojure 1.2 многие вызовы кажутся статически связанными, и если я хочу заменить функцию, иногда мне приходится находить все места, где она вызывается, и помещать#' перед ними.
Хуже того, я не могу предсказать, где мне нужно будет это сделать.
Можно ли вернуться к старым настройкам динамического связывания по умолчанию?Возможно, если вам нужна дополнительная йота скорости, вы можете включить ее снова для производственного приложения, но для разработки я очень предпочитаю поведение 1.1.
Я надеюсь на какой-то вариант компилятора, такой как * warn-на отражение *.
Редактировать:
Я не понимаю, что происходит.Более конкретно, здесь есть две функции.Я предпочитаю поведение второго.Как я могу заставить первый вести себя как второй, как я полагаю, что это было в 1.1?
user> (clojure-version)
"1.2.0"
user> (defn factorial[n] (if (< n 2) n (* n (factorial (dec n)))))
#'user/factorial
user> (require 'clojure.contrib.trace)
user> (clojure.contrib.trace/dotrace (factorial) (factorial 10))
TRACE t1670: (factorial 10)
TRACE t1670: => 3628800
user> (defn factorial[n] (if (< n 2) n (* n (#'factorial (dec n)))))
#'user/factorial
user> (clojure.contrib.trace/dotrace (factorial) (factorial 10))
TRACE t1681: (factorial 10)
TRACE t1682: | (factorial 9)
TRACE t1683: | | (factorial 8)
TRACE t1684: | | | (factorial 7)
TRACE t1685: | | | | (factorial 6)
TRACE t1686: | | | | | (factorial 5)
TRACE t1687: | | | | | | (factorial 4)
TRACE t1688: | | | | | | | (factorial 3)
TRACE t1689: | | | | | | | | (factorial 2)
TRACE t1690: | | | | | | | | | (factorial 1)
TRACE t1690: | | | | | | | | | => 1
TRACE t1689: | | | | | | | | => 2
TRACE t1688: | | | | | | | => 6
TRACE t1687: | | | | | | => 24
TRACE t1686: | | | | | => 120
TRACE t1685: | | | | => 720
TRACE t1684: | | | => 5040
TRACE t1683: | | => 40320
TRACE t1682: | => 362880
TRACE t1681: => 3628800
3628800
Правка (ко всему вопросу и смена заголовка):
Джуст отмечает ниже, что на самом деле здесь происходит то, что самовызов в факториале оптимизируется.Я не могу понять, почему это будет сделано, так как вы не можете сделать так много рекурсивных самостоятельных вызовов, не взорвав стек, но это объясняет наблюдаемое поведение.Возможно, это как-то связано с анонимными самостоятельными вызовами.
Первоначальная причина моего вопроса заключалась в том, что я пытался написать http://www.learningclojure.com/2011/03/hello-web-dynamic-compojure-web.html,, и меня раздражало количество мест, которые мне приходилось вводить #чтобы получить поведение, которое я ожидал.Это и дотрас заставили меня думать, что общее динамическое поведение ушло и что переопределение на лету, которое работает в некоторых местах, должно быть сделано с некоторым умным взломом.
В ретроспективе это кажется странным выводом, к которому я могу прийти, но теперь я просто растерялся (что лучше!).Есть ли ссылки на все это?Я хотел бы иметь общую теорию о том, когда это будет работать, а когда нет.