Skip to content

Commit a3ed183

Browse files
authored
Add reset-vals! and swap-vals! for atoms (#399)
1 parent 764449d commit a3ed183

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

src/basilisp/core.lpy

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,12 +714,37 @@
714714
v
715715
(recur atom v))))
716716

717+
(defn reset-vals!
718+
"Reset the value of an atom to v without regard to the previous value.
719+
Return a vector containing the new value and the old value in that order."
720+
[atom v]
721+
(let [current (deref atom)]
722+
(if (compare-and-set! atom current v)
723+
[v current]
724+
(recur atom v))))
725+
717726
(defn swap!
718727
"Atomically swap the value of an atom to the return value of (apply f
719728
current-value args). The function f may be called multiple times while
720729
swapping, so should be free of side effects. Return the new value."
721730
[atom f & args]
722-
(apply basilisp.lang.runtime/swap atom f args))
731+
(let [current (deref atom)
732+
new-val (apply f current args)]
733+
(if (compare-and-set! atom current new-val)
734+
new-val
735+
(recur atom f args))) )
736+
737+
(defn swap-vals!
738+
"Atomically swap the value of an atom to the return value of (apply f
739+
current-value args). The function f may be called multiple times while
740+
swapping, so should be free of side effects. Return a vector containing
741+
the new value and the old value in that order."
742+
[atom f & args]
743+
(let [current (deref atom)
744+
new-val (apply f current args)]
745+
(if (compare-and-set! atom current new-val)
746+
[new-val current]
747+
(recur atom f args))))
723748

724749
(defn atom
725750
"Return an Atom containing v. The value of an Atom at any point in time

src/basilisp/lang/runtime.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -934,13 +934,6 @@ def deref(o, timeout_s=None, timeout_val=None):
934934
raise TypeError(f"Object of type {type(o)} cannot be dereferenced")
935935

936936

937-
def swap(a: Atom, f, *args):
938-
"""Atomically swap the value of an atom to the return value of (apply f
939-
current-value args). The function f may be called multiple times while
940-
swapping, so should be free of side effects. Return the new value."""
941-
return a.swap(f, *args)
942-
943-
944937
def equals(v1, v2) -> bool:
945938
"""Compare two objects by value. Unlike the standard Python equality operator,
946939
this function does not consider 1 == True or 0 == False. All other equality

tests/basilisp/runtime_test.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,16 +270,6 @@ def test_deref():
270270
runtime.deref(vec.Vector.empty())
271271

272272

273-
def test_swap():
274-
assert 3 == runtime.swap(atom.Atom(1), lambda x, y: x + y, 2)
275-
assert vec.v(1) == runtime.swap(
276-
atom.Atom(vec.Vector.empty()), lambda v, e: v.cons(e), 1
277-
)
278-
279-
with pytest.raises(AttributeError):
280-
runtime.swap(1, lambda x, y: x + y, 2)
281-
282-
283273
class TestToPython:
284274
def test_literal_to_py(self):
285275
assert None is runtime.to_py(None)

0 commit comments

Comments
 (0)