Skip to content

Commit

Permalink
Add reset-vals! and swap-vals! for atoms
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisrink10 committed Jun 8, 2019
1 parent 764449d commit 79f8acf
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
27 changes: 26 additions & 1 deletion src/basilisp/core.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -714,12 +714,37 @@
v
(recur atom v))))

(defn reset-vals!
"Reset the value of an atom to v without regard to the previous value.
Return a vector containing the new value and the old value in that order."
[atom v]
(let [current (deref atom)]
(if (compare-and-set! atom current v)
[v current]
(recur atom v))))

(defn swap!
"Atomically swap the value of an atom to the return value of (apply f
current-value args). The function f may be called multiple times while
swapping, so should be free of side effects. Return the new value."
[atom f & args]
(apply basilisp.lang.runtime/swap atom f args))
(let [current (deref atom)
new-val (apply f current args)]
(if (compare-and-set! atom current new-val)
new-val
(recur atom f args))) )

(defn swap-vals!
"Atomically swap the value of an atom to the return value of (apply f
current-value args). The function f may be called multiple times while
swapping, so should be free of side effects. Return a vector containing
the new value and the old value in that order."
[atom f & args]
(let [current (deref atom)
new-val (apply f current args)]
(if (compare-and-set! atom current new-val)
[new-val current]
(recur atom f args))))

(defn atom
"Return an Atom containing v. The value of an Atom at any point in time
Expand Down
7 changes: 0 additions & 7 deletions src/basilisp/lang/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,13 +934,6 @@ def deref(o, timeout_s=None, timeout_val=None):
raise TypeError(f"Object of type {type(o)} cannot be dereferenced")


def swap(a: Atom, f, *args):
"""Atomically swap the value of an atom to the return value of (apply f
current-value args). The function f may be called multiple times while
swapping, so should be free of side effects. Return the new value."""
return a.swap(f, *args)


def equals(v1, v2) -> bool:
"""Compare two objects by value. Unlike the standard Python equality operator,
this function does not consider 1 == True or 0 == False. All other equality
Expand Down
10 changes: 0 additions & 10 deletions tests/basilisp/runtime_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,16 +270,6 @@ def test_deref():
runtime.deref(vec.Vector.empty())


def test_swap():
assert 3 == runtime.swap(atom.Atom(1), lambda x, y: x + y, 2)
assert vec.v(1) == runtime.swap(
atom.Atom(vec.Vector.empty()), lambda v, e: v.cons(e), 1
)

with pytest.raises(AttributeError):
runtime.swap(1, lambda x, y: x + y, 2)


class TestToPython:
def test_literal_to_py(self):
assert None is runtime.to_py(None)
Expand Down

0 comments on commit 79f8acf

Please sign in to comment.