Fork me on GitHub

Java logging is a gigantic can of worms @stopachka We've gone back and forth on several solutions and we eventually ended up using org.clojure/tools.logging with log4j2 as the implementation and deps for that and the various bridges to route all logging through it. tools.logging can be told to use any of several logging backends so that should probably be your "first stop" on logging. Nearly all of the community logging libraries have a variety of gotchas that ultimately make the logging problem worse, IMO.

👍 1

Using slf4j/logback per that blog post is likely to be fine for your needs. I really don't like that slf4j treats FATAL as ERROR and I don't want any XML configuration files so that's why we prefer log4j2 (we can use .properties files, it does auto-loading of changed log files without dropping log items, it supports MDC -- not sure whether slf4j/logback does?)

👍 1

But, yeah, to your basic question, using a JVM option to select the appropriate logging context is reasonable. We default to the production log config but override it per-dev with an environment variable or a local JVM option (we run SQL migrations locally with a different log config to when we're running tests, for example).

👍 1

Thanks for the awesome context Sean! Will look deeper into the essay and play around with setting up sans community libraries.


is there any clean way to inspect the values in a channel before taking from it? or is this getting away from the purpose


i’d like to see if it either has a certain number of bytes, or whether it contains a delimiter


you could implement a custom buffer that offers this, but it also means that using that information in program logic invalidates promises that CSP makes


eg. (if (> (messages-count c) 4) ...) - that's a race condition, there's no way to know if the count is for inside the ... code or not


all you know is that for a moment that was true


if you have a single consumer of the channel in your design, you could use a closed over collection of inputs in a go-loop and hold off execution until the collected data meets some condition


just to make sure i’m understanding, something like

(go-loop [acc []]
   (conj acc (<!! chan))
   (when stuff
      (handle acc))


seems like it would work.


the acc needs to be an arg to occur, conj doesn't have side effects


right, yeah


(go-loop [acc []]
  (let [acc' (conj acc (<! chan))]
    (if (some-condition? acc')
       (do (handle acc')
            (recur []))
       (recur acc'))))
• fixed typo


also note that using <!! inside a go or go-loop block can stall all of core.async, use <! inside go


brilliant, thank you


Hello all just getting started with Clojurians.

Jonathan Barrenetxea10:07:19

Hi! I'm running into a strange behaviour and I have no clue what could be happening... I have the following reagent component:

(defn FullCalendar [ date-vec
                    view move-resize-cb
  (prn "sel-event 1" sel-event date-vec)
  (let [localizer (. BigCalendar momentLocalizer m)]
    (fn [date-vec events view sel-event]
      (prn "sel-event 2" sel-event date-vec view)
       [:> DndCalendar {:localizer localizer
                        :date (convert-date date-vec)
                        :events events
                        :views ["day" "week" "month" "agenda"]
                        :view (if (or (nil? view) (empty? view)) "month" view)
                        :titleAccessor #(:int-title (js->clj % :keywordize-keys true))
                        :resizeable true
                        :toolbar true
                        :step 30
                        :timeslots 2
                        :selected sel-event
                        :components {:toolbar (if (nil? toolbar-component)
                                                (reagent/reactify-component Cal-Toolbar)
                                                (reagent/reactify-component toolbar-component))}
                        :scrollToTime cal-start-time
                        (fn [event]
                          (if (equal-events? event sel-event)
                              (prn "events are equal so selected" event sel-event)
                              "rbc-event rbc-selected")
                              (prn "different events" event sel-event)
                              (set-background sel-event))
                        :onNavigate navigation-cb


Your (fn) params need to match your (defn) params. I suspect, your sel-event in your fn is actually dbl-click-cb. Have a look at for reagent.


as a style rule, if you have more than 4 args, it's best to use a hash-map with keywords instead of a long arglist


(some people disagree on whether "4" is the magic number, I think there's consensus that the magic number is less than 9)

Jonathan Barrenetxea07:07:10

Sorry for the late response... Yes @U5DFXKYSV, you are right, I forgot that the call to the second fn is called exactly the same way as the main defn

Jonathan Barrenetxea07:07:51

with the same params I mean

Jonathan Barrenetxea07:07:59

Good point about the number of args, @noisesmith, I think I might have to refactor some of the functions in my code now that you mention this

Jonathan Barrenetxea10:07:25

sel-eventis coming from a re-frame subscription in the call to this component. The thing that I don't understand is that in the first prn I can see the correct value of sel-event (a map with different fields), but when I pass it into the fn the second prnand the rest of the calls treat it as a #object[Function]

Jonathan Barrenetxea10:07:14

Why can that be? Why is this map treated as a function inside of the render fn ? Thanks!

Timofey Sitnikov12:07:05

Good Morning Clojurians. I am trying to convert the to work with Postgres, but I am getting an error:

HTTP ERROR 500 org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = character varying Hint: No operator matches the given name and argument types. You might need to add explicit type casts. Position: 28
(The full error listing is attached) My last hook to libraries function:
(ns bubbleuptop.model.user-manager
            [next.jdbc.sql :as sql])

(defn delete-user-by-id
  "Given a user ID, delete that user."
  [db id]
  (sql/delete! (db) :users {:id id}))
When I change the last line to (sql/delete! (db) :users 1)) it works fine and deletes the user with ID of 1. Also as long as I do not have to pass any numeric parameters to DB it seems to work fine. Am I doing something wrong?


It looks like the id you received in delete-user-by-id is a string, and not an int


This often happens at the protocol border, it it expecting an INT but it got a CHAR


Works when you pass an explicit INT, but not when you pass a string or char, so you gotta find a way to convert or Cast that string/char into an int datatype for postgresql


I get these errors sometimes when working with HTML input / form input... sometimes you need to specify exactly in the HTML form type="number"


if it's on the clojure side, you may need to cast to integer .. i think it's Integer/parseInt


hey everyone, how can i get the byte form of ÿ ? (extended ascii)


Do you mean the Unicode code point integer value? Or a sequence of bytes that Unicode is represented in UTF-8? In UTF-16? Something else?


unchecked-byte throws character cannot be cast to number


Is the error message you see: "Value out of range for byte: ÿ"


The numeric range for a JVM byte is -128 to +127. That Unicode code point for that character is not in that range. Try int


oh yeah! that did it


Or unchecked-int if you prefer




more generally, given an encoding, you can get the sequence of 8 bit signed values that would be interpreted as that value in that encoding - characters don't have bytes, but encodings do map characters to sequences of bytes

user=> (->> ["US-ASCII" "UTF-8" "UTF-16" "UTF-32" "Big5" "IBM-Thai"]
     (into {} (map (fn [encoding]
                     (let [decoded (.getBytes "ÿ" encoding)]
                        {:bytes (seq decoded)
                         :reconstructed (String. decoded encoding)}]))))
{"US-ASCII" {:bytes (63), :reconstructed "?"},
 "UTF-8" {:bytes (-61 -65), :reconstructed "ÿ"},
 "UTF-16" {:bytes (-2 -1 0 -1), :reconstructed "ÿ"},
 "UTF-32" {:bytes (0 0 0 -1), :reconstructed "ÿ"},
 "Big5" {:bytes (63), :reconstructed "?"},
 "IBM-Thai" {:bytes (63), :reconstructed ""}}
unchecked-int is doing something weird, 255 is not the right answer • edited to expose the encodings that fail to contain that character


@gtzogana - note that ÿ is not "extended ascii", and AFAIK there is no such encoding - according to unicode "ÿ" is a code point, and an encoding decides which bytes (and how many, and in what order) correspond to that code point


@gtzogana and I was partially wrong above - 255 (int) is the same as (-61 -65) according to the jvm, but this depends on things like the jvm's default encoding, and byte order, which are implementation details that are bad to rely on


(unless your question is very specifically and only about one version of java, because it's allowed to change those things AFAIK)


Hello, So I created a coljure-script project based on a reframe template and added calva and re-frame-10x. I used this command: lein new re-frame py_project +calva +10x To run and test my project I use the "jack in" REPL in calva and it works great. However I noticed that +10x reframe tracing slows down a bit my execution. Is there a way to elegantly remove/deactivate 10x from the lein project? What I would do otherwise is create a new lien template without +10x and copy paste all my .cljs files. Thank you for your help


you might be able to simply get away with modifying or removing these 2 key value pairs in your project.clj:

:closure-defines      {"re_frame.trace.trace_enabled_QMARK_" true}
 :preloads             []


@U7RJTCH6J It worked. Actually I did set true to false but I didn't notice the :preloads part. Thank you very much!

bananadance 1

there's also a more advanced setup possible where you use profiles to turn 10x on and off

👍 1
🙏 1

Clojure sages how do i schedule functions to run at certain times. Library recommendations or roll my own?


you can use Java ScheduledExecutor or Quartz


What's the practical differences between creating a var using def say of a map and having the same map but it being a function using defn with no input parameters?


With def it will be evaluated at load/compile time. With defn it will be "evaluated" at call time (although it will still be compiled at load time). So any differences will depend on what is in the hash map.


As an example from Clojure From the Ground Up:

(defn atlas-v
  {:dry-mass  50050
   :fuel-mass 284450
   :time 0
   :isp 3050
   :max-fuel-rate (/ 284450 253)
   :max-thrust 4.152e6})


The other difference is for REPL workflows: references to a def will be compiled in with the initial value, so if you change the def in the REPL, references to it will still refer to the old value. If you use a defn, each call will always produce the latest value of the function.


(you can get around that by using #'atlas-v instead of plain atlas-v and then you can change the def and its new value will be picked up)


For a hash map like that which is all constants, I'd use def.


Ok, cool. Thanks for the clarifications. I'm a little stoked I was thinking the same with it just being constants which is why I asked. Figured I was missing some kind of functionality


Perhaps it's a nod to the future where the Atlas V data might come from somewhere else (but then I would expect it to have some sort of argument that could be queried to find where to get the data).


0-arity functions are nearly always impure, unless they are deliberately recomputing something on every call (such as a lazy sequence so you can consume it without holding onto the head).


Hey, is there a way to inspect anonymous function?


e.g. find out what a function like this #function[namespace/eval14220/fn--14227] does.


You can't really "inspect" a function since each function is compiled to a class with an .invoke() method.


What you can do to make some things more readable is using (fn [..] ..) instead of #(..) or (partial ..) or (comp ..) and then giving a name to the otherwise anonymous function (fn some-name [..] ..) and then at least some-name will show up in the compiled name and in stacktraces.

❤️ 1

@UP2FUP0TT, there’s a little mini-library that attaches a fn’s form as metadata to itself for printing,, but I’m not sure it’ll apply to reader literal fns. Still, it might be worth a look while learning.


Thank you guys :hugging_face:


I want to learn how to read the output of spec/explain-data. I'm sure this is full of useful information but I couldn't make heads or tails of it... it's from looking at cider inspect last result

Class: clojure.lang.PersistentArrayMap
  :clojure.spec.alpha/problems = ( { :path [], :pred clojure.core/map?, :val [ :com.logicgate.helpER.source/indent 4 ], :via [ :com.logicgate.helpER.specs/scenarios :com.logicgate.helpER.specs/scenario :com.logicgate.helpER.specs/specification ], :in [ 0 0 ] } { :path [], :pred clojure.core/map?, :val [ :com.logicgate.helpER.source/tag "describe" ], :via [ :com.logicgate.helpER.specs/scenarios :com.logicgate.helpER.specs/scenario :com.logicgate.helpER.specs/specification ], :in [ 0 1 ] } { :path [], :pred clojure.core/map?, :val [ :com.logicgate.helpER.source/message "Adding a user in an SSO environment" ], :via [ :com.logicgate.helpER.specs/scenarios :com.logicgate.helpER.specs/scenario :com.logicgate.helpER.specs/specification ], :in [ 0 2 ] } { :path [], :pred clojure.core/map?, :val [ :com.logicgate.helpER.source/level 0 ], :via [ :com.logicgate.helpER.specs/scenarios :com.logicgate.helpER.specs/scenario :com.logicgate.helpER.specs/specification ], :in [ 0 3 ] } { :path [], :pred clojure.core/map?, :val [ :com.logicgate.helpER.source/indent 6 ], :via [ :com.logicgate.helpER.specs/scenarios :com.logicgate.helpER.specs/scenario :com.logicgate.helpER.specs/specification ], :in [ 1 0 ] } ... )
  :clojure.spec.alpha/spec = :com.logicgate.helpER.specs/scenarios
  :clojure.spec.alpha/value = ( { :com.logicgate.helpER.source/indent 4, :com.logicgate.helpER.source/tag "describe", :com.logicgate.helpER.source/message "Adding a user in an SSO environment", :com.logicgate.helpER.source/level 0 } { :com.logicgate.helpER.source/indent 6, :com.logicgate.helpER.source/tag "describe", :com.logicgate.helpER.source/message "Navigate to Admin -> Users", :com.logicgate.helpER.source/level 1 } { :com.logicgate.helpER.source/indent 8, :com.logicgate.helpER.source/tag "describe", :com.logicgate.helpER.source/message "Click on \"+ New User\" button", :com.logicgate.helpER.source/level 2 } { :com.logicgate.helpER.source/indent 10, :com.logicgate.helpER.source/tag "describe", :com.logicgate.helpER.source/message "the \"Send Welcome Email\" checkbox input", :com.logicgate.helpER.source/level 3 } { :com.logicgate.helpER.source/indent 12, :com.logicgate.helpER.source/tag "it", :com.logicgate.helpER.source/message "is displayed", :com.logicgate.helpER.source/level 4 } ... )


I ended up solving my problem by zooming my attention toward a smaller part of what i was working on


but, i'd love to understand what Lassie was trying to express...


In the above, it's saying "expected map, found ..." for each of those values.


The :pred says what test failed, :val tells you what it tried to test, and :via gives the "call tree" through the specs.


:com.logicgate.helpER.specs/scenarios :com.logicgate.helpER.specs/scenario :com.logicgate.helpER.specs/specification so scenarios is (I assume) a collection of scenario and that has a specification which I expect is s/keys (most likely, given the map? predicate failure).


and your overall value was a sequence of hash maps -- scenarios, I assume, so the problem is that a value like { :com.logicgate.helpER.source/indent 4, :com.logicgate.helpER.source/tag "describe", :com.logicgate.helpER.source/message "Adding a user in an SSO environment", :com.logicgate.helpER.source/level 0 } fails the scenario spec because the :in suggest collection navigation (`0`th element, then 0th element of that, which is a MapEntry -- the [ :com.logicgate.helpER.source/indent 4 ] pair -- and it is expecting an s/keys so it should be a hash map.


So I think the level of nesting is off -- either in the Spec or in the data structure.


I'll need to reflect quietly on it for a minute but I think so, thx Sean


:via gives a key path and :in gives a numeric index path, then?


:in matches get-in so it would be a combination of keys and index values


:via is the path through the chain of Specs, rather than through the values (which is :in)


Anybody willing to help a Clojurian newbie here? I am trying to implement some typical coding questions to get up to speed. I'm struggling a bit with the typical of computing the depth map of a binary tree 4 / \ 7 9 / \ \ 10 2 6 \ 6 \ 2 Implementing this in TypeScript was really trivial, but it relies on the global map being passed and modified around:


I wanted to try to implement it in Clojure trying to stay immutable as much as possible, but I am struggling. Anybody has any advice?

Daniel Stephens23:07:01

(defn depth-seq
  (letfn [(children [n] (concat (keep :right n) (keep :left n)))]
    (->> (iterate children [tree])
         (take-while seq)
         (map (partial map :node)))))
Thought I'd try a solution as well since I'm still learning 🙂 I quite like when I can use iterate for things, though the last map is little ugly unfortunately! The idea here is that iterate applies a function to the previous value to get the next one each time, so if we start with a list of nodes [tree] we can map over them to get the children, and we can do that recursively! That take-while is so that we stop when we reach the bottom (no more children exist). In some cases the last map might not be desirable as without it you keep more context, but with it is closer to your TypeScript solution


Oh interesting, let's check this out!


Well there are a lot of things I am still uneducated about here! THat's good


There's probably a small bug in your implementation since it returns nil , I'll try to take a look!


Ok I guess its' (partial map :value)


> though the last map is little ugly unfortunately! Now I understand why it was required though! Nice stuff

👍 1

The depth, meaning the maximum number of steps from the root to any of the leaves?


So 4 in your example tree of your figure?


@andy.fingerhut Thanks for chiming in! Not exactly. The idea is to group all the items by the depth in the tree


So the output would be something like this:


On level 0 we have 4, on level 1 we have 7 and 9… and so on


I guess this is not really a Clojure specific question, it's more about how to implement this without using mutable data structures


So you want to return a map whose keys are the depths of all nodes, and the value corresponding with each key is a list of nodes with that depth?




the general concept is to use an accumulator holding things that get updated, and pass it to a recursive call or reduce step


@noisesmith So…reduce all the way down?


I'll have a one liner in a moment

🕐 1

Looking forward. I've been thinking about this for a while and I can't figure that out


(def tree
  [{:node 4
    :children [{:node 7
                :children [{:node 10
                            :children [{:node 6
                                        :children [{:node 2
                                                    :children []}]}]}
                           {:node 2
                            :children []}]}
               {:node 9
                :children [{:node 6
                            :children []}]}]}])

(defn depth-seq
   (when (seq tree)
     (cons (map :node tree)
           (depth-seq (mapcat :children tree))))))
user=> (depth-seq tree)
((4) (7 9) (10 2 6) (6) (2))


the list is the nodes in order of depth


I thought it was going to be a one liner, but really it's clearer on 6 lines


as usual my estimate for how long my work would take was wildly wrong

😁 1

if you want a different representation for the tree, just replace :node and :children with the functions that get those respective parts of each branch


Yeah so the data structure I have has left and right keys explicitly but that should not be a problem


Thanks for the tip, I'll check out the code There's a lot of stuff I do not know about


in that case, you can replace :children with a function returning the tuple of [r,l] - the rest should work as is


feel free to ask about the functions / macros used, and the idioms, there are plenty of common but relatively unique clojure tricks in that small program


I would have finished this faster but when I was 95% done with the recursive accumulating version I realized it was better done as a breadth first search


Why the use lazy-seq?


because idiomatically if the only data dependency for the next item to produce is the previous item, a lazy-seq is the best representation


this would allow traversing a very deep tree breadth first (one level at a time going down), without filling the RAM, for example


though if the primary usage would be indexed lookup of items by depth, you could use a vector instead of a lazy-seq


Well these 6 lines are very…dense. I still do not get what's going on 🙂


lazy-seq is a macro that takes form, and returns something you can call to evaluate the compiled form, which caches it the first time it is accessed


so the body is executed only once, and not until you ask for it


when is like if, but it only has one branch, and returns nil if the branch returns false


seq returns nil, which is treated as false, if presented an empty collection


cons takes a "head" and a "tail" (it's short for construct), it returns a linked list comprising that head and tail


Well yes I get the individual functions


Just trying to understand the logic and the flow


well if explaining start to end of the body is tedious, perhaps you have concrete questions?


Still going through the code. I guess the secret sauce is mapcat 🙂


Ok I can see you defined the nodes as an array with a single map inside


That I do not understand but I am assuming it's to make it work with mapcat


I did that so that the initial call to the function and the recursive calls would use the same data representation


mapcat is needed because the children of 7 and the children of 9 are treated as coequal siblings • edit wrong number was here


so I concatenate them into one result


IOW it defines a "tree" that is really a forest: 0 or more trees which are walked in parallel to group nodes by depth


and IMHO the real magic comes from using data structures and function calls that are "sympathetic" to that pattern


of course you could make a helper that only accepts a tree, but to me that's more complicated than putting a tree in a vector producing a forest


(or wrapping it in whatever other "forest" representation your structure uses - I guess it's actually a right/left pair)


@noisesmith Would this be a correct spec for the data structure we're using above?


My doubt is that s/coll-of wants a predicate, and I do not understand how to get a predicate our of a registered spec


So one approach is to somehow return a list of maps where each has the depth of a node, and the node, e.g. {:depth 1 :node <whatever you want to use to represent a node>}. Then call (group-by :depth foo), where foo is that list of maps.


Oh interesting, I did not know about group-by . I'm really not that familiar with the list library


There is certainly a lot in Clojure's core library, so don't expect to learn it all at once. The Clojure cheatsheet tries to group things with related functionality together, which can help when learning about similar things:


Also this version, but it doesn't have the hovering tool tips


Never mind. It does. But I like the other version better, personally.


For the 'somehow' step that comes first, you can use a recursive function that take a parameter current-depth, and returns {:depth current-depth, :node current-node}, and append that to the list returned by a recursive call on all children.


Here's the issue I'm having. I do not want to mutate anything so adding a map = creating a new map


When I'm calling recursively the function on the left and the right element, I would get two new maps and they should get merged somehow?


how do folks configure library behavior? for example, I'm writing a tiny logging library to teach myself clojure and I'd like the user to be able to configure certain behavior once, e.g. set a boolean to true or false I found dynamic variables (`def ^:dynamic foo ...`) but wanted to avoid having the user wrap every call in a binding


right now my code has this hardcoded at the top:

(def config
  {:level  :debug
   :stdout true
   :file   nil
   :pretty false})
and these are things I'd like the user to configure once I found some libraries like


you only need binding if you want different values in different contexts, you can use set! on the root value


ah, lemme give that a shot - thank you


see for example *warn-on-reflection*, *out* *print-length* etc. offered by clojure - people usually set them once if they want a non-default value, or rarely they use binding, both work


awesome, I'll check those out - thanks


I seem to be unable to change with set! and get:

Can't change/establish root binding of: *pretty* with set
where I have:
(def ^:dynamic *pretty* false)
(set! *pretty* true)


I can, however, use set! on *warn-on-reflection*


oh, I misremembered how to set this up you can only use set! inside a binding context, I forgot that the repl itself was inside a binding context - but outside the context you can use the value provided via the initial def


(cmd)user=> (def ^:dynamic foo false) #'user/foo (ins)user=> foo false (ins)user=> (binding [foo true] (set! foo :file-not-found) foo) :file-not-found (ins)user=> foo false


hm not sure I follow, in the example above, the next invocation of `*foo*` shows false


right, because set! only works inside binding - you can use alter-var-root to set a root binding though


so if my code is relying on the user having configured *foo* , dynamic vars probably won't work here? is that accurate?


(ins)user=> (alter-var-root #'*foo* not)
(ins)user=> *foo*


is there recommended best practice here? i.e. is what I'm doing discouraged 🙂


or is this a fairly clojuresque way of doing things


it's a slightly odd API, but using a function encourages safer coding patterns


I could wrap the alter-var-root in a function called "toggle" or something like that?


all of clojure's mutable containers are modified by providing a function that takes the previous value and returns the new one


sometimes you just want (alter-var-root **foo** (constantly true))


but constantly means you are ignoring any changes other threads might be trying to make


oh neat, yeah I think that's what I want considering this is kind of analogous to an "init" that's unchanged through the rest of the process/application