Fork me on GitHub
David Pham06:10:50

I would be interested into moving to tech. My background is from mathematics/statistics and I wondered if there was any book teaching how to solve algorithmic problems but on a playful manner. Something like many problems that you should be able to solve using ideas more than just coding endlessly?

David Pham06:10:38

Something similar to project Euler, but less brutal for beginners? :)


Maybe 4clojure or clojure-koans

💯 8

@neo2551 I haven't read this myself, but it looked interesting to me: SICP might be worth going through as well.

🙂 4

With Clojure, you should find that most ideas are expressed succintly. If you find yourself debugging endlessly, maybe your ideas weren't as clear as they should have been originally, and you may find the debugging process helpful to clarify them. Or you may need to step back and rethink.


(which I also haven't read but looked interesting)

David Pham07:10:29

These are great suggestions. I was more looking in a book that was presenting the material in the other direction than usual: first show problems, and then present some common algorithms that could be applied in several areas (like divide and conquer as a concept, or dynamic programming).


You might be interested in something like Concrete Mathematics, which provides algorithmic solutions for math problems. It’s really light on the actual coding part though so I would suggest supplementing the book with coding exercises or another book.

David Pham07:10:31

But I did 4-Clojure and Clojure koans, what i miss is a bit of an overview of the common algorithmic patterns (if this means anything) to solve problems.


Once you know how to solve some kinds of problems, the next trick is to learn how to see real problems as instances of those problems. Quite a lot of problems turn out to be graph traversals or spans, for example.


Rereading your question... there's always Knuth

David Pham07:10:44

But thanks I will start with the grokking algorithm.


Is there any way to make clj -Spom to include paths from :extra-paths ? Another one, how to invoke deps.edn with clj in a certain path (not cwd)?

Sam White10:10:47

Hi, I frequently see “NO_SOURCE_FILE” printed in my clojure logs, could anyone tell me what this means and how I might prevent this?


When you type forms into a REPL (or sends forms to the REPL), it doesn't really come from any file, which the logs reflect. Is this happening while using the REPL, or while running the program?

Sam White10:10:22

This happens while running the program

Abhinav Sharma13:10:32

Hi guys, I think I’m missing some conceptual knowledge about the reduce function. Individually pieces here seem to work but together, my reduce function fails to return a map with {:d {1 {:value 42}}

    (fn [new-map [a-path a-value]]
      (if-not (coll? a-value)
        (assoc-in new-map a-path a-value)))
    {[:d 1 :value] 42,
     [:top-tm]     [[:d 1] [:b 1]]})

Could anyone point out what I’m missing or doing wrong here please 🙂


@abhi18av the if-not is returning nil when the condition is met, so the new-map on next iteration is nil


(if-not (coll? a-value)
        (assoc-in new-map a-path a-value))
Should work

👍 4
Abhinav Sharma13:10:08

Hi @U6CN6JQ22, thanks for the quick response. Let me try this out

Abhinav Sharma13:10:51

Hmm, unless there’s a parens issue, still a nil

    (fn [new-map [a-path a-value]]
      (if-not (coll? a-value)
        (assoc-in new-map a-path a-value)
    {[:d 1 :value] 42,
     [:top-tm]     [[:d 1] [:b 1]]}))

Abhinav Sharma13:10:29

Yup, got it working. The issue was with the parens ( not on a good text editor right now) - Thanks @U6CN6JQ22


@abhi18av Just a style point... I know this might be a toy example but separating the collection filter and value might make it easier to grok. Like this:

(->> {[:d 1 :value] 42
      [:top-tm]     [[:d 1] [:b 1]]}
     (remove (fn [[_ v]] (coll? v)))
     (reduce #(apply assoc-in % %2) {}))
Here we've separated removing non-coll items, but introduced apply which comes with some performance overhead and makes it less clear because %2 will only ever contain two things, so we can do:
(->> {[:d 1 :value] 42
      [:top-tm]     [[:d 1] [:b 1]]}
     (remove (fn [[_ v]] (coll? v)))
     (reduce #(assoc-in % (first %2) (second %2)) {}))
That's clearer but here %2 is always a key-val pair and using first and second goes through the seq abstraction, coming with some overhead of itself. Enter key and val:
(->> {[:d 1 :value] 42
      [:top-tm]     [[:d 1] [:b 1]]}
     (remove #(coll? (val %)))
     (reduce #(assoc-in % (key %2) (val %2)) {}))


That being said, of course, all this is my subjective opinion, and YMMV.

Abhinav Sharma15:10:25

Thanks @U883WCP5Z for being so clear in your explanation man! This way of thinking does seem more idiomatic parens


skykanin [9:40 PM] So I wrote a spec for this function which checks if the input argument is a vector or list and checks if the length is greater than 2. For some reason when I call the function with valid input arguments the spec assertion that (> (count %) 2) fails. What am I doing wrong here?

Kailash K19:10:26

(s/valid? (s/and #(s/or :vector? (vector? %) :list? (list? %)) #(> (count %) 2)) [1] => false

Abhinav Sharma11:10:34

A bit of a side-question @nicholas.jaunsen, how did you put in this kind of code? I mean I’m only aware of the triple backtip notation


There is a button for text/code snippets @abhi18av


@nicholas.jaunsen The :args part of s/fdef is the whole argument list. You want s/cat for the argument list.


:args (s/cat :ns (s/and #(s/or ,,,) #(> (count %) 2)))


What you're testing above is essentially that you should be calling highest-prod with three or more arguments.


But you could use (s/coll-of number? :min-count 3) instead

💯 4

(s/fdef highest-prod
  :args (s/cat :ns (s/coll-of int? :min-count 3))
  :ret int?)
(just noticed you spec to return an integer so the ns argument would be a collection of int? as well)


Should I be using clojure.test or clojure.spec.test.alpha to test specs? I wasn't able to run clojure.spec.alpha/valid? on the function spec (`fdef`).


@nicholas.jaunsen I've written a small lib to tests fdefs:


This is exactly what I wanted. Thank you!


hmm, seems that leiningen can't find the respeced dep even though the jar is downloaded and I've imported it in the test file as [respeced :as r]


respeced.test :as r


I'm not sure if that's what you're looking for.


@nicholas.jaunsen fdef is intended for two different uses: clojure.spec.test.alpha/instrument will enable checking of :args specs during calls to the function -- so you might instrument code during dev or test work; clojure.spec.test.alpha/check will perform generative testing of the :ret/`:fn` specs explicitly.


Generative testing can often take time so it isn't generally intended to be run as part of your "unit tests" (which should complete quickly).