Core-async transducers with atoms

106 views
Skip to first unread message

Elena Canovi

unread,
Mar 23, 2017, 10:06:26 AM3/23/17
to Clojure

I have a question about transducers in core.async channels.

As far as I understand, if I define a channel with a transducer, the latter cannot depend on any other external argument other than what is put on the former.
So the transducer works in a purely functional fashion.

Here is the question: is it idiomatic to define a transducer which depends (without side-effects) on a globally defined atom?

Consider this example with a chatroom. Suppose we have a set (called banned-users) containing the names of users who have been banned from the chat. Let us initialize banned-users like this:

(def banned-users (atom #{}))

Let us further suppose that this set can change in time with users added and removed asynchronously.
Every user can send messages to the server containing their name and the actual text of the message, in this format:

{:name "John" :text "Hi, friends!"}

Depending on whether the user is banned or not, the server will broadcast their message to all the other users or not. To this aim, let us define a channel with a transducer:

(def server (chan 1 (filter #(not (contains? @banned-users (:name  %) ) )))

As you can see, the effect of the transducer on the input message depends on the current value of banned-users. In other words, the channel does not work in a purely functional way, because given an input message, the result of applying the transducer will depend on the global context.

Is this idiomatic or do you suggest other solutions? Thanks!

Reply all
Reply to author
Forward
0 new messages