2013-06-06 4 views
2

Мне было любопытно, поэтому я проверил исходный код свопа! функция на репозитории Clojure, и это было так:Что такое «.swap» в «swap!» исходный код?

(defn swap! 
    "Atomically swaps the value of atom to be: 
    (apply f current-value-of-atom args). Note that f may be called 
    multiple times, and thus should be free of side effects. Returns 
    the value that was swapped in." 
    {:added "1.0" 
    :static true} 
    ([^clojure.lang.Atom atom f] (.swap atom f)) 
    ([^clojure.lang.Atom atom f x] (.swap atom f x)) 
    ([^clojure.lang.Atom atom f x y] (.swap atom f x y)) 
    ([^clojure.lang.Atom atom f x y & args] (.swap atom f x y args))) 

И я не знаю, что такое «.swap» функция делает? Я попытался найти его, но он не определен в том же файле, поэтому не может найти его определения. Или это еще одна особенность, которая на самом деле не является функцией вообще?

+2

[Кодовые части вы хотели] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java#L33). Как вы могли бы извлечь из подсказок типа, они находятся в clojure.lang.Atom (вы можете немного прокрутить список - есть несколько перегрузок .swap). –

+1

, если вам интересно, вот перегрузки swap https://github.com/clojure/clojure/blob/8fda34e4c77cac079b711da59d5fe49b74605553/src/jvm/clojure/lang/Atom.java#L33 – Shlomi

ответ

5

В Clojure выражение (.x object a b c) приводит к вызову метода, который в Java будет отображаться как object.x(a, b, c). Для получения дополнительной информации см. Java Interop.

В данном конкретном случае функция swap! вызывает надлежащим образом перегруженный метод swap экземпляра clojure.lang.Atom, переданного в качестве первого аргумента. Метод swap содержит фактическую логику, выполняющую своп.

+0

Спасибо, теперь весь код имеет для меня полный смысл! –

6

Много вещей в Clojure фактически реализованы в Java, как ссылочные типы (атом, реф, вар, агент), структуры данных (карта, вектор, список, набор), пространства имен (фактическое Namespace класс) и другие вещи. При чтении исходного кода для Clojure функции в clojure.core не редко можно найти вызов interop для метода Java.

Это мое понимание того, что есть долгосрочная цель, чтобы реализовать эти вещи в Clojure сам (поиск here для Clojure в-Clojure), но сейчас эти вещи реализованы в Java, которая на самом деле не так плохо, поскольку весь язык является открытым исходным кодом, и вы можете проверить любую информацию о реализации онлайн в github repo (уже связанную в комментарии): Clojure (обратите внимание, что есть jvm и clj папка, указывающая, на каком языке реализован код внутри) ,

+0

Не знал, что даже атом реализован в Java. Хотя другой ответ - именно то, что я хотел, ваш ответ позволил мне узнать и новую вещь, спасибо! :-) –

+0

Я рад, что это помогло :) –

0

Проще говоря, атом является sth. который находится под контролем транзакционной памяти. (Прочитайте о STM, пожалуйста.) Это невозможно для своих наблюдателей (разыменование атома возвращается в нестабильное состояние с момента дешифрования), но может быть мутировано транзакционно. Это именно то, что своп! делает. Он транзакционно меняет прежнее значение для нового значения. Обратите внимание, что это очень отличается от назначения. Назначение небезопасно для параллелизма.

Иными словами, атом работает как ячейка в таблице базы данных. Когда вы запрашиваете его, у вас будет значение, а не исключение, даже если в тот же момент другой запрос обновляет его.

Приветствия -

+0

Ну, думаю, я не сформулировал свой вопрос так, что многие прекрасные ребята попытались объяснить обмен!и атом :-) Я искал своп! фактический исходный код функции, чтобы проверить, есть ли обмен! ведет себя так, как описано в моей книге ... тогда я увидел «.swap» в исходном коде swap !, я не знал «.swap», поэтому я не мог понять код, теперь я вижу, что это java метод call lol. Но я действительно читал о STM & ref & atom, прежде чем публиковать вопрос. –