1
votes

I am building an application that consumes a file, and produces another file. It's not terribly important what it does, but I want to use core.async; main reason is I want to learn it, but also to be able to make this processing potentially faster on multicore machines.

I want the app to have 2 modes of operation: you can run it from command line, and pass a file on the STDIN, or you can fire up a REPL session, and create your inputs there. I've already used this approach in my Emacs REPL, and I want to be able to use in command-line REPL session.

When run with a file on STDIN, my code creates a channel, creates consumers, and puts the lines unto the channel. When I go interactive, I figured I'll create a channel and bind it to an atom; then there will be an API exposed to add individual messages to the channel, or entire sequences, doesn't matter.

What made me doubt the decision is the absence of examples/articles talking about channel+atom combinations. As if it's not a good pattern. Would anyone be able to provide their opinions? Perhaps I'm just overthinking this =) Sorry about the wall-of-text!

2
Guess you're right. - alexakarpov

2 Answers

2
votes

I can't see any benefit to putting a mutable object in an atom. The purpose of atoms are to act as a mutable container for immutable objects.

I'm guessing you want to hold off initializing the channel, and are reset!ing the atom when it's decided that the channel is needed. While this works, I would consider it an abuse of atoms.

I recommend just using a delay:

(def ch (delay (chan)))

; The chan is initialized here the first time it's dereferenced
@ch

; And the same cached chan is used here
@ch

This frees you up from needing to initialize the atom with nil, then constantly check if the atom has had a channel added to it before using it.

0
votes

A better approach would be to simply eval (def c (chan)) at the REPL. Then you can pass/inspect c as needed, but not alter the structure of your program.

It's not uncommon to find a comment form at the end of a .clj file with helpers intended to be evaluated at the REPL. For example:

(comment
  (def c (chan))
  (do-something-with-c c))