Fork me on GitHub
Eric Ihli01:11:51

I'm looking for a resource that can help me learn how to parse arbitrary binary data. Given a description along the lines of "Offset 0000, 32 bit integer, magic number. Offset 0004, 32 bit integer, number of rows. etc...", It would be a huge help to see an example of a simple program that parses a custom binary data structure and... kind of like but in Clojure. Actually, I think I might just go with that and try translating it to Clojure.


you could also check out gloss, which is meant for this sort of thing


Is there a nice way to do the following? I feel there is too much repetition going on …

(defn should-add-label [settings issue]
   (check-issue-status settings issue)
   (check-issue-assignee settings issue)
   (check-issue-milestone settings issue)
   (check-issue-labels settings issue)))


(every? #(% settings issue) [#'check-status #'check-assignee #'check-milestone])


Sometimes it helps to think out loud


There may be an every-fn or every-pred already in core


ah yes but the predicates take only one argument


Oh, wait it takes multiple args, but as ands to the predicate weird


Nope, confusing myself with all the anonymous functions, the returned predicates takes multiple args as expected


Ok I need to re-read that


I have POST /parse-reply {body :body} (compojure-api) The content of (str(slurp body)) is along the lines of:

Content-Disposition: form-data; name=\"attachments\"

Content-Disposition: form-data; name=\"dkim\"

{ : pass}
Content-Disposition: form-data; name=\"subject\"

Content-Disposition: form-data; name=\"to\"

Content-Disposition: form-data; name=\"spam_score\"

^ A multipart-form with boundary --xYzZY Is there a way I can convert it into JSON or if I have to parse the string to get the values by name like "spam_score" or "to" email address, how should I go about it? I’m thinking of splitting the string with --xYzZY and follow the parse-split cycle further until I get the value (yet to verify if the fields are always returned in the same position for the parse-split cycle to work).

Ben Sless08:11:08

An aside: I recommend against using slurp in production unless the endpoint sees very little traffic. Json libraries like Cheshire and jsonista can parse byte arrays directly

👍 3


👍 3

There is a ring middleware to decode form data


Yeah. Referring the last comment response of: Went through: but not sure how to get it working. Especially the handler:

(require '[ring.middleware.defaults :refer :all])

(def site
  (wrap-defaults handler site-defaults))
The service I’m working on, has no handler defined.


Hi. I’m trying to create a clojurescript library that makes use of some javascript files. I”m using leiningen and :foreign-libs under :cljsbuild in order to bundle the js into the library. However, that doesn’t seem to make the js code available to the application code consuming the library. Could anyone point out to me the proper way to incorporate javascript files into clojurescript libraries?


Is there someway in clojurescript to define constant values during compile-time, like the plugin?


Euh... What does that plugin do?


You can define constants with ^:const which will inline the value if its EDN


Otherwise, you can use macros to perform whatever compile time things you want


I was trying to do it with macro just now but the compiler wasn’t happy about it

# .clj
(ns my.core)
(defmacro getenv [key]
  (System/getenv key))

# .cljs
(ns my.core 
  [:require-marcors my.core])

(def ENV (getenv))
(defn hi [] env)
This causes cljs compiler to warn me
WARNING: Can't take value of macro my.core/getenv at line 4
WARNING: Can't take value of macro my.core/getenv at line 5
I know it’s a very hacky way of using macro as a function, but I’m not sure how else to pass the JVM environment during compilation into runtime


I wouldn't say the use of a macro for this is hacky. Like if you want this functionality, macros are a great way to get it. Much better than the JS pre-processing that webpack plugin must have to do. Now, that error normally means you are passing a macro to something that expects a function. I assume that's not the real try, cause you have typos and all in it. Macros in ClojureScript can be a bit tricky to setup right, and then I'd just double check you don't have a dumb mistake, like missing a parens or forgetting to pass an arg, etc.


So it could be a false positive warning. Apparently is fixed in a newer version of figwheel


thanks for the link, I wasn’t using figwheel, but I’ll double check the macro usage


There’s a typo in your require macros expression. Is that present in the source or just in slack?

Noah Bogart14:11:15

is there a way to load into a default namespace with deps.edn?

Noah Bogart14:11:32

in lein's project.clj, I can say :repl-options {:init-ns default.core} and when the repl starts, it loads the file and enters the namespace so I don't have to do anything extra

Noah Bogart14:11:08

in my project's root directory, when i enter clj, it loads into the repl with my dependencies in the classpath, but it doesn't load the current project's files, and I have to call (load "default/core") to load them before I can call (in-ns 'default.core)

Alex Miller (Clojure team)14:11:09

you can use the -e features of clojure.main to evaluate expressions before you start the repl:

% clj -M -e "(require 'clojure.set)(in-ns 'clojure.set)" -r
#object[clojure.lang.Namespace 0x5bf22f18 "clojure.set"]

Alex Miller (Clojure team)14:11:43

that can be bundled into an alias in deps.edn as well (requires a , instead of spaces to avoid some word splitting through the shell):

 {:repl {:main-opts ["-e" "(require,'clojure.set)(in-ns,'clojure.set)" "-r"]}}}
