Fork me on GitHub

Is there a way to repeatedly call a function, feeding it its own output?


(foo (foo (foo (foo 42))))


Check out iterate. (Iterate foo 43)


oh so i would grab (last (take 1000 (iterate foo 42))


Maybe that is nth

👍 3

Working on an old Advent of Code puzzle .. so odd .. this works (take 2 (iterate simulate-motion system))


But when I hit 3 .. (take 3 (iterate simulate-motion system))) .. class clojure.lang.LazySeq cannot be cast to class


Hm again I am bitten by lazy seqs


(defn simulate-motion [system]
  (->> system
       (map planet-apply-velocity)))


The last map turns my system (a vector) into a lazy seq




I should really just read clojure.core


clojure.core is just really interesting generally to see the language build itself


I have thought about using clojure.core as wallpaper for my house... you are welcome to have that idea :D

Sam Stowers03:12:05

Hi! Please let me know if this is the wrong place, but I'm learning Clojure and have a simple problem I'm mystified by

Sam Stowers03:12:50

Clojure is telling me that two (what appear to be identical) strings are not equal, but only in the context of this one function.

Sam Stowers03:12:38

(defn any-chars-match
  "Checks if any chars in a string match the single char in the second string. If any do, return true. Otherwise return false."
  [comparisonChars checkChar]
  (reduce (fn [passedVal compareChar]
            (if (= compareChar checkChar) ;; This always evaluates false
              (reduced true)
          (seq comparisonChars)))


I’m away from keyboard but i think the issue is that compareChar is a char and checkChar is a string in your example. does (checkChars “kk” \k) work?


That was what I was about to say: you're comparing characters to a string.


When you do seq on a string, you get a sequence of characters, so (seq "kk") is (\k \k) and then you're comparing \k against "k" which are not equal @U01FQCBAFGX

Sam Stowers03:12:33

Ah, knew I was missing something dumb - should've checked the types

Sam Stowers03:12:49

Thanks for the quick reply @U7RJTCH6J @U04V70XH6, really appreciate it


and remember to play around in your repl (seq "kk") probably would have shed some light


to mimic what your (seq comparisonChars) is doing. ironically, the answer is in your variable name 🙂 comparison`Chars`

Sam Stowers06:12:27

I did that very thing in the REPL, but I didnt put 2 and 2 together that chars were a different data type than strings. Learned today to pay more attention to such things lol

Sam Stowers06:12:27

Coming from JavaScript, which doesn't use the distinction


yeah. clojurescript is the same way due to that.


its a surprise for sure


part of the distinction is driven by using the built in Java types (which dramatically helps performance). not sure if the design would be the same if reusing the built in java string and char types wasn't as beneficial


another thing that would have helped is prn instead of println -

(ins)user=> (println ["k" \k])
[k k]
(cmd)user=> (prn ["k" \k])
["k" \k]


(there's also pr-str for getting the pr behavior inside arbitrary output from println / format)

Sam Stowers20:12:04

How are you all so helpful

Sam Stowers20:12:19

This is my first interaction w/the Clojure community - posted a question and multiple helpful replies in minutes. Never really seen this before. 🙂


haha, we try

🙌 3
Sam Stowers03:12:22

Tried logging each value and the comparison, but that still looks identical

Sam Stowers03:12:09

Could someone tell me what I'm missing? Read up on the = function, tried using identical?, still no idea


Trying to make a websocket app using http-kit, Sente and Reitit. Something is broken and don't know what, browser says it fails to connect, gets some 406's back from the websocket requests. The code is still minimal and nearly identical to working Sente examples except I'm not using Compojure, so I'm stumped on what is the problem... The relevant files are router.clj and websocket.clj at I've tried to substitute http-kit for Jetty9 and Reitit for Compojure, but no luck :thinking_face:


Oo a websocket app, nice! Tell me more about how you are hosting your server? nginx? apache? I think websockets need a special outer layer, too.


Usually I use all of Sente if working on a real-time app, and hack with a machete. But also be mindful that it might need a reverse-proxy (apache) or something similar (for nginx) ... hope that helps. if not, i am confident we can get down to the bottom of it.


Not using any dedicated webserver, it's a hobby project. Using Sente for both back and front, but I don't think the problem lies with Sente itself, as using just http-kit and it's builtin websocket handler also returns 406's


I will try later if it's a configuration/computer problem by making an empty lein project, adding only http-kit and seeing if that will return 406's as well. If it does, I'll start something without websockets


Oh you're running it locally?


Hmmmmmm. curl from the command-line can be helpful to see what's coming back, too.


I've tried a websocket tester, not curl in particular, but it does connect successfully to other websockets so i'm sure it's the server. First get/handshake returns 101, but then any request after 406's. If you are interested, clone and run the project


Created an empty project, added http-kit as a dependency and wrote

(defn handler [req]
  (hk/as-channel req {:on-open (fn [_] (println "connection"))
                      :on-receive (fn [_ msg] (println msg))}))

(defn -main [& _args]
  (hk/run-server handler {:port 3000}))
which did work, so the problem is project specific. Since the app is going to be very simple, I might just drop Sente on the backend and use http-kits own websocket handling


Yeah why not. Chime in again if you run into any issues ^.^


Hi. I have a newbie question around plumatic.schema. Given this simple schema, how would I indicate either foo or bar must be provided? (one or the other must be there, but not both)

:id s/Int
:name s/Str
:foo s/Str
:bar s/Int


I have thought about using clojure.core as wallpaper for my house... you are welcome to have that idea :D


So here you have it .. I'm working on some Python code for work and I just C-c C-c to try out a code snippet


How do I take something like this and turn it into a map: ((foo bar) (baz qux)) -> {:foo "bar", :baz "qux"}


is (foo bar) a sequence of symbols?


generally it would be into


No they are strings. I am trying (map #(into {} %)) but I get:

java.lang.Character cannot be cast to java.util.Map$Entry

Alex Miller (Clojure team)17:12:23

entries need to either be Map$Entry or 2-element vectors


(into {} (map (fn [[k v]] [(keyword k) v])) '(("foo" "bar") ("baz" "qux")))

Alex Miller (Clojure team)17:12:35

lists don't allow indexed access

Lars Nilsson17:12:29

(zipmap (map keyword (map first coll)) (map second coll)) maybe?


basically im trying to convert a string like “foo:bar baz:qux” into a map {:foo "bar", :baz, "qux"} . I’m using re-seq but maybe there’s an easier way?


that seems fine. can also do a straightforward clojure.string/split

(into {}
      (map (fn [s] (let [[k v] (clojure.string/split s #":")]
                     [(keyword k) v])))
      (clojure.string/split "foo:bar baz:qux" #" "))


oh the destructing in that let binding is slick

Alex Miller (Clojure team)17:12:44

Any time you are using first/second/nth that should be a clue to use destructuring


and just to make it clear for this channel, i used clojure.string/split so it was clear what function i was using but you should require that in your namespace and alias it.


(->> (input "resources/day4.txt" #"\n\n")
  (map #(clojure.string/replace % "\n" " "))
  (map #(clojure.string/split % #" "))
  (map #(let [[k v] (clojure.string/split % #":")]
          [(keyword k) v]))
  (map #(into {} %)))
Am I missing something here? clojure.lang.PersistentVector cannot be cast to java.lang.CharSequence


you are calling a string operation on a vector


if you look at the stack trace it should show which step is actually doing so


your split will return a vector and then you're calling split on that


always helpful to do all of the mapped functions on a single thing and make sure it works and then map them over the whole collection. and a sequence of maps like this you could just combine them into one function


I did a very different solution for parsing the input .. check the Answers thread on #adventofcode 🙂


ie, (->> col (map f) (map g)) could just be (map (comp g f) coll). then its very easy to see that the composition works in the single case and therefore necessarily works on the collection


(and here don't literally use comp but make a single function which does what you want to "one thing")


yeah - that stack of #() blocks is much less clear than a single function doing each of those steps would be


in fact, you probably want (->> (input ...) (map (fn [el] (-> el (string/replace ...) (string/split ...) ...))) you can stil use an arrow, but do it in the more useful place


and stylistically, make a function that takes the input file and returns a sequence of the lines (doing all the #"\n\n" stuff and splitting. then a single function that processes a single line. and then (map process-line (get-input "resources/day4.txt")). makes it very easy to call process-line on a literal "foo:bar baz:quux" to check yourself


an example here if you wanted to see


What's a nice function for taking a seq as input and returning all (unordered) pairs where no element is paired with itself?


I thought about math.combinatorics, then thought I'd write a nested for, then noticed I'd get more pairs than i wanted


(into #{} (for [a lst b lst :when (not= a b)] #{a b}))


:male-cook::skin-tone-2: 💋


(ins)user=> (def lst (range 10))
(ins)user=> (into #{} (for [a lst b lst :when (not= a b)] #{a b}))
#{#{6 3} #{7 1} #{4 3} #{0 1} #{7 5} #{7 6} #{3 5} #{0 4} #{0 9} #{0 7} #{5 8} #{7 3} #{4 8} #{0 3} #{2 8} #{9 5} #{9 8} #{6 5} #{0 6} #{1 4} #{1 8} #{6 8} #{7 4} #{6 9} #{4 6} #{6 2} #{7 2} #{3 8} #{1 6} #{1 5} #{4 2} #{7 9} #{1 3} #{1 2} #{0 2} #{4 9} #{3 9} #{1 9} #{2 5} #{4 5} #{7 8} #{3 2} #{2 9} #{0 8} #{0 5}}


rule 0 of clojure: use the data type that gets the closest to the behavior you need


(let [coll [:a :b :c :a]]
  (for [i (range (count coll))
        j (range (count coll))
        :when (not= i j)]
    (into #{} [(nth coll i) (nth coll j)])))


not sure if that's important for you. some of these sets would be single element sets


I took "no element is paired with itself" to mean equality, not input position


based on "unordered pairs"


the source collection happens to be distinct


and yeah the operation i'm feeding this data to is commutative


Hello, when I do (Integer/parseInt "1") I get back 1 but when I do (map Integer/parseInt ["1" "1"]) I am getting the following error Unable to find static field: parseInt in class java.lang.Integer


(map #(Integer/parseInt %) ["1" "1"])

Alex Miller (Clojure team)19:12:33

Integer/parseInt is not a function but a java static method

Alex Miller (Clojure team)19:12:45

wrap it in an anonymous function

Alex Miller (Clojure team)19:12:53

(map #(Integer/parseInt %) ["1" "1"])


Oh I see, thank you very much guys!!!


I need to write that down in my Clojure notes 😄


There's also a function I think in core (can't remember which) to convert a method to a function, but just wrapping it in an anonymous function is more common and convenient most of the time.

👍 3
Alex Miller (Clojure team)19:12:47

memfn is that but generally it's not worth using because it introduces reflection

✔️ 3

Hum... so it does something funkier then just doing (fn ~name [& args#] (. method ~@args#))

Alex Miller (Clojure team)20:12:11

well it's effectively same

Alex Miller (Clojure team)20:12:28

it's ensuring that type hints on memfn will transfer


Oh, so doing that somehow limits the ability of the compiler to not use reflection? Versus wrapping it in an anonymous function?

Alex Miller (Clojure team)20:12:15

type hints on memfn will work (because the impl ensures they are transferred into the interop call)

Alex Miller (Clojure team)20:12:34

there's nothing magical here wrt the compiler or reflection


Hum, I guess I'm just confused then, say Class/foo is overloaded and I do:

(map #(Class/foo %) coll)

;; or

(map (memfn Class/foo) coll)
Won't they both use reflection?


Oh, I guess memfn doesn't even work for static


But ok, ignoring that, is there any difference in terms of reflection between:

(map (memfn toUpperCase) ["a" "b"])
("A" "B")
;; and
(map #(.toUpperCase %) ["a" "b"])
("A" "B")

Lars Nilsson19:12:18

Could use (map clojure.edn/read-string ["1" "2"])


is there any difference between using edn reader and a java static method?


edn/read-string will read pretty much Clojure form -- hash maps, vectors, as well as numbers, strings etc. Generally, your Java static methods are going to parse just one specific thing.


It depends on your use case. They parse thing differently. If you want an Int back, better use Integer/PartseInt. If you are okay getting any type of number back (or possibly even other types like getting a string, a vector, erc. Then you can use edn read-string. Where as ParseInt will throw an error if the thing you have can't be parsed as an Integer.

Alex Miller (Clojure team)20:12:32

well, read-string will never return an Integer, only Long :)

😮 3

(clojure.edn/read-string {:readers {'an-int int}} "#an-int 42")

Alex Miller (Clojure team)20:12:19

....for some definition of "never" :)

😁 3
😂 3
Lars Nilsson20:12:12

Or BigInt if the number is big...?

Alex Miller (Clojure team)20:12:06

for this particular case, I would use Integer/parseInt (or Long/parseLong)


Thank you all! Very much appreciated the extra info 👍

Jeff Evans20:12:05

I can conditionally add something to a vector based on a condition, with when.

(def whatev true)
[1 2 3 (when whatev 4)]
Is it possible (similarly) to conditionally add a map entry using when? This doesn’t work (fails with Map literal must contain an even number of forms):
{:a 1 :b 2 (when whatev (:c 3))}


that unconditionally adds either nil or 4


(cond-> [ 1 2 3] whatever (conj 4)) and (cond-> {:a 1 :b 2} whatever (assoc :c 3)) are the standard ways to do this

👍 3
Jeff Evans20:12:51

ah, that makes more sense. thank you


(merge {:a 1 :b 2} (when whatever {:c 3})) and (into [1 2] (when whatever 3)) are also alternative ways to do this.


Is there a partition-by that can throw out the “markers” ?


For example I partition on nil but don’t want the nils. I use take-nth to skip them now. Would be nice to leave that out.


Maybe the answer is: don’t be afraid to compose pipelines