This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-07-06
Channels
- # announcements (3)
- # biff (13)
- # cider (11)
- # clojure (4)
- # clojure-dev (6)
- # clojure-europe (96)
- # clojure-norway (14)
- # clojure-spec (1)
- # clojure-sweden (1)
- # clojurescript (7)
- # conjure (2)
- # core-logic (2)
- # events (1)
- # hyperfiddle (8)
- # introduce-yourself (9)
- # nbb (12)
- # off-topic (70)
- # pedestal (3)
- # releases (1)
- # squint (2)
- # tools-deps (20)
- # yamlscript (1)
A question on the implementation of clojure.lang.Ref
. Ref
has a field TVal tvals
. TVal
clearly is implemented as a circular, doubly-linked list, via fields next
and prior
A singular object of type TVal
has these fields initialized to point to itself. An inspection of all code touching these two fields seems to confirm that the requirements of a circular, doubly-linked list are maintained.
(BTW, the most fun piece of code is in Ref.trimHistory
where we find tvals.next = tvals; tvals.prior = tval
, discarding the all of the list except the head node itself -- a nice confirmation of the semantics.)
Ref
has two constructors. The one-arg ctor just calls the two-arg ctor. The two-arg ctor initializes the tvals
field to a new Tval(...)
and hence the tvals
field is not null upon construction.
There are a few places in the code (in Ref
but also in LockingTransaction
) that do set the tvals
field, but in each case it is either to a new TVal(...)
or ref.tvals = ref.tvals.next;
. For the latter, given the circular nature, tvals.next
will not be null.
Nevertheless, I count 13 places where ref.tvals
is tested to see if it is null
. Have I missed some situation where tvals
can be null? Is someone running around creating bare Ref
s without using the supplied constructors? are there any other loopholes? Modification to Ref
outside of the Ref
and LockingTransaction
code that I have overlooked.
(This is not idle curiousity -- I'm implementing in a language where if this field can be null
I have to choose among declaring the type as allowing null values, declaring the field to be a nullable reference type, or using an option type. Yes vs no here impacts code design.)
don't know of anything else, but since Ref is a non-final class, something else could subclass it and write this field
maybe it's just defensive for that sake
the only other magic constructor path that springs to mind is serialization, but this isn't serializable
so I think you would be ok making the presumption that its non-null in your impl