Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Refs, agents, atoms by

I’m porting a JS library to clojure (and, potentially cljs), and I’m struggling with reasoning about local state. Imagine a scenario where you do RPC over websockets, and the server reply contextually depend on what the server had already sent you. You'd want to keep a local cache of the replies from the server, then.

In OOP world it's expected you incapsulate both the socket and the cache and provide the library users an interface that sends RPCs and transparently handles the cache population and pulling results from it. What would be the ideomatic way to do the same in clojure[-script]? Would I just return a map and expect my functions to take it as a first argument, returning the update state along with the rpc result?

2 Answers

0 votes
by
selected by
 
Best answer

Yes, make state explicit, passed as arguments. Don't use global state. Don't use dynamic vars either. Don't assume a specific state framework such as Integrant or Component.

This way consumers will have the most flexibility and simplicity.

0 votes
by

Nothing's wrong with the way you'd approach it in JS. It's similar to how e.g. any stateful transducer works.

by
I guess my concern there is if I return the whole state to the library user to store in e.g. the application-local atom, then it becomes really non-trivial to manage bits of that state transparently within the library (e.g. reacting to the websocket closure and transparently reconnecting, without having it handled by the external API). Insofar I found it reasonably easy to just internalize the library state in an atom within the library's own namespace, but that, of course, limits the RPC client to exactly one "instance".
by
Yes, there's no need to expose the state that's meant to be internal. And it doesn't limit anything if you make the state a part of a client. When you use a stateful transducer, it's not limited to a single instance at a time - the state is created every time you create a transducer.
Welcome to Clojure Q&A, where you can ask questions and receive answers from members of the Clojure community.
...