beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
West 2021-03-03T00:43:17.099400Z

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?

alexmiller 2021-03-03T00:55:51.100200Z

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

alexmiller 2021-03-03T00:56:22.100600Z

So, not that useful imo

2021-03-03T01:04:08.100900Z

really great talk on this topic: https://www.youtube.com/watch?v=E8I19uA-wGY

2021-03-03T01:05:10.101100Z

1
2021-03-03T01:48:09.102Z

Can recommend this talk, it got me interested in FP

2021-03-03T01:49:40.103500Z

@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

sova-soars-the-sora 2021-03-03T02:06:07.103700Z

much appreciated thank you

sova-soars-the-sora 2021-03-03T02:09:08.104300Z

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

seancorfield 2021-03-03T02:49:07.105Z

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

seancorfield 2021-03-03T02:50:28.105500Z

I like to point folks to this http://mishadoff.com/blog/clojure-design-patterns/ when they're asking about "classic" design patterns @c.westrom

seancorfield 2021-03-03T02:51:17.105700Z

This is quite a good preso https://www.infoq.com/presentations/Clojure-Design-Patterns/

Eric Ihli 2021-03-03T03:08:10.107200Z

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:
   com.owoga.tightly_packed_trie.core.Trie

          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 Ihli 2021-03-03T03:12:09.108Z

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

popeye 2021-03-03T08:00:00.108100Z

@robertfrederickwarner yeah I used :insecure? to false and it worked for me,

em 2021-03-03T08:08:44.108300Z

I think at this point the can of worms has been fully opened lol Double byte-array + transient for filter output is a neat way to get around the bottlenecks of either approach Curious though, I wonder how close these implementations are getting to bare metal Java solutions

robertfw 2021-03-03T08:10:20.108600Z

set to false? I would have expected it to be set to true to allow insecure certs

popeye 2021-03-03T08:12:46.108800Z

ya sorry, I rechecked it ..i set it to true

robertfw 2021-03-03T08:16:15.109Z

Groovy. Glad that got you off the ground. Just be wary of that :insecure? setting - it does what it says on the tin, and makes things less secure. Fine for development but if you are putting things into production I'd recommend either getting a properly signed cert, or looking into the :keystore options

popeye 2021-03-03T08:16:45.109200Z

yes

Sithabiso Makhathini 2021-03-03T08:25:45.110800Z

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

Sithabiso Makhathini 2021-03-10T09:13:36.188700Z

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.

javahippie 2021-03-10T09:15:46.190300Z

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

javahippie 2021-03-03T08:50:10.110900Z

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

Sithabiso Makhathini 2021-03-03T09:08:43.111100Z

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

javahippie 2021-03-03T09:10:44.111300Z

I see a typo in a namespace in the error:

Sithabiso Makhathini 2021-03-03T09:10:45.111500Z

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

Sithabiso Makhathini 2021-03-03T09:11:28.111700Z

actually I still get the same error

Sithabiso Makhathini 2021-03-03T09:17:12.111900Z

I'm sorry how so?

Sithabiso Makhathini 2021-03-03T09:19:13.112100Z

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

javahippie 2021-03-03T09:24:57.112300Z

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

Sithabiso Makhathini 2021-03-03T09:26:55.112500Z

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

javahippie 2021-03-03T09:40:15.112700Z

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

Karo 2021-03-03T09:55:15.115700Z

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}]

jkxyz 2021-03-03T10:03:30.117400Z

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

1👍
2021-03-04T19:47:04.181300Z

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

2021-03-04T19:47:15.181500Z

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

2021-03-04T19:48:03.181700Z

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

jkxyz 2021-03-05T10:54:00.316100Z

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

Karo 2021-03-03T10:06:03.117900Z

great thank you

Sithabiso Makhathini 2021-03-03T10:09:04.118200Z

I have "messages" as a parameter.

javahippie 2021-03-03T10:10:09.118400Z

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

