Fork me on GitHub

Hey guys, I’m looking for a book on design patterns. I found this one: Design Patterns: Elements of Reusable Object-Oriented Software. Of course, it has OO in the title. Is it still useful for a young fledgling clojure dev? What do you guys recommend?

Alex Miller (Clojure team)00:03:51

Most of those patterns can be replaced in Clojure with just using a function

Alex Miller (Clojure team)00:03:22

So, not that useful imo

Thomas Tay01:03:09

Can recommend this talk, it got me interested in FP

Thomas Tay01:03:40

@c.westrom that book is still pretty useful to understand the patterns, but don't try to do it that way in Clojure. I have it and I refer to it occasionally for my day job using Typescript


@c.westrom I believe SICP Structure and Interpretation of Computer Programs is a classic


Not really a "design patterns" book though... but good for FP if you haven't already read it.


I like to point folks to this when they're asking about "classic" design patterns @c.westrom

Eric Ihli03:03:10

I'm getting an error when I modify some code related to a deftype/defprotocol. It works on first load, but after modification, I get:

1. Unhandled java.lang.IllegalArgumentException
   No implementation of method: :as-map of protocol:
   #'com.owoga.tightly-packed-trie.core/ITrie found for class:

          core_deftype.clj:  583  clojure.core/-cache-protocol-fn
          core_deftype.clj:  575  clojure.core/-cache-protocol-fn
I see the error coming from a -cache-protocol-fn. Is there some type of cache that needs to be cleared for deftype/defprotocol reloading in a REPL?

Eric Ihli03:03:09

^ Cancel! Realized I had a defonce instance of the thing I was refactoring... 😳

Sithabiso Makhathini08:03:45

anyone gone through the web-development-with-clojure book and had problems with chapter 5 replacing cljsbuild with shadow-cljs? Getting kicked hard right now


Which edition of the book do you have? Which errors do you get?

Sithabiso Makhathini09:03:43

I have the third edition. I have attached a screenshot of the errors


I see a typo in a namespace in the error:

Sithabiso Makhathini09:03:45

Sorry I just realized I was missing a "src/cljs" source path

Sithabiso Makhathini09:03:28

actually I still get the same error

Sithabiso Makhathini09:03:13

I see it not, sorry I managed to fix the typo and looks like I have a couple more issues


Oh, I meant’ “geustbook” instead of “guestbook”. Did the error messages change?

Sithabiso Makhathini09:03:55

Thank you so much I'm just getting warnings now that I am worried about


It seems like get-messages requires a parameter, and your code calls it without one

Sithabiso Makhathini10:03:04

I have "messages" as a parameter.


The error messages show different code. Maybe you have not saved the file?

Sithabiso Makhathini10:03:19

It is only when I remove the parameter that the warning goes away


Does the app work as expected, it’s just the warnings?

Sithabiso Makhathini10:03:21

Yes when I open the app on port 3000 is works just fine, I was just worried that the warnings have introduced an issue into the app. I am yet to open the app on port 7002

Sithabiso Makhathini11:03:19

hey sorted it out thank you so much


Good to hear 🙂 What did you change to sort it out?

Sithabiso Makhathini09:03:36

Hey so sorry for only getting back to you now, I had another typo, instead of rf/drispatch it should have been rf/dispatch and lastly I didn't need a namespace.


Thanks for your answer 🙂 For catching typos, I recommend using clj-kondo in your configuration, makes a huge difference 😉


Hi team, how can I delete maps in vector? for example how can I delete a map if :name is "a" or "c" from given vector want to get

{:name "b" :age 23}
in the result.
[{:name "a" :age 32} {:name "b" :age 23} {:name "c" :age 23}]


(vec (filter #(contains? #{"a" "c"} (:name %)) [{:name "a"} {:name "b"} {:name "c"}])) @vnazaryan

👍 3

great thank you


I'd write that as (into [] (filter (comp #{"a" "c"} :name)) [...])


(does the same thing slightly faster and I find it clearer)


oh, you need remove rather than filter if "b" is the only one you want (or change the set literal to #{"b"} )


My bad 🙂 I misread the desired result. (comp #{,,,} :some-key) is a common pattern but I figured contains? is more explicit if you don’t know that sets and keywords can be used as fns


What’s a simple static file server in clojure? I want to move from local hosting my oz viz to exporting to html and server more widely (to my LAN)


Not sure if this is what you are looking for, but deployment to Heroku is pretty straightforward:


I created with golang in the past.. if you have exported html/js version. Quite ok, I didn’t implement the ‘faster go http server’ (fasthttp) but you can shutdown the clojurescript process gracefully


Naw, I want to host on my raspberry pi. Basically my Pi is taking various measurements of sensors and shoving it in a DB. I use oz to display it, but it normally opens a websocket to the front end which is on localhost. I want to make a bit of a dashboard


You can compile to Raspberry PI with my solution, with To build it for the Raspberry Pi, we use: env GOOS=linux GOARCH=arm GOARM=7 go build. command. i think you could do with that, eg what you can with shadow-cljs. I updated a little bit the repo, maybe in this way could be helpful.


You can create w/ V8 cli apps too, or with Babashka/ Graalvm.


yeah there are tons of ways, I was actually already in the thread, but I figured I’d host within the same JVM process that I am using to collect the data. Looks like oz export needs node, though, so maybe I’ll just host with node


Honestly, for purely local, static stuff, it's hard to beat just typing python -m http.server <port> at the command line in the dir you want to publish. If you don't need to make API calls to a Clojure backend and are just serving static files, that's the route I'd go.


Yep, though I already willi have a clojure daemon running


One really cool thing I like about Clojure's built-in map function is that you can pass it multiple lists. As it maps through, it will take the nth item from each list and pass it to your function:

(def vector-one ["hello " "goodbye "])
(def vector-two ["friend" "buddy"])
(map (partial apply str) vector-one vector-two)
; -> ("hello friend" "goodbye buddy")
Does anyone have a good method for achieving this when the lists are "unbalanced"? For example:
(def vector-one ["hello " "goodbye "])
(def vector-two ["friend"])
(map (partial apply str) vector-one vector-two)
; -> ("hello friend" "goodbye friend")
I think there might be some murky things lurking underneath the surface of that idea which make it tricky to implement, but I'll put it out there anyway 🙂

Alex Miller (Clojure team)16:03:18

Use an infinite sequence of “friend” for vector-two


Here comes the next step in building up my "Clojure brain." Great suggestion, thank you!

Alex Miller (Clojure team)16:03:44

A common pattern for initializing maps is to zipmap finite keys with (repeat 0) or whatever the initial value is (similar idea)

Alex Miller (Clojure team)16:03:52

(def scores (zipmap [“Joe” “Anna”] (repeat 0)))

Alex Miller (Clojure team)16:03:04

map stops when it runs out of a seq input


What's the best way to do this sort of thing (first (for [i items j (expensive-fn i) :when (pred j)] j)) without computing expensive-fn unnecessarily due to chunking? Is there an unchunked version of for?


(imagine there's more layers to the for)

Alex Miller (Clojure team)16:03:52

If you want control, use loop recur

Alex Miller (Clojure team)16:03:59

In general, if you care about exactly how many things get evaluated, you should not be using lazy seqs


Fair point 🙂


for is just so nice and readable