openlang

Есть ли в Clojure разница между defn- и объявлением функции с ^:private?

Оба варианта, похоже, объявляют закрытую функцию, как в большинстве объектно-ориентированных языков. Поведение различается или один вариант лишь синтаксический сахар?

Я встречал defn ^:private в коде обработчика приложения ring.

Переведено с английскогоПоказать оригинал

Разговор продолжается 2

Следуя доводам
  1. Ссылка на ответ

    Макрос defn- просто сокращает объявление "закрытой" функции. Полная запись выглядит так:

    
    (defn ^:private entry [inputs] ...)

    На деле это лишь сигнал пользователям не обращаться к таким функциям. Обойти эту ограниченную "закрытость" для тестов и подобных задач несложно. Из-за неудобств я избегаю так называемых "закрытых" функций (иногда добавляю метаданные ^:no-doc и выбираю имена вроде entry-impl, чтобы показать, что fn не входит в публичный API и пользователям библиотеки стоит её игнорировать).

    Подробности можно увидеть в определении defn- в исходниках Clojure (https://github.com/clojure/clojure/blob/38bafca9e76cd6625d8dce5fb6d16b87845c8b9d/src/clj/clojure/core.clj#L4925).

    Переведено с английскогоПоказать оригинал
  2. Ссылка на ответ

    Если отвечать на исходный вопрос: они эквивалентны.

    
    user=> (defn- first_fn [value] value)
    #'user/first_fn
    user=> (defn ^:private second_fn [value] value)
    #'user/second_fn
    user=> (meta #'first_fn)
    {:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name first_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "user"]}
    user=> (meta #'second_fn)
    {:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name second_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "user"]}
    user=> (source defn-)
    (defmacro defn-
      "same as defn, yielding non-public def"
      {:added "1.0"}
      [name & decls]
        (list* `defn (with-meta name (assoc (meta name) :private true)) decls))
    nil
    user=>

    Из реализации defn- видно, что он ведёт себя точно как defn, к символу name которого добавлены метаданные :private true.

    Переведено с английскогоПоказать оригинал

Другие стороны того же вопроса

  1. Как случайно выбирать варианты enum в GDScript на Godot 3.3, не перечисляя их?

    Вот объявление enum, которое я использую в GDScript: Хочу случайно выбирать вариант enum, не перечисляя все возможные вариант…

    Ответы 2Последняя активность gdscript
  2. Синтаксис остатка в Nim

    Как в Nim записать операцию взятия остатка? cell % 7 == 0 выдаёт undeclared identifier: '%' Ни поиск в Google, ни просмотр SO…

    Ответы 2Последняя активность nim
  3. Возврат результата из функции APL

    Как сделать так, чтобы моя функция возвращала значение после завершения выполнения? Например, у меня есть: ROUTINE N ? N ⍴ 12…

    Ответы 2Последняя активность apl