Sithabiso Makhathini 2021-03-03T10:11:19.118600Z

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

javahippie 2021-03-03T10:13:45.118800Z

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

Sithabiso Makhathini 2021-03-03T10:15:21.119Z

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 Makhathini 2021-03-03T11:01:19.119300Z

hey sorted it out thank you so much

javahippie 2021-03-03T12:48:07.119700Z

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

pez 2021-03-03T14:38:04.121200Z

I think I have lessons gained in my optimizing of the Java-ish solution that I can bring over to my more Clojuresque solutions. Maybe there are at least two classes to this hunt?

grazfather 2021-03-03T15:33:27.121900Z

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)

grazfather 2021-03-04T14:14:14.159600Z

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

vanelsas 2021-03-03T15:38:44.122400Z

Not sure if this is what you are looking for, but deployment to Heroku is pretty straightforward: https://devcenter.heroku.com/articles/getting-started-with-clojure

2021-03-03T15:41:24.123700Z

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.

rwstauner 2021-03-03T15:48:35.123800Z

See also:

sb 2021-03-03T15:53:51.123900Z

I created with golang in the past.. https://github.com/damesek/golang-clojurescript 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

grazfather 2021-03-03T16:07:48.126800Z

Yep, though I already willi have a clojure daemon running

2021-03-03T16:09:50.128200Z

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 🙂

alexmiller 2021-03-03T16:11:18.129200Z

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

alexmiller 2021-03-03T16:12:04.130400Z

map stops when it runs out of a seq input

danielneal 2021-03-03T16:12:16.130700Z

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?

danielneal 2021-03-03T16:12:33.131Z

(imagine there's more layers to the for)

alexmiller 2021-03-03T16:12:52.131600Z

If you want control, use loop recur

2021-03-03T16:13:29.131800Z

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

alexmiller 2021-03-03T16:13:59.132900Z

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

danielneal 2021-03-03T16:14:09.133200Z

Fair point 🙂

danielneal 2021-03-03T16:14:16.133500Z

for is just so nice and readable

alexmiller 2021-03-03T16:15:44.135Z

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

alexmiller 2021-03-03T16:17:52.136700Z

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

grazfather 2021-03-03T18:33:55.137700Z

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

sb 2021-03-03T18:56:38.139600Z

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.

sb 2021-03-03T19:00:02.141700Z

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

pez 2021-03-03T23:36:06.142500Z

Here’s a version of that last loop w/ transients solution, where I parallelize the collection of the sieved indexes.

(defn pez-ba-loop-transient-parallel-sieve [^long n]
  (let [primes (boolean-array (inc n) true)
        sqrt-n (int (Math/ceil (Math/sqrt n)))]
    (if (< n 2)
      '()
      (loop [p 3]
        (if (< sqrt-n p)
          (let [num-slices (if (and (even? n)
                                    (> n 1000))
                             50
                             1)
                slice-size (quot n num-slices)
                futures (mapv (fn [^long slice-num]
                                (future
                                  (let [start (inc (* slice-num slice-size))
                                        end (dec (+ start slice-size))]
                                    (loop [res (transient [])
                                           i start]
                                      (if (<= i end)
                                        (recur (if (aget primes i)
                                                 (conj! res i)
                                                 res)
                                               (+ i 2))
                                        (persistent! res))))))
                              (range num-slices))]
            (concat [2]
                    (drop 1 (into []
                                  (mapcat deref)
                                  futures))))
          (do
            (when (aget primes p)
              (loop [i (* p p)]
                (when (<= i n)
                  (aset primes i false)
                  (recur (+ i p p)))))
            (recur  (+ p 2))))))))
Doesn’t gain me the slightest speed on my machine, though. I don’t quite understand why, because in a more syntetic test I had a 40% speed gain. Maybe on some other machine it makes more difference. In any case, now I sieve through 10M numbers in 70ms on my laptop. Chasing this particular local maxima might not be the way to make real progress.