This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-07-03
Channels
- # announcements (1)
- # babashka (22)
- # beginners (176)
- # calva (10)
- # cider (4)
- # circleci (5)
- # cljsrn (20)
- # clojure (28)
- # clojure-europe (11)
- # clojure-italy (5)
- # clojure-nl (5)
- # clojure-spec (1)
- # clojure-sweden (2)
- # clojure-uk (29)
- # clojuredesign-podcast (4)
- # clojurescript (38)
- # code-reviews (25)
- # conjure (1)
- # core-typed (1)
- # data-science (16)
- # datomic (23)
- # figwheel-main (16)
- # fulcro (48)
- # helix (9)
- # jobs (3)
- # juxt (5)
- # kaocha (17)
- # malli (19)
- # mount (9)
- # nrepl (4)
- # off-topic (35)
- # pathom (7)
- # re-frame (28)
- # reagent (26)
- # reitit (1)
- # releases (1)
- # remote-jobs (5)
- # sci (6)
- # shadow-cljs (36)
- # spacemacs (3)
- # sql (8)
- # tools-deps (13)
- # unrepl (1)
- # vim (4)
- # xtdb (8)
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.
This is good reading on logging https://lambdaisland.com/blog/2020-06-12-logging-in-clojure-making-sense-of-the-mess
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?)
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).
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))
(recur))
the acc needs to be an arg to occur, conj doesn't have side effects
but yes
(go-loop [acc []]
(let [acc' (conj acc (<! chan))]
(if (some-condition? acc')
(do (handle acc')
(recur []))
(recur acc'))))
⢠fixed typoalso note that using <!!
inside a go or go-loop block can stall all of core.async, use <!
inside go
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
events
view move-resize-cb
dbl-click-cb
selection-cb
event-select-cb
navigation-cb
toolbar-component
sel-event
]
(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)
[:div
[:> 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
:eventPropGetter
(fn [event]
(if (equal-events? event sel-event)
(do
(prn "events are equal so selected" event sel-event)
"rbc-event rbc-selected")
(do
(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 https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md 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)
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
with the same params I mean
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
sel-event
is 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 prn
and the rest of the calls treat it as a #object[Function]
Why can that be? Why is this map treated as a function inside of the render fn
? Thanks!
Good Morning Clojurians. I am trying to convert the https://github.com/seancorfield/usermanager-example 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?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
OK, so yes, https://clojuredocs.org/clojure.core/int, Integer/parseInt
works.
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?
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
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)]
[encoding
{:bytes (seq decoded)
:reconstructed (String. decoded encoding)}]))))
(pprint))
{"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 ""}}
nil
unchecked-int is doing something weird, 255 is not the right answer
⢠edited to expose the encodings that fail to contain that characterthe supported encodings are https://docs.oracle.com/en/java/javase/14/intl/supported-encodings.html#GUID-187BA718-195F-4C39-B0D5-F3FDF02C7205
@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 look at doing the opposite of https://github.com/Day8/re-frame-10x#installation
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 [day8.re-frame-10x.preload]
@U7RJTCH6J It worked. Actually I did set true to false but I didn't notice the :preloads part. Thank you very much!

there's also a more advanced setup possible where you use profiles to turn 10x on and off
Clojure sages how do i schedule functions to run at certain times. Library recommendations or roll my own?
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).
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.
@UP2FUP0TT, thereās a little mini-library that attaches a fnās form as metadata to itself for printing, https://github.com/technomancy/serializable-fn, but Iām not sure itāll apply to reader literal fns. Still, it might be worth a look while learning.
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
Contents:
: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
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 0
th 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.
Does that help @U0E9KE222?
: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?
(defn depth-seq
[tree]
(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 solutionThere's probably a small bug in your implementation since it returns nil
, I'll try to take a look!
> though the last map is little ugly unfortunately! Now I understand why it was required though! Nice stuff
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
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?
(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
[tree]
(lazy-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
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
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
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
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 if explaining start to end of the body is tedious, perhaps you have concrete questions?
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: http://jafingerhut.github.io/
Also this version http://clojure.org, 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?
Oh interesting, I did not know about group-by
.
I'm really not that familiar with the list library
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 https://github.com/yogthos/configyou 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)
true
(ins)user=> *foo*
true
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