This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-12-05
Channels
- # adventofcode (95)
- # announcements (3)
- # babashka (11)
- # beginners (39)
- # boot (19)
- # bristol-clojurians (1)
- # cider (32)
- # clj-kondo (39)
- # cljsrn (8)
- # clojure (156)
- # clojure-dev (35)
- # clojure-europe (4)
- # clojure-italy (15)
- # clojure-nl (28)
- # clojure-spec (43)
- # clojure-uk (153)
- # clojurescript (168)
- # core-async (13)
- # core-logic (11)
- # cryogen (4)
- # cursive (13)
- # datomic (26)
- # duct (3)
- # emacs (8)
- # fulcro (33)
- # garden (4)
- # graalvm (18)
- # graphql (4)
- # jobs-discuss (2)
- # kaocha (1)
- # leiningen (3)
- # malli (8)
- # off-topic (1)
- # pathom (7)
- # re-frame (21)
- # reagent (3)
- # rewrite-clj (1)
- # schema (4)
- # shadow-cljs (40)
- # sql (2)
- # uncomplicate (3)
is there a convenient way to determine which source files get pulled in during a call to (compile my-ns)
?
@sogaiu I think this dynamic var might help - the code that loads namespaces uses it to decide whether to print
user=> (doc clojure.core/*loading-verbosely*)
-------------------------
clojure.core/*loading-verbosely*
True while a verbose load is pending
@noisesmith that was helpful, thanks!
how could I spit an edn and have it pprinted
?
pprint takes an optional writer arg, or you can use with-out-str to create a string out of what would otherwise be printed, and then write that
(ins)user=> (with-open [w (io/writer "foo.edn")] (pprint {:a 0 :b 1 :c (range 12) :d (zipmap (range 10) (range))} w))
nil
(cmd)user=> (println (slurp "foo.edn"))
{:a 0,
:b 1,
:c (0 1 2 3 4 5 6 7 8 9 10 11),
:d {0 0, 7 7, 1 1, 4 4, 6 6, 3 3, 2 2, 9 9, 5 5, 8 8}}
nil
• edit - removed redundant io/file call that io/writer doesn't need, a writer should use with-openwith-out-str effectively does the same thing
(ins)user=> (spit "bar.edn" (with-out-str (pprint {:a 0 :b 1 :c (range 12) :d (zipmap (range 10) (range))})))
nil
(ins)user=> (= (slurp "foo.edn") (slurp "bar.edn"))
true
funny enough, nearly identical character count between the approaches
I wouldn't know it took a writer arg, except for the error you get when you pass two clojure data objects to one pprint call (hey, it works with println...)
the version without the with-open worked accidentally thanks to the writer's finalizer since it fell out of scope instantly, but the correct way is to use with-open, so I fixed it
I have build a jar file. However, when I run it with java -jar
I get in return an error telling me that one of my functions does not exists! But it exists. If I run it in the repl, It works 100%
Caused by: java.lang.RuntimeException: No such var: elastic/search-hits
I can even run my project in the repl directly in the namespace where the exception is coming from and run the function with no problem
Eastwood, kibit, yagni, and bikeshed are coming back postive, with no erros
it is kind of complicated. I am using boot and my own boot task.
I just deleted my boot cached and it work 😐
My off the cuff guess is you are calling eval somewhere and assuming that the value of *ns*
is something it is not
It is weird becasue if I run the jar couple times in the row. the Error will go away
Hi. What is the most common deployment model for clojure web apps (servers)? Specifically, deployments when there are services like AWS ECS Fargate, does one really need Application Servers (containers) like Tomcat, Jetty etc.? Anyone using systemd
+ jvm
+ nginx
sidecar deployment in production?
I just use a docker image with clojure installed there. we dont have any special configs. you dont benefit of an owner role thats all
Great, thanks. And, with the usual web service (app) involving RDBMS, is PostgreSQL a viable choice for Clojure?
It has been the primary choice for me and the tools I've used so far. I am just curious, maybe there are some core inconsistencies you may have encountered.
Not really inconsistencies - just an occasional need to map some type that some jdbc library didn't map itself. So far, has happened to me only once.
Also, it depends on how you will create your queries. E.g. with honeysql
and honeysql-postgres
, I sometimes need to add a defmethod
that describes some keyword that the libraries don't know about.
I have no idea, I have never used Ring. I use Edge, which uses Yada, which uses Aleph.
@U2FRKM4TW spasibo
Ah, no - I've used Ring once, for my very first Clojure project that was an entry project for some job. 🙂
There are plenty more acronyms and concepts in the JavaEE world. It doesn't mean you need even a single one of them to create something of value.
That confidence you have only after deploying, some production ready apps. But, for the beginners, we try to find the analogous tools and concepts.
The best advice out there in this situation is probably "just go do it". 🙂 Not "just deploy something to production" of course, but "just create a working web app and see for yourself". Try Ring, try Aleph, try raw CLJ, see what you like. Read a bit about them, create some more. Yet another kind of loop, not unlike REPL.
From https://bugs.openjdk.java.net/browse/JDK-5039533 "The static function java.lang.Character.isWhitespace(char ch) correctly recognizes U+00A0, U+180E, U+202F, U+2060, U+FEFF as non-breaking spaces and excludes them from being considered whitespaces according to the documentation and specifications." Not sure why though.
Postgres choked on it when inserting XML: XML declaration allowed only at the start of the document
Hi. I am getting reflections warnings call to method indexOf can't be resolved (target class is unknown)
The function params are a regex string and a sequence (vector of strings\n), it's returning index of the first occurrence of sub-string in seq. Is there a way to resolve the warning?
(defn firstindexof [timestap seqq]
(.indexOf seqq
(first
(filter #(re-find timestap %) seqq))))
I guess
(defn firstindexof [timestap seqq]
(.indexOf seqq
^String
(first
(filter #(re-find timestap %) seqq))))
it's a sequence of strings, or rather a sequence returned by (line-seq reader). is there a way to annotate it by type?
(type (line-seq ...))
returns clojure.lang.Cons
. Try using that.
Although I find it strange that the type isn't known here. In what context do you get the reflection warning? I tried it in a REPL and don't see anything.
your advice helped, thanks!
(defn firstindexof [timestamp ^clojure.lang.Cons seqq]
(.indexOf seqq
(first
(filter #(re-find timestamp %) seqq))))
Really interesting. Can you tell how you run your REPL?
Because right now, the code will probably fail if you pass there anything but Cons
. E.g. a vector.
yep )
Execution error (ClassCastException) at data-health.dataloss/firstindexof (form-init17101450020595890464.clj:1).
class clojure.lang.PersistentVector cannot be cast to class clojure.lang.ASeq (clojure.lang.PersistentVector and clojure.lang.ASeq are in unnamed module of loader 'app')
Ah, you have (set! *warn-on-reflection* true)
. I didn't know about this option.
It seems that you have 3 options:
1. Stop caring about reflection
2. Use a more wide-spread type annotation (e.g. just APersistentVector
) and just wrap the argument each time you call the function (in vec
)
3. Rethink the way you work with data - maybe there's a more idiomatic approach, as explained e.g. here: https://stackoverflow.com/a/4831170/564509
yes, the option on reflection is indeed set, I though you new about it, as your advice was spot on : ). I can choose to ignore it but it's interesting to see how can I solve in a proper way. I was thinking about something generic, like a collection etc that will accept set, vector, and list type
The issue is that all of the collections that implement .indexOf
, implement it on its own and not as a part of some interface.
In JavaScript I can do text.replace(regExp, (m, grp) => grp.toUpperCase())
How can I replicate it in Clojure? The thing is that my replacements aren't static, I need to run a fn on the match. I could do it in two steps - 1) extract all matches, 2) create a map match -> replacement, 3) replace every match by the corresponding replacement one by one. But perhaps there is a nicer way?
(clojure.string/replace "some-text" #"some-regex" clojure.string/upper-case)
Awesome, how could I have overlooked that? Thanks a lot!
When shutdown-agents
is called in Clojure, it stops both the agent threadpools (`soloExecutor` and pooledExecutor
) but since future
spawning happens on the soloExecutor
, is there any way to say that I want the agents to stop but new future
s can still be spawned? Without using something like a dedicated pool and spawning future
s on it like with https://github.com/TheClimateCorporation/claypoole?
Would it be possible/useful to shutdown just the pooledExecutor? (i.e. (.shutdown clojure.lang.Agent/pooledExecutor)
)
you should only call shutdown-agents if you are shutting down the jvm
@U1UQEM078 Thanks, I think that would work, I’ll try it out @U064X3EF3 I am calling shutdown-agents during JVM shutdown but there are a few other shutdown hooks that are causing the JVM to take more time to exit, and in the meantime, if some thread calls future, it gets rejected. I’m right now catching the rejected exception and running it in the calling thread.
What is the most Clojure-friendly observability platform? (New Relic, Honeycomb, LightStep, etc.)
Let me know when you find out. We basically use
which is to say we decorate fns manually for newrelic's sake
Hadn't seen that before @U0MQW27QB -- nice! We rolled our our tracing with New Relic (I blogged about it years ago) but this is much nicer. @U0HJJF9A4 Happy to answer Qs about New Relic -- we've been using it for years.
I certainly know of people doing both New Relic and Honeycomb with Clojure /cc @ghadi
(require '[clj-time.format :as f])
(def example-date "Sat, 02 Nov 2019 00:00:00 GMT")
(f/parse (f/formatter :rfc822) example-date) ;; malformed at GMT
is this a bug or it this date truly not rfc822?There is no joda time formatter symbol that corresponds to the timezones allowed in a rfc822 date
I must the the author of clojure.java-time has courage. He uses clojure in the library name and the core namespace is just "java-time"
Love that lib, hate that name/namespace 🙂
Anyone familiar with Schema?
I'll ask there. Thanks.
If I start a Thread such as (-> (Thread. function-name-here) (.start))
How could I stop it?
yeah, I will probably do the same to avoid kibit linting yelling at me about this
NB: the interrupt method doesn't stop a thread, it sets a flag that makes certain methods exit. This is cooperative and opt-in, and you should make sure any thread that needs to be interruptable calls a method that exits cleanly if the interrupted flag is set
there's no way to safely stop a thread from the outside in the jvm, it's always voluntary
Is there a way to generate all valid values for a spec?
"all"? That could be an infinitely large set of values...
You could use s/exercise
to randomly generate as many valid values as you want tho'...
Ah all is difficult because spec cannot be that smart
Trying to solve Advent of Code day 4 using spec
• It is a six-digit number.
• The value is within the range given in your puzzle input.
• Two adjacent digits are the same (like 22
in 1_22_345
).
• Going from left to right, the digits never decrease; they only ever increase or stay the same (like 111123
or 135679
).
How many possible
sounds like you want logic programming https://github.com/clojure/core.logic - give constraints and the code returns some datum satisfying the constraints
since you need every possible solution (or the count...), you might think about the most efficient way to generate unique numbers fitting the pattern
Ah yes it’s logic programming.
Although now you can generate it more smarter than a core.logic evaluator I guess
I’ll check afterwards in #adventofcode 🙂
Is it possible to update a value in an atom, by it's index? For example changing the value of the 5th value in a list
ignore the atom. its just a container. if you know how to update the 5th value in a list you can do it in an atom
if you want to update a single reference, it needs to be some kind of mutable container. Not sure if that's your requirement though.
An atom is a mutable container/box/pointer/reference, intended to point at an immutable value. Creating a new immutable value from an existing immutable value, you have most of the Clojure library to help you with, and is no different than starting with any immutable value and producing another one.
If the immutable value is inside of an atom, then the only way to change what immutable value the atom points to, is via a function for modifying an atom, typically swap!
if you're new to functional programming a common pitfall is to think you need mutability and atoms much more than you might otherwise need. Not saying that's your case now but that's something to be aware of if you're a beginner (and apologies if you aren't.)
@olle142 you can create a new list with a new value at the 5th index by using assoc
:
(assoc '(0 1 2 3 4 5 6) 4 10)
;; => '(0 1 2 3 10 5 6)
user=> (assoc '(0 1 2 3 4 5 6) 4 10)
Execution error (ClassCastException) at user/eval293 (REPL:1).
clojure.lang.PersistentList cannot be cast to clojure.lang.Associative
you must have been thinking of square brackets here?
@dpsutton Yea I'm not quite used to the immutable way of thinking yet. If I need to update a lot of items in a list, is it more efficient to use an atom or is it better to create new lists for it? (because that's how you want to do it in clojure, right?)
it will create a new immutable data structure either way, @olle142. whether you use an atom or not
this is usually pretty efficient due to the way that the immutable data structures are implemented
see Structural Sharing
I haven't provided a solution for you because there's a lot that can vary according to your requirements and assumptions. ie, what if there are fewer than 5 elements, what data type, how its used, etc
also #beginners is a great place to hash these things out as you're getting used to the functional/immutable paradigm
Trying to use the assoc function on my list gives me a ClassCastException, which has to do with trying to redefine my constant or something?
in: http://www.duelinmarkers.com/2016/01/24/the-life-of-a-clojure-expression.html there is this bit:
If the form being eval‘d is not a “def” of some kind, it’s wrapped in a zero-arity fn and that fn is invoked. I don’t know why that’s necessary. (If you do, please let me know.)
i've been puzzling over this too. does anyone know why this wrapping is necessary?
(i think this bit is not explained in clojure pills 17 either.)https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7169_L7178
@sogaiu Because each expression (at the top-level) is compiled to a class -- because that's the unit of compilation on the JVM -- as if it were an anonymous function definition and then that (compiled) function-as-class is invoked. (my understanding)
(each function is compiled to a class with static invoke
methods)
There are probably under 10 people in the world who know the answer to that question off the top of their head, and unfortunately I am not one of them 🙂 This channel and #clojure-dev are the most reasonable places to ask, so you are in the right place -- it all depends on whether one of those few people happen to be reading.
"necessary" might be too strong a word in your question "why this wrapping is necessary", i.e. likely the code could have been implemented differently. It may be that it makes the compiler more straightforward to reduce the number of kinds of 'top level' forms.
Also, feel free to delete the code that does that wrapping, compile your custom version of Clojure locally with a different version number, and try it out on a Clojure project of yours and see what happens 🙂 Sometimes that is a quicker way to find an answer.
thanks a lot for the feedback and tips -- i guess i should become more familiar with building a custom clojure version 🙂 may be an early version would be easier to get working -- one that doesn't involve spec.
Happy to walk you through the steps if you are interested. It is pretty quick and easy once you know how.
You should already have Java installed. Install Maven, then from the root of a Clojure source tree, type mvn clean install
, and if it succeeds, then near the end of the output it should have a line like the one in my next message. Use the version number there in your org.clojure/clojure dependency version number instead of "1.10.1", e.g. replace it with "1.11.0-master-SNAPSHOT", and run your Clojure code again. It will look in your $HOME/.m2 directory for that locally installed version, as it does for any other version of Clojure that is first downloaded from the Internet and then put into your $HOME/.m2 directory.
[INFO] Installing /Users/andy/clj/clojure/target/clojure-1.11.0-master-SNAPSHOT-sources.jar to /Users/andy/.m2/repository/org/clojure/clojure/1.11.0-master-SNAPSHOT/clojure-1.11.0-master-SNAPSHOT-sources.jar
If you do not want to run Clojure's built-in tests for some reason (e.g. you made only a tiny change and expect them to pass), you can skip those by instead using mvn -Dmaven.test.skip=true clean install
Just think of all the places in the Clojure compiler Java code you could stick in a little System.out.println(...)
call and learn all kinds of things 🙂
it seems to be working (including my first System.out.println 🙂 ). i was under the impression that there was some kind of extra work involved because of some kind of circular dependency(?) with spec. perhaps that is just a misunderstanding on my part? in any case, thanks for the fishing pole 🎣