the good news is that it's possible to set message levels on a per-package basis, the bad news is that java logging config is overly complex
haha awesome. well that's good to know. I see this Logger.LEVEL stuff ... blargh
yeah, you can even say "no warnings from com.google.cloud specifically"
the annoying part is there's multiple ways to say that, and which way you do it depends on your app because there are parallel and incompatible ways to configure
and you can get changes in which system is used caused by config files in your deps for example
right on.. well maybe a hacky way to delete that message from the result will be fine. I washoping I could disable this logging on the google cloud console somewhere but it's complex and made for robots
How would I go about saying I don't want any warnings from com.google.cloud?
is this relevant? https://ask.clojure.org/index.php/8985/can-i-suppress-low-level-logs-with-tools-logging
;/ doesn't seem to do it
it depends on which logging system you decide you are using, and which style of config file it uses (this is a weird mess because of the hyper-flexible way various java logging systems and compatibility layers are defined) - search for "architecture" here to see a diagram https://stackify.com/logging-java/
okay... thanks, i will do some learning. I really just want to suppress the WARNING: x on cloud translate
since i plan on doing lots of translate calls and don't want the repl blasted
if only that were as simple as it should be
commence the weeping
theoretically could i set the warning "status" to something other than warn
and then see no more warnings?
pardon my ignorance i know very little about this fiasco xD
all of the loggers have a concept of a "log level", which can be modified (either globally or on a per package basis) to suppress messages below a desired level
warn, debug, error, info etc. have numeric constants and the normal style of config is to set a numeric level (via its symbol)
but many of the logging systems allow things that are more targeted than that (eg. per package config if someone else made their stuff too verbose / not verbose enough)
Aha.
Make use of this: https://twitter.com/markm208/status/1353495678509608960?s=20
weeping continues
How would one hide the warnings from a specific namespace or package?
welp. I used their recommended export G_TRANS_CREDENTIALS thing on the command line instead of manually passing in an api key and... the warnings are gone
but like... why google why
Is there a way to setup default :jvm-opts
on deps.edn
? It seems you can only do it under an alias
(defn my-add [[n1 d1] [n2 d2]]
(let [d3 (+ d1 d2)
[-n d3'] (cond
(< d3 10) [0 d3]
(= d3 10) [1 0]
(< 10 d3) [1 (- d3 10)])]
[(+ n1 n2 -n) d3']))
Using some elementary school math rules 🙂 (expressed within the cond)@dromar56 There is currently no way to have a default set of JVM opts.
I'm curious about your use case? I don't see how you'd always want the same JVM opts no matter what aspect of the project you're running?
From the deps/CLI reference page: "JVM arguments may either be passed on the command line (with -J) or by using data stored in an alias under :jvm-opts and passed with -X or -A or -M" and also "The configuration file format (in deps.edn files) is an edn map with top-level keys :deps, :paths, and :aliases, plus provider-specific keys for configuring dependency sources." -- so it says there are three top-level keys and it also says :jvm-opts
can be stored in an alias. I guess if you have suggestions for making it clearer, you could post that on http://ask.clojure.org
The closest equivalent to Leiningen's sample.project.clj
is the example-deps.edn
in the CLI install, which is copied to ~/.clojure
on first use (and also remains in the installation). But that currently refers to -R
and -C
options which are both deprecated (or maybe even removed at this point). And it does not show :jvm-opts
... I'll post a Q on http://ask.clojure.org about that...
https://ask.clojure.org/index.php/10094/add-the-cli-equivalent-of-leiningens-sample-project-clj
Thanks a lot!
@dromar56 One thing you could do is use a shell alias, for any options to clj
that you use very frequently while developing
good morning all
I don't actually have a use-case that requires it. But I also very seldom use jvm options (I think today was the first time I used them for something other than setting the heap size).
When I tried searching for how to set it using deps.edn, I found you could set them using :jvm-opts
through an alias, but I didn't expect it would the only way.
Without prior knowledge about when/how someone would want to use jvm opts, I assumed that it also worked as a top level option.
This is actually related to an issue I have with the documentation of deps.edn: there's no succinct reference to it. I've read the manual on http://clojure.org, but most of the time I already know how to use it (more or less) and am just trying to find the exact syntax to do it.
With leins, I used this:
https://github.com/technomancy/leiningen/blob/master/sample.project.clj
I haven't found an alternative to deps.edn, and that made my discovery that :jvm-opts
is only an alias setting more difficult than it could have been
any shadow-expert who can help me with this How to solve this one :
cljs꞉cljs.user꞉> @state/orders
nil
; No available JS runtime.
clj꞉cljs.user꞉> @state
shadow-cljs.edn
{:source-paths ["src"]
:dependencies [[binaryage/devtools "0.9.10"]
[proto-repl "0.3.1"]
[reagent "0.8.0"]]
:nrepl {:port 3333}
:builds
{:app {:target :browser
:output-dir "public/js"
:asset-path "/js"
:modules
{:main
{:entries [giggin.core]}}
:devtools
{:after-load giggin.core/main
:http-root "public"
:http-port 3000}}}}
That wouldn't be confusig at all. Imagine you want to understand a bit of regex and somebody starts by introducing a nondeterministic finite automaton first, because that's basically the same thing 😄
The repl needs to something that runs js so it can run stuff
Since you're targeting a browser, you need to open the browser
Localhost:3000 it seems.
I just found out that the Duffer brothers (stranger things) were from Durham NC. What is it that makes people from Durham special?
Having just moved to the area recently, I suspect it may also have to do with the vinegar based barbecue, which I never heard of before: https://www.youtube.com/watch?v=6ubTQfr_tyY&feature=youtu.be
@hobosarefriends I have a browser open
if you do (js/alert "test")
does the alert window pop up?
(have you made sure that nothing else is running on that port?)
yep, I see then a popup with the text test
on it on my browser
huh… then it is connected.. that’s pretty weird
maybe ask in #shadow-cljs
thanks
no probs, sorry I couldn’t solve it
it is solved
I had to use the namespace before the call
stupid beginners error
Good to hear my dude, and you seem to understand why it happened so that’s even better.
I think it's the Cheerwine
Sounds appealing. They have cherry beer here in Belgium.
also good! :)
yep I understand now after soeme help of the shadow-cljs channel
Study Algo & Data Struc. in Java will help me become a better Clojure dev?
studying algo and data structures in any language will usually help you become a better developer in every other language you use
I agree with @dpsutton,I work with devs where everything is either an object (as in C# object
or a string, and every data structure is list. Then they wonder why everything is so slow. Learning data structures and algorithms will never not be a good idea.
is there a better idomatic way to turn for example 123 into (1 2 3)
then this :
(map #(rem % 10) (take-while pos? (iterate #(quot % 10) 123)))
oke, but the mentor wanted a solution where I did not first convert it to a string and then convert back
Yes that's what I'm talking about
The one where you use mod
or the near-substitute, rem
(defn num->list
[num]
(loop [acc '() q num r 0]
(if (zero? q)
acc
(let [r (rem q 10)
q (quot q 10)]
(recur
(conj acc r)
q
r)))))
(num->list 123)
;; => (1 2 3)
Or like you had it:
(defn num->list
[num]
(->> num
(iterate #(quot % 10))
(take-while pos?)
(map #(rem % 10))
(reverse)))
(num->list 123)
;; => (1 2 3)
Ya rem is what you want so it works on negative numbers as well.
I had the last one
you could go via strings.
(map #(Character/getNumericValue %) (str 123)) ; => (1 2 3)
not sure if that’s more idiomatic
thanks, Was hoping i could do it without parse to a string and then back from a string
concise v. fast tradeoff
Maybe you can use partition?
(partition 1 (str 123))
;; => ((\1) (\2) (\3))
could be a idea
@roelof is it required to work on positive integers only?
I think so
;; I took a try as well:
(pr-str
(map #(Integer/parseInt %)
(str/split "123" #"")))
I use (str/split s #"") to split a string into strings on 1 character often, dunno if thats the best way
;; Didn't notice this:
;; > positive integers only?
(fn [s]
{:pre (pos-int? (Integer/parseInt s))}
(pr-str
(map #(Integer/parseInt %)
(str/split s #""))))
is there a prettier for clojure?
I’ve found this https://github.com/brandonbloom/fipp, but not sure how to run this in a cli to pretty print my code
tks
@mksybr you don’t need to split on #“”. Mapping a function over a string applies it to each character in turn automatically.
(map #(Integer/parseInt %) s)
is fine.
Thanks for letting me know!
Hrm...
1. Caused by java.lang.ClassCastException
java.lang.Character cannot be cast to java.lang.String
;; from
(map #(Integer/parseInt %) "123")
AIUI, when you map over a String the function receives a value of type Character, not of String.
And Integer/parseInt expects and only accepts a String
I have once seen a nice youtube? demo of clojure where the presenter is counting words of moby dick to demonstrate clojure. Does anyone know what I'm talking about?
Yes, James did some great live coding sessions like this a while ago, great to bring them together. I did a short version of one of his examples to show how to use Cider and the Cider inspector https://www.youtube.com/watch?v=rQ802kSaip4
;; coerce Character to String
(fn [s]
{:pre (pos-int? (Integer/parseInt s))}
(pr-str
(map (comp #(Integer/parseInt %) str) s)))
whoops, sorry, use #(Character/getNumericValue %) instead
oke, but the inout is a number not a string
I mean.. you can also count the length of the number.. and make a list that long by getting the remainders of the number and 10^x but that’s a bit convoluted
I like the original version - eg. to get a base other than 10 it only requires changing a constant
he my posts is gone
I have used the code like this :
(->> number
(iterate #(quot % 10))
(take-while pos?)
(map #(rem % 10)))
you need a reverse on that though
So is there something special I have to do to make sure my clojure / lein program can access all my linux box environment variables? I am trying to run google translate on my remote box and I keep getting 403 invalid API key even though I have run export GOOG_APP_CREDS = /path/to/file
... the api key works on my local box ;/
System/getenv can see everything that your process sees, it shouldn't even be an issue on the java / clojure side
That's what I was thinking.
Hmm. perplexing
for debugging: (pprint (into {} (System/getenv)))
it might be that it needs the System property to be set
or that it's using some config instead of the environment
depending on how you start an application, it may not be running your shell startup environment
gasp. is no there in the pprint list.
"export" is for the current shell and child shells, you need the export to happen in the parent of the java process - I usually prefer to add the env var as a prefix on the java command itself
Hmmm okay... what's that look like?
FOO=bar java ...
or env $(cat env_file) java ...
brilliant
thanks
you saved me a lot of headscratching
maybe 2 miles worth of headscratching if calculated by finger travel
you can also access the environment of other processes if you have permission
user=> (-> (slurp "/proc/self/environ") (s/replace (String. (byte-array [0])) "\n") println)
("self" is the magic directory for the current pid, you can use an arbitrary pid there)
How do you deal with async methods in repl based development? Let's say I have a method that returns immediately and calls a callback when done, I can't evaluate it in the repl because I won't be able to access what is passed to the callback
@ggfpc12495 you can call def, or deliver to a promise, or swap! on an atom
(cmd)user=> (def p (promise))
#'user/p
(ins)user=> (.start (Thread. (fn [] (Thread/sleep 10000) (deliver p 42))))
nil
(ins)user=> @p
42
that ten second delay should be long enough to see the pause happen in a repl
@ggfpc12495 if your app design is consistently async, core.async can help keep things a little simpler (but it also imposes a number of constraints)
Your approach makes sense to me, but then are we not changing our code to fit a specific development process?
oke, accordingt o the test I do not. All tests are green with this code
I don't have much experience with Lisps but it feels weird coming from a Java world to do that
java is full of bizarre "patterns" that shoehorn models into a dev process
@ggfpc12495 on a slightly less glib note, clojure does tend to encourage a specific kind of design that makes repl usage easier, but in most cases this can be done in a way that is also decoupling concerns
the real thing to avoid is coupling things because it makes dev simpler without regard for your domain (DI / factories etc. can do this as easily as decomposing for repl usage does)
your adaptor might look like a function that takes a callback and returns a new one that also sets a promise, for example
user=> (map #(rem % 10) (take-while pos? (iterate #(quot % 10) 123)))
(3 2 1)
i know
but I have to calculate if a number is a amstrong number and those tests are still green
so it seems that this is reversed does not make a difference
Thanks will look into your suggestions
here's a minimal function which takes a promise and a callback, and creates a new cb that captures the value the callback sees
(ins)user=> (defn tracked-cb [p f] (fn [& args] (deliver p args) (apply f args)))
#'user/tracked-cb
(ins)user=> (defn printing-cb [x y] (println "callback:" x y))
#'user/printing-cb
(ins)user=> (def p (promise))
#'user/p
(ins)user=> (def cb (tracked-cb p printing-cb))
#'user/cb
(ins)user=> (.start (Thread. #(cb :a :b)))
nil
user=> callback: :a :b
(ins)user=> @p
(:a :b)
in general a lot of mocks / stubs / dependency injections can be replaced with regular functionsa promise (as a let binding rather than a def most likely) can similarly be used in tests - dual benefit that the value isn't ready until the promise is delivered to so the test won't do its comparison until the async result is ready
I have done this course: https://www.jacekschae.com/courses/learn-reagent-free/21668-components/57007-04-creating-components
are there more free courses . I find this one also a lot about clojure and not much about components and so on
You could always setup a function (I've called mine spy
) that is able to wrap any other function and logs inputs and outputs. No reason you couldn't also get it to reset! some atoms of input and output if it's not a nice readable results.
(defn spy [f]
(fn [& args]
(println "--------------------------")
(println "calling callback" f "with:")
(clojure.pprint/pprint args)
(println "--------------------------")
(let [o (apply f args)]
(println "--------------------------")
(println "callback" f "returned:")
(clojure.pprint/pprint o)
(println "--------------------------")
o)))
=> #'user/spy
(defn async-method [millis callback-fn]
(future
(Thread/sleep millis)
(callback-fn millis)))
=> #'user/async-method
(defn callback [millis] (println "In callback after" millis))
=> #'user/callback
(async-method 1000 (spy callback))
=>
#object[clojure.core$future_call$reify__8439
0x4f45e549
{:status :pending, :val nil}]
--------------------------
calling callback #object[user$callback 0x4ac10f16 user$callback@4ac10f16] with:
(1000)
--------------------------
In callback after 1000
--------------------------
callback #object[user$callback 0x4ac10f16 user$callback@4ac10f16] returned:
nil
--------------------------
i think i solved all those exercism-clojure problems, most anyway, if you want a reference.
https://github.com/tschady/exercism-clojure wouldn’t want to post spoilers, up to you.
oops, just seen this is basically what was already suggested in another thread!
but my armstrong is pretty concise.
my clojure was more naive then, so YMMV
oke, and are all your answers approved by a mentor ?
i don’t understand
in exercism you can do the mentored track and a practice track
which one did you do ?
I’m trying to make log/info and log/debug to show in my terminal, but I’ve got this error: ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console... this is the code/project https://github.com/runopsio/sequence/blob/master/src/decimals/dynamodb.clj#L55
java logging config is severely brittle and counterintuitive, the big picture answer is "you need to pick a logger, configure it, and ensure code you care about is hooked up to it", but the specifics are full of gotchas. The best answers will probably be java specific in presentation.
the two stable outcomes I've seen are "magic .properties fill in resources that nobody touches" and "complex clojure.tools.logging code that nobody touches"
You need to look at the deps tree, but my guess is something is pulling in log4j2, and tools.logging is defaulting to using that, where it looks like the project is trying to use logback
is there a simple print or console.log (from js) but in clojure?
I just wanna introspect some variables to understand this code
There are many
prn or println are maybe the most common
*out*
gives you access to a PrintWriter that writes to stdout by default, *err*
to stderr
neither. it was 4 yrs ago, I just downloaded all the separate _test.clj
, put them in 1 project and made em pass. from e.g. https://github.com/exercism/clojure/blob/master/exercises/armstrong-numbers/test/armstrong_numbers_test.clj
Hello, are records in use in the wild or maybe maps are more popular these days?
there's a really good flowchart about this, but the tl;dr is that everything is designed so you can write code using maps, and convert to records / types / generated classes etc. when you know you need it
aha,I do the mentored one so mine soutions get looked at my a xp person in clojure
https://github.com/cemerick/clojure-type-selection-flowchart
It's worth noting that Clojure Applied talks up records fairly heavily but the author (Alex Miller) has said that if they do a 2nd Ed he would deemphasize records quite a bit and lean more heavily on plain hash maps.
Records are in use in the wild, and maps are more popular, there are good reasons for both. Use maps, and switch to records when you have millions of maps with the same keys.