Fork me on GitHub

Curious, is there a bult-in predicate that returns true for list-like things (vectors, lists) but not strings/maps?


I can never remember what sequential? returns true vs. false for, but I would check that.


it doesn't work for eg. arrays or java.util.List, but it's the right thing for ordered clojure immutable collections


nb. also it returns false for sets


Its doc string is probably 100% accurate, but tells you very little if you do not know the internal implementation details of data structures.


user=> (pprint (group-by sequential? ["hi" 3 [] clojure.lang.PersistentQueue/EMPTY {} #{} () nil]))
{false ["hi" 3 {} #{} nil], true [[] <-()-< ()]}


when did we get that nice pr for queues? I like it


That is probably some REPL plugin thingy you have. Not part of default Clojure REPL


There are also return values of seq that at least some (maybe all except nil?) that sequential returns true for, e.g. (sequential? (seq {:a 1})) is true


But I may be getting too far off into the weeds there in my wondering. Part of the reason I am confused by it is that I have actually looked at half a dozen different implementations of seq under the hood in Clojure/Java.


hmm, I don't have any plugins - this is just vanilla clj with no deps.edn file


the fish version only shows up with pprint, not normal pr


Ah, yes, I see it, too. I wasn't using pprint before.


anyway, it's a pleasant surprise


Looks like it's been in there since Clojure 1.2.


1.1 doesn't have clojure.pprint


$ clojure -A:1.2 -e "(println *clojure-version*)" -e "(require 'clojure.pprint)" -e "(clojure.pprint/pprint (conj clojure.lang.PersistentQueue/EMPTY :a))"
{:major 1, :minor 2, :incremental 1, :qualifier }


(well, that's 1.2.1)


Why is defn / valid but defn // is not? Also, suggest me a name for a division operation which repeatedly divides x with y and returns the count, e.g. (? 125 5) => 3 and (? 250 5) => 3.


"'/' has special meaning, it can be used once in the middle of a symbol to separate the namespace from the name, e.g. my-namespace/foo. '/' by itself names the division function."

đź‘Ť 4

@hindol.adhya You're looking for the opposite of power/exponent?


Yes, exactly. But don't want to name it log.


I went with times-divisible last time, but that's too long. I will be using this frequently.


Some variant of the name log seems appropriate for what it does, perhaps with a letter thrown in to mean "floor of log" or "log, truncated"


@U0CMVHBL2 Because the calculation method is different and also because log returns a double. My method returns a whole number.


That's an interesting idea! Thanks. But I really really wanted something like //.


Probably I will go with tlog or similar.


/ is not going to work well in Clojure,nor anything that contains /


That part I understood. That's why I am a little sad.


(defn -:- [x y] ...)


What about %% ?


%% is valid? "Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, ', ?, <, > and = (other characters may be allowed eventually)."


It is valid! This is promising.


Ya, I'd say its a little icky as well, since it won't work inside #() cause it'll conflict with that form's %


Many things that are not on the list of officially supported characters are not explicitly disallowed -- they just aren't on the officially supported list.


/ is one of the few on the explicitly disallowed (or very special restricted use) list.


One hack is if you define a / fn in some namespace, and then alias it to say m you can do (m// 10 5)


Thanks everyone for pitching in. Instead of fighting against the system, I think I'll go with tlog for now.

đź‘Ť 4

That would probably be my approach to this. Define a new / in a namespace that can get a nice, short alias.


user=> (ns times.div (:refer-clojure :exclude [/]))
times.div=> (defn / [a b] (count (take-while #(<= b %) (reductions clojure.core// a (repeat b)))))
times.div=> (ns user)
user=> (require '[times.div :as *])
user=> (*// 250 5)
user=> (*// 125 5)
(updated to add :refer-clojure :exclude so the warning about redefinition doesn't appear)

đź‘Ť 4

Reviving and old thread, but I did a cool (to me) implementation of int-log.

(defn int-log
  "Returns how many times b can evenly divide x."
  [x b]
  (let [squares (reverse
                 (map vector
                      (iterate #(* 2 %) 1)
                      (take-while #(zero? (rem x %))
                                  (iterate #(*' % %) b))))]
    (loop [[[i m] [j n] & squares] squares]
      (if (nil? n)
        (if (zero? (rem x (* m n)))
          (recur (cons [(+ i j) (* m n)] squares))
          (recur (cons [i m] squares)))))))
This one calculates the exponent in logarithmic time O(log n). Benchmarked against a naive O(n) implementation.
(defn int-log-naive
  [x b]
   (->> (iterate #(*' b %) b)
        (take-while #(zero? (rem x %))))))
(defn -main
  [& _]
  (let [base   29
        raised (math/expt base 1000)]
    (dotimes [_ 1000]
      (? raised base))))

int-log: "Elapsed time: 113.5178 msecs" int-log-naive: "Elapsed time: 11103.9029 msecs"


For (int-log 1250 5), 1. collect enough squares [5 25 625] 2. start with the highest square 625 3. (* 625 25) divides 1250? if not, drop 25. (* 625 5) divides 1250? if not drop 5.


is there a channel in this Slack about this book ? đź“–


Would anyone be able to point me to some information on why a ClojureScript application (re-frame template +handler) wouldn’t show updates on a custom domain when changes are pushed to master with GitHub integration, but will show them on the herokuapp? I’ve ran git add ., git push heroku master(:master), lein prod, lein with-profile prod uberjar, pulled my changes into master and committed that, I’ve ran git push --force, and still, the changes will not take to the new site? I’ve scoured through some S/O answers but most of them are for languages/platforms that aren’t Clojure/S.

Eamonn Sullivan16:01:00

Just a dumb question, but have you eliminated caching? Each browser has a different way of busting the cache -- in Chrome, shift-click on reload, for example.


Oh my dear god that was it. That was it! Thanks so much, I’ll never forget it.


@UHR1B0NJG For future reference: There is a small trick to always force the browser to use the most recent version of your script and ignore cache. When loading your script you can add a version-identifier as any query parameter. For example: app.js?v=1.0 as soon as the browser sees another query string it won't load from cache

đź‘Ť 4

We sometimes use this to ensure that clients get the newest version and we don't get calls which are resolved by a simple cache reload

đź‘Ť 4
Luke Schubert12:01:44

I know the angular bundler solves this by adding some random string to the end of its generated js files

Luke Schubert12:01:19

so for v1.0.0 all of the built js will be bundle-45ASDB123.js and the index.html file will reference that, and when you bump to v1.0.1 that random string will change

Victor FM23:01:09

Hey everyone, I'm having trouble managing response types on a API, like sending a 200, 422, or any other status, does anyone have this problem too? I'm using compojure to design it


how are you setting the response status?

Victor FM23:01:50

At the moment it is always sending back a 200, with the contents on the body


there's a helper, but a hash-map {:body ... :status N} should do the trick

Victor FM23:01:27

I'm trying to figure out how to set up the responses types without applying that on the business layer

Victor FM23:01:53

I have 3 layers, the API, business, and repository

Victor FM23:01:16

If I add the logic to send back a 422 for example, where would I put it? On the API layer or the business layer? If I add it in the business layer, it wouldn't really be a business layer anymore, right?


likely a middleware that takes your handler as an argument and returns a new handler that validates that the request can be processed, and falls back to 422


but I haven't isolated my layers in as disciplined way as you are describing, so I might be missing a better option


I'm also slightly confused by your usage of the term "response type" here because to me that's somehting like application/json


which clearly isn't what you mean

Victor FM23:01:24

sorry, I mean sending back a 422 when someone sends a invalid entity, like a missing field or wrong information type


OK yeah I'd definitely write a wrap-validate middleware and wrap the handler with it (inside the route if it's endpoint specific, around the router if it's generic)

Victor FM23:01:57

hmm, ok I'll take a look on how to create middlewares then, maybe that's what I'm missing


the platonic form of a handler middleware:

(defn wrap-foo
  (fn new-handler-function [request]
    (post-function (handler-function (pre-function request)))))
it takes a handler, and returns a new one that might do something with data before the handler is called, and might do something after the handler is called


a validator is probably more like this:

(defn wrap-validate
  (fn [request]
     (let [validation-error (validate request)]
        (if validation-error
           {:status 422 :body validation-error}
           (handler-function request)))))


where validiate returns nil or false for a good input, and a message for a bad one

Victor FM23:01:31

ok, that makes it way easier to understand

Victor FM23:01:55

you helped me a lot, thanks! I was thinking the whole day about this


so instead of using layers per-se (or as well as), you can isolate concerns into middleware, and compose them on each other to get all your needed features (there are a lot of great middleware that come with ring, many are applied already by default)

Victor FM23:01:35

that is a interesting approach, I'll have to think more on that and decide what to do


and another variation is that wrap-validate can take another arg- the validator rules (or validator function) and individually get wrapped on different contexts


since in ring the router itself is wrappable (for things that apply to all routes) but so are individual endpoints (for things that are route or subtree specific)

Victor FM00:01:53

you mean adding the middleware only for a specific route?


right - they are flexible enough to be applied at either level


(or maybe better to say, ring's design is such that they can be applied at either level)

Victor FM00:01:03

Ok, thanks for all the help man, I'll try work on it