and then clj -M:repl

Noah Bogart14:11:29

didn't look at that page

Alex Miller (Clojure team)14:11:59

yeah, -i can be useful to load a .clj file containing whatever in advance too


Any feedback on using javascript files in cljs library code?


What is the idiomatic Clojure equivalent of Python's if "foo" in ("foo", "bar", "baz"): ?


(or (contains? {"foo" "bar"} "foo") ({"foo" "bar"} "foo")) you can use the function contains? or use the fact that sets are callable themselves


eval both of those expressions at the repl to see the different values they return


oh sets are callable 🙂

Chris Emerson19:11:20

Beware of contains? because it trips most new people up at some point. It's behaviour is sometimes different to what you expect!

Chris Emerson19:11:41

contains? checks for the presence of a key, for sets it does what you would expect, since keys=values, and for vectors it checks whether the index is present (contains? #{:a :b} :a)            ;;=> true (contains? #{:a :b} :c)            ;;=> false (contains? {:a :b} :a)             ;;=> true (contains? {:a :b} :b)             ;;=> false (contains? [1 2] 1)              ;;=> true (contains? [1 2] 2)              ;;=> false


Right so you need a # in your example @dpsutton 🙂

Chris Emerson19:11:45

yep! (contains? {"foo" "bar"} "foo") => true (contains? {"foo" "bar"} "bar") => false

Chris Emerson19:11:22

but if you used a set instead of a map:

(contains? #{"foo" "bar"} "bar")
=> true


oh right. my bad 🙂

Daniel Stephens19:11:34

(some #{:some :things :to :check :are :contained} [:some :vec :of :things]) I quite like this pattern, uses the fact that sets can be called and lets you check for more than one thing (if needed) existing in the coll, no idea on the performance but it's never been my bottleneck

Chris Emerson19:11:15

that's a great tip

☺️ 3

Yeah that is nice - because right now I do (some #(contains? (set labels) (:name %)) (:labels issue))


Oh I can't directly translate that but i can shorten it with that trick


(some (set ignored-labels) (map :name (:labels issue)))

👍 3

I'd usually just define ignored-labels as a set


also consider: (some (comp (set ignored-labels) :name) (:labels issue)) - some already traverses, you don't need to map too


That is really cool


you can even do something like (def ignored-issue (comp (set ignored-labels) :name)) then do (some ignored-issue (:labels issue))


or maybe "ignored-label" is a better name there


I find a tendency to reduce line / definition count as if that were meaningful simplicity, where giving the right things the right names is the clearest approach


"more smaller functions" ?


Also there are caveats if the set can contain false or nil when invoking the set


not just that - because the one liner has the same number of functions - the question is what is exposed as a name


I have some data with timestamps like "2020-11-19T17:32:32.277Z" and I think it would be a little nicer to transform that to our time zone, and/or "time ago" format. Near as I can tell the move is to use java.time directly, instead of the various wrappers I can find (which seem to be for Java 8 ). There are a rather overwhelming number of classes and I cannot figure out which one, if any, has a constructor that will take a string like I've got. Any tips?

Daniel Stephens20:11:16

(defn format-when [zdt-str]
  (let [zdt (ZonedDateTime/parse zdt-str)
        dur (Duration/between zdt (ZonedDateTime/now))
        secs (.getSeconds dur)]
    (if (< secs (* 5 60 60))
      (let [[v a b] (->>
                      [[(quot secs (* 60 60 24)) "day" "days"]
                       [(quot (rem secs (* 60 60 24)) (* 60 60)) "hour" "hours"]
                       [(quot (rem secs (* 60 60)) 60) "minute" "minutes"]
                       [(rem secs 60) "second" "seconds"]]
                      (filter (comp (complement zero?) first))
        (if v (format "%s %s ago" v (if (= 1 v) a b))
      (str (.toLocalDateTime (.withZoneSameInstant zdt (ZoneId/systemDefault)))))))
=> #'user/format-when
(format-when "2020-11-18T17:32:32.277Z[Australia/Sydney]")
=> "2020-11-18T06:32:32.277"
(format-when "2020-11-19T17:32:32.277Z")
=> "2 hours ago"
(format-when (str (Instant/now)))
=> "now"
this is some very rough code I dug out, did something similar to this when I was starting out with clojure, probably helpful for the interop more than the clojure!


ooh, i did work out how to use ZoneId/systemDefault but i didn't know about Duration/between, thank you

Daniel Stephens19:11:39


🎉 3
Daniel Stephens19:11:25

Instant/parse would also work, but if you are messing with timezones the first thing you'd probably do from there is convert to a ZonedDateTime


there's multiple classes usable, but they each have parse methods


you may also be seeing the instant tagged literal in a print out


I don't think so, hiredman, the data I've got is not coming from a Clojure program


thanks folks! i thought I'd be using a constructor (Like. so) instead of a method


the difference is that the parse methods make you specify the format you are parsing, where a constructor wouldn't (not that it couldn't, that would just be weird...)


@mathpunk If you would prefer a wrapper, the clj-time README links to several (as part of trying to stop people using clj-time these days!).


Hi, html5 audio element needs my server to send "Accept-Ranges" "bytes" and while the default ring file-response sends "Content-Length" $len the audio element still says Live Broadcast as opposed to showing the seek bar as needed


this might be relevant - each response still uses Content-Lenth, which just describes that payload not the resource


Right on. Thanks for snooping, man! Guess what I did? Used full paths instead of relative paths -- now html5 audio elements with .m4a works on mobile safari and desktop safari. Also... what the effnet?


I guess the header is supposed to read "Content-Range" ? hrm


Apparently it needs 3 headers set:

Content-Range:bytes 0-7437846/7437847
but it doesn't look like Content-Range is by default in ring/file-response...


So basically it looks like I gotta add the "Content-Range" header... but i'm not sure how to get the byte length of a file


oh. looks like (.length ) does the trick with


opened a new issue @ ring ^_^


Maybe I am overthinking this, but what is preferred in Clojure land? pr / pr-number or pull-request / pull-request-number ?


"pr" is a pretty common term in github speak of course


Oh hm their API calls it pull_number actually .. interesting


as far as I know "pull request" is a github UI concept, it's been adopted elsewhere but isn't part of git itself


I think this is off topic though


@st3fan for example the clojure.core project uses github as a mirror, but it's not how contributions are accepted, you'd use JIRA instead

Alex Miller (Clojure team)21:11:50

the github repo is the repo

Alex Miller (Clojure team)21:11:30

this seems to be a pervasive thing people believe but I'm not really sure why as it has always been this way (since moving to git)


Sorry my question is about naming not about contributing to Clojure 🙂


right, OK - regarding naming, pull-request is the name of a github UI feature


i'm working on a github client - so that is ok, i don't have to hide that detail

hiredman21:11:13[email protected]/ the first instance of "pull request" on the git mailing list predates github by 3 years


I'm writing a small application which models populations changing over time - a sort of zero player game, similar to game of life. I want to draw the output of the steps on a canvas (a grid with squares on it that fill and empty) with the output being redrawn with each step. Is there a go-to Clojure library for this? I was thinking of quil, but only because it's the only one I've heard of. Are there alternatives I should be thinking about?


have you seen rich's ants simulation?


I've heard about it in the context of core.async, i didn't realize it had a drawing component


it predates core.async by a lot


Oh, not async, state management


I am not sure if the original is around any more is maybe a copy, it renders using java's built in 2d canvas stuff


That looks good enough to do what I want, thanks!


There's an awesome story in Surely You're Joking Mr. Feynman about how Richard Feynman had a line of ants in his apartment and bathroom. Rather than try and get rid of them, he started experimenting. For example, he put some sugar on a table and then used a coaster to "elevate/teleport" ants to the table. Sure enough, ants were able to figure out there was an elevator and they would start waiting on the coaster to get a ride. But they couldn't really figure out that the elevator went 2 ways. Very interesting. Also he used chalk to draw a line for each ant's path to the sugar in his bathroom. It was like a newton's linear approximation. First it was curvy and clunky, and over time each ant successively did a straighter-and-straighter line towards the sugar.


Love that book!

🐜 3

I'm a really happy camper right now. I rewrote the backend for in Clojure (from Go) and it is really nice compact code and ... 10x less LoC 7000 vs 700

clojure-spin 15
👍 9
😲 6
aw_yeah 3

Is it possible to programatically "load" a namespace? for example my bots nicely organized in their own namespace and right now I have code like this:

(def apps [needs-triage/bot needs-review/bot lock-issue/bot lock-pull-request/bot])
(def apps-by-id (into {} (map #(vector (:id %) %) apps)))
But it would be nice if I can just discover all devbots.bots.* namespaces at runtime ...


They do contain multimethods, so I think I need to fully "load" them before the multimethod dispatch works.


(not sure what the right terminology is)

Alex Miller (Clojure team)22:11:36

you can load dynamically via require (or load, but that's considered lower level), but discovery is not generally a thing you can ask a jvm to do

Alex Miller (Clojure team)22:11:29

you can inspect parts of your classpath as files/jar paths to "discover" things like that (and there are java libs that have support for that kind of thing)

Alex Miller (Clojure team)22:11:36

probably best way to handle is with some kind of runtime config that lists the ns'es to load


these namespaces are embedded in my app, so i can also require them in core and then iterate over available namespaces and filter on devbots.bots. - maybe that is a simple start


Right on. Thanks for snooping, man! Guess what I did? Used full paths instead of relative paths -- now html5 audio elements with .m4a works on mobile safari and desktop safari. Also... what the effnet?