This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-27
Channels
- # announcements (10)
- # aws (11)
- # beginners (158)
- # calva (8)
- # cider (14)
- # clj-kondo (1)
- # cljsrn (1)
- # clojure (83)
- # clojure-europe (5)
- # clojure-italy (25)
- # clojure-nl (3)
- # clojure-spec (12)
- # clojure-uk (20)
- # clojurescript (72)
- # community-development (18)
- # core-async (4)
- # core-logic (19)
- # cursive (11)
- # datomic (21)
- # duct (6)
- # events (1)
- # figwheel-main (3)
- # fulcro (15)
- # ghostwheel (1)
- # jobs (1)
- # leiningen (16)
- # off-topic (45)
- # onyx (3)
- # pathom (7)
- # perun (1)
- # ring (3)
- # shadow-cljs (48)
- # spacemacs (10)
- # specter (1)
- # sql (24)
- # tools-deps (7)
- # vscode (7)
- # xtdb (14)
Okay I have another really noob question. I have this data structure how do I loop over it in clojure. Coming from C# with foreach and I have tried elixir and the have "Enum.*" for everything just trying to see how you do it here.
(#clojure.data.xml.Element{:tag :COUNT, :attrs {:Records "3312"}, :content ()}, #clojure.data.xml.Element{:tag :COUNT, :attrs {:Records "3312"}, :content ()}.#clojure.data.xml.Element{:tag :COUNT, :attrs {:Records "3312"}, :content ()})
I figured this out. I had to map over the collection and then I could deconstruct the object.
@UT3PD0UGY It's a sequence of records which you can treat like a sequence of hash maps (as you've discovered).
@U04V70XH6 I'm trying to filter on a attribute with filter but keep getting error because of the type clojure.lang.LazySeq I'm using the clojure.data.xml lib and parsing a string with xml/parse-str. How to I make it not lazy ?
You have (data)
but you want data
-- you can't "call" a collection.
Also, you can't access a member of a sequence: (:tag data)
You want (:tag %)
inside the filter function instead of tag
Also, the :tag
element of each record is a keyword, not a string, so looking for "DATA"
will not find any matches.
You probably want #(= (:tag %) :DATA)
if that's the tag you are looking for.
Yup, in Clojure parentheses are not for grouping, they indicate function calls.
In C#, if you have obj.method(arg1,arg2)
, in Clojure you'll have (method obj arg1 arg2)
Happy to help. Welcome to Clojure! 🙂
BTW, you can use triple backticks around code to make blocks of it easier to read
like this
rather than single backticks like this
You may need to change the *When typing code with , Enter should not send the message. With this checked use ShiftEnter to send. * option in the "Advanced" settings.
Looks like you're an hour ahead of me -- Mountain Time?
Cool. My wife lived in Boise growing up.
Yep that is where I'm from. Grew up here. Now I live in a small town about 40 min west of Boise
tearing my hair out over here; i have [org.ode4j/parent "0.4.0" :extension "pom"] [org.ode4j/core "0.4.0" :extension "pom"]
in my project.clj
, and yet cannot for the life of me (import org.ode4j.ode.OdeHelper)
in my init-ed-ns
i've even gone so far as to pull in commons-lang3
and can use eg EscapeStringUtils
just fine
I don't think Leiningen can pull in bundles based on a POM -- I think you need the whole series of subprojects listed as dependencies explicitly.
(although you might try :classifier
instead of :extensions
just to see if that works)
@benkay a lil late but... is it possible you need to (import org.ode4j.ode OdeHelper)
instead of (import org.ode4j.ode.OdeHelper)
? at least that's how it seems to work with (ns ...)
this prefixing syntax requires an extra collection, and will error as you have it here
user=> (import File)
Execution error (ClassNotFoundException) at .URLClassLoader/findClass (URLClassLoader.java:381).
user=> (import ( File))
.File
ah maybe not needed if you are importing just one thing.
How do people normally track the progress of large collection of asynchronous requests?
I’m using clj-http
and mapping over a collection of 2000. This does 2000 asyncronous requests and I would like to track progress of it somehow.
I’m currently looking at manifold
and thinking I need to build a queue? Of some sort. From that maybe I could ping the queue every second to track progress?
https://clojureverse.org/t/does-clojure-have-scrapy-like-framework-for-web-scraping/3957/2
What would be the tradeoffs between say clj-http
+ core.async
+ transducers
(transducers I know little about at the moment) and the one below. That borkdude uses which is aleph
+ manifold
.
I will shortly release the new version of Skyscraper: https://github.com/nathell/skyscraper
I’m not so much interested in web scraping but how I’m to handle the asyncronous requests I am making
Does anyone know how to translate the fib example in this article http://jelv.is/blog/Lazy-Dynamic-Programming/ to clojure? I have tried and failed miserably. Either suggested version, or both, would be interesting to see. I found my functional code doing dynamic programming tends to end up quite ugly so I'm looking to learn some better techniques for it.
there are a bunch of variants of fib in Programming Clojure in Ch 4, although the push there is really to turn it into a lazy tail-recursive sequence, not to use memoization
this page has a bunch too https://rosettacode.org/wiki/Fibonacci_sequence#Clojure
including a memoize one
Thank you! Both seem like great resources, and I have already considered getting Programming Clojure so I guess now is the time.
Doesn't memoize cache every past result? I wonder if there's a way to use some partial memoization so it doesn't overflow.
you can use the core.memoize (+ core.cache) libraries to get more control
That's awesome. Thanks for pointing it out. I guess https://github.com/clojure/core.memoize/wiki/Fifo should allow a competent implementation of fibonacci. Though it's just too much complexity for a problem this simple
@sam.hedin Have you considered memoize
? That way you can implement the straightforward recurrence using a recursive function. It might be a bit more overhead but often gives simpler code.
Hmm, yes. I somewhat overlooked it because I once had a teacher say that memoization isn't the big boy way to do it (it being more caching than "regular" dp), but that is maybe an irrelevant detail when it comes to actually writing code that just does its job. I should probably let go of such details and start using memoization. Thanks!
> #Logging_in_prod: New to clj and not sure about logging in production apps, in a java world i'd wrap most of my methods with
{
logger.debug("starting method to embrace %s", rightIdioms)
....doSomething()....
logger.debug("successfully embraced %s idioms", idioms.length)
}
From what I can see in clojure, adding logs with 'start-end' fmt will force me to use more 'do' and 'complicate' my code instead of just returning values.
what are some common idioms of logging in clj? ty!@ghadi What would be a good-practice-clj in your opinion?
this is false, because every fn / defn / let etc. has an implicit do
you can still return values
ofcourse, but it adds clutter
what I'm saying is it looks the same in clojure as it does in your original, clojure doesn't enforce lack of side effects and the proper bodies (functions, let blocks, reify method blocks etc.) all have implicit do
I added a Q to SO so this will maybe useful for others :: https://stackoverflow.com/questions/60019148/idiomatic-logging-in-clojure you are welcome to reply aswell
I use org.clojure/tools.logging
which wraps around slf4j
(amongst other implementations such as log4j2)
@aviv logging is a side-effect, and Clojure expressions return values, so there is a tension there that you are pointing out
Then I simply have (log/infof "Starting a [%s] Foobar using [%s]." param-1 param-2)
I don't find text-based logging nearly as useful as I did 5 years ago, and now I prefer things like clojure.core/tap>
when doing things locally, or tracing facilities like Honeycomb/X-Ray when in prod
@dharrigan there's a wonderful keynote from Bradford Cross at an early Conj where he talks about unstructured logs and how it supports a nonsense $1B log parsing industry
(log/infof "Starting a [%s] Foobar using [%s]." param-1 param-2)
instead of that ^
(emit {:foobar/start ... :params [...]})
I would be interested to know more about tracing, esp http requests and the time it takes to service them - so looking at http://honeycomb.io / x-ray
@ghadi of course, that's why I asked the question, let's open a thread on it
Hello 👋 How do you do declarative/functional iteration without a collection? For example, I want to iterate base on the value 5
. I can only think of recursion as the only alternative to a for loop.
https://clojuredocs.org/clojure.core/range
(range)
is one way
range will create a sequence for you and you can iterate over it. There is dotimes if you just want some side effects without creating any temporary sequence. The benefit of range is it can be paired with most of the language constructs.
Sometimes, you will find clever ways to skip for/doseq/dotimes entirely, by using map/filter etc.
Thanks, helpful to know! I also found https://clojuredocs.org/clojure.core/repeat
repeat also creates a temporary sequence. So, if you repeat a billion times, and also hold onto the head of the sequence intentionally or otherwise, that's a lot of memory. Coming from imperative languages where the same memory location is updated again and again for iteration, this can surprise you.
Thanks Nate!
Hey all, I'm using CIDER but for some reason I can't jump to definitions, what could I be doing wrong?
my project uses Lein
@papachan
cider-find-var
@papachan which function is that?
@papachan weird, I don't have that
@papachan I feel like it's dependent on project
@papachan I do cider-jack-in-clj and it flat out doesn't work
now i always start projects with C-c C-x j j
with lein or with clj deps.edn. But yeah i tried with lein and it worked. i have cider version 20200120.711
How do I eval the ns?
oh wow yeah
I just assumed it would kick me into that ns
thanks guys 😄
i tried it myself - when i eval the relevant buffers C-c C-k
- then the M-.
is working as expected, thanks
Hi! I’m new with clojure and working with Luminus I need to restrict the access for specific routes. Following the luminus documentation I found what I need, but the template application (luminus with +auth) is a bit different. Now I want to understand where I’ll locate the configuration? I need to modify the defstate app-routes component?
(mount/defstate app-routes
:start
(ring/ring-handler
(ring/router
[(home-routes)(admin-routes)])
(ring/routes
(ring/create-resource-handler
{:path "/"})
(wrap-content-type
(wrap-webjars (constantly nil)))
(ring/create-default-handler
{:not-found
(constantly (error-page {:status 404, :title "404 - Page not found"}))
:method-not-allowed
(constantly (error-page {:status 405, :title "405 - Not allowed"}))
:not-acceptable
(constantly (error-page {:status 406, :title "406 - Not acceptable"}))}))))
(defn app []
(middleware/wrap-base #'app-routes))
Why does the following work as a solution for grouping anagrams: (group-by sort ["veer" "lake" "item" "kale" "mite" "ever" "holy" "ver"]) => {(\e \e \r \v) ["veer" "ever"], (\a \e \k \l) ["lake" "kale"], (\e \i \m \t) ["item" "mite"], (\h \l \o \y) ["holy"], (\e \r \v) ["ver"]} How do sort and group-by interact here?
user=> (group-by first ["veer" "lake" "item" "kale" "mite" "ever" "holy" "ver"])
{\v ["veer" "ver"], \l ["lake"], \i ["item"], \k ["kale"], \m ["mite"], \e ["ever"], \h ["holy"]}
group-by first collects all the strings that start with the first letter. group-by sort will group all the strings that have the same output when called with sort. In effect, its all the strings that are made of the same letters. which is why mite and item, lake and kale, etc. are grouped into the same partitionwhat is the common way to accomplish this in clojure (copy-keys sourcemap [:id :name :email])
=> {:id 1, :name "Jon", :email "
?
I have feeling something like this already exists and i just don't know how to find it. Thanks.
what does copy-keys do?
my hunch is the clojure version is select-keys
it isn't named "copy-keys" because we don't usually copy things in clojure, since we can assume they were immutable we just reuse them and that's safe
@noisesmith indeed thanks - works like a charm e.g. (select-keys {:id 2 :name "jakub" :zip 45603} [:id :name])
Thanks!
I’m reading in a file sent by my colleague. The file is produced by python (3), has as a Byte order mark, and linux $file text.txt
describes the file as Ascii. When I slurp the file I get spaces between each character.
(slurp "e:/test.txt" :encoding "UTF-8")
=>…M e c h a n i c
Notice the spaces between each character.
what makes you think the text is UTF-8?
so the spaces don't show up in a text editor?
xxd might help
I mean, opening test.txt directly outside clojure
figuring out encoding oddities based on repl output is usually not useful, because repls tend to be sort of best effort about those things, and you end up with multiple places where characters are being encoded and decoded and you have audit it all to make sure everything is in lock step
xdd or some kind of hex editor is a great idea, or even dumping the numeric byte values use read on an inputstream
a repl for whatever reason might display some characters as spaces that notepad or idea display as zero width
btw it's xxd
not xdd
(I make that mistake myself all the time) - it's easy to use and eliminates encoding ambiguities immediately
you need to look at the literal bytes to really determine the file contents to determine what the contents should be
you can also take the string you get from slurp and call seq and try get the byte value of one of the characters that is rendering as a space and look it up to see what character it is
(map int "some string value")
can be useful in such situations.
(map int (slurp ...))
does remove some ambiguity, but you're still getting the numeric values after the java methods turned the original encoding into UCS-16 and we can't take for granted that conversion was correct
so knowing the original bytes in the file is still useful
Right. Byte sequence of the raw file is needed, too. The (map int ...)
in Clojure is only useful as the "what came out of the sausage grinder" part of the issue.
This feels like a moment I should go google and read, but this is definitely a gap in my knowledge I’d like to fill. Here is the output of xxd on the first few characters. 00000000: 5045 5253 4f4e 5f49 4409 5049 4409 5553
If you can point me resources I’d like to learn more on how to understand this. (realizing this is likely a fundamental knowedge gap).
the weird thing here is that normal ascii thinks those .
are tabs
user=> (apply str (map char [0x50 0x45 0x52 0x53 0x4f 0x4e 0x5f 0x49 0x44 0x09 0x50 0x49 0x44 0x09 0x55 0x53]))
"PERSON_ID\tPID\tUS"
Assuming that is hex dump, hex 50 is the ASCII code for "P", so I don't see any byte-order marks there.
Not sure of a targeted resource specifically on debugging your issue. A few years ago I got interested in what Unicode was all about, and learned enough from Wikipedia articles on UTF-8 and UTF-16 and UTF-32 encodings to get the basic idea and some of the details. There is also a Wikipedia article on byte order marks that probably has more details than I ever retained in my head.
Given the Windows path name "e:/file.txt" you mentioned in an earlier expression, you are likely on Windows. JVMs have a default encoding they use for some file I/O operations, and that default can be different on different operating systems, and you can in some cases change it at JVM startup, I believe, via particular command line options.
In your case, I suspect that providing a particular encoding explicitly when you do the file I/O will be most robust across operating systems. I am a bit surprised that (slurp "e:/test.txt" :encoding "UTF-8")
still gives you the spaces.
What does the output of (take 20 (map int (slurp "e:/test.txt" :encoding "UTF-8")))
look like for you?
Or if you want to see hex to more easily compare to the output of xxd, you can try (take 20 (map (fn [c] (format "%02x" (int c))) (slurp "e:/test.txt" :encoding "UTF-8")))
instead