Fork me on GitHub
#clojuredesign-podcast
<
2019-11-25
>
ScArcher14:11:21

I really enjoy your podcast and I'm excited about learning / applying Clojure! I just listened to your latest podcast and I'm a beginner in the midst of learning Clojure while attempting to solve a real-world problem. I'm struggling a bit with finding examples of how I should structure my program. The program should be simple. I'm connecting to a server via TCP Socket and receiving string messages terminated by newline. When I receive a message, I need to parse it into a Clojure map, then based on the type of message, I would perform some action, then return a message to be written to the socket, or return nil if I don't need to write a message. I'm really struggling with where responsibilities should live and where or how to manage the state of the connection. Right now I'm passing around a map

{:socket socket :in input-stream-reader :out writer :config config}
While this works, it gets pretty ugly. I like the idea of a pipeline of sorts that could receive the messages and handle them, but what I'm currently doing doesn't feel right. I've looked into the Clojure server source code for examples, but it uses some things I don't understand (dynamic + binding + some dynamic function lookup) I also have some additional side-effects, I'd like to keep at the edge of the program as well. I need to make an authentication call at some point to retrieve a bearer token to login. I'll need to make a few web service calls in order to build some of the return messages that will be written to the socket. I have all of this working right now, but it still feels complex and I'm not seeing the benefits of Clojure that I hear so much about. I'm confident it's due to my lack of knowledge of how to apply the language properly in these situations. As far as topics for the podcast go, I'd love to hear more about how to practically apply a lot of the principals that make Clojure so great.

spfeiffer15:11:55

@scott.archer This surely sounds like you are not exploiting idiomatic Clojure (yet). But without looking at code, it might be hard to give helpful directions.

spfeiffer16:11:26

Putting ina gist/Github repo would be nice. From whnt you described i had the feeling that this is similar to the tic-tac-toe and twitter client examples discussed in the podcast

ScArcher16:11:57

I'll move it to a github repo. Thanks!

ScArcher16:11:32

Is the source code for the twitter or tic-tac-toe example available somewhere?

nate17:11:37

Hey @scott.archer, unfortunately for that series, we only talked about the code

nate17:11:53

we didn't get a chance to make code available

nate17:11:18

we've used that pattern several times to good effect in non-open-source code

ScArcher17:11:23

I listened to it. I think that's the difference in hearing and seeing.

nate17:11:30

I don't know of any examples of it in the wild

nate17:11:43

I'm hoping I can release something soon

ScArcher17:11:14

I'm going to step back and put a "simple socket server" and "simple socket client" on github and see if I can solicit feedback / help based on that code.

nate17:11:18

I definitely understand the difference. There is nothing like being able to explore code.

nate17:11:42

cool, I'll take a look at your code and see what I can offer as feedback

ScArcher17:11:46

Other pointed me towards the server.clj in clojure and it was very helpful.

ScArcher17:11:11

At this point, I'm about convinced that the best way to learn Clojure is reading Clojure code.

ScArcher17:11:41

My app is working just fine, it's just not good 🙂

ScArcher17:11:20

I appreciate your podcast! I started listening recently and have been working through the backlog of episodes. I did listen to the latest one and it sums up why I want to learn Clojure.

spfeiffer17:11:32

When you google „clojure design podcast github“ you'll find code based on the discussions in the podcast. I cannot say anything about the quality of said code, though.

ScArcher17:11:00

I searched that exact term in duck duck go and came up empty 🙂 google is more helpful!

ScArcher17:11:13

Not "empty" but not with the same result

lodin20:11:03

@scott.archer If your program does a lot of IO and you need the result from the IO operation to continue and the logic in-between is simple, then you essentially have an imperative program. I don't think this is the kind of program that shows the benefit of Clojure or FP in general. I would guess that the code might be at least as nice if written in e.g. Python. Another way of phrasing that is that if what you have is essential complexity, then that's what you have and it won't get nicer in pure FP. What you might find to be nicer with pure FP is the level of accidental complexity, and that will reveal itself when the program's logic grows.

ScArcher20:11:29

Thanks @lodin.johan I've found that parts of the application are really nice with Clojure. The messages going into and out of the socket are easily transformed into maps, which makes it really easy to work with. I was looking at potentially using a finite state machine to handle the messages, but I'm not sure how well that approach will work. I'm probably just trying to use too many things I've heard about in this application.

lodin20:11:50

@scott.archer Why not add some core.async go blocks to the mix then. 😉