This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-22
Channels
- # announcements (5)
- # aws (38)
- # aws-lambda (21)
- # babashka (45)
- # beginners (87)
- # boot (1)
- # calva (32)
- # cider (23)
- # clara (7)
- # clj-kondo (41)
- # cljs-dev (29)
- # clojure (145)
- # clojure-europe (6)
- # clojure-italy (12)
- # clojure-nl (4)
- # clojure-spec (39)
- # clojure-uk (45)
- # clojurescript (171)
- # copenhagen-clojurians (4)
- # cursive (14)
- # datomic (48)
- # docker (6)
- # figwheel-main (2)
- # fulcro (54)
- # jackdaw (1)
- # jobs (1)
- # kaocha (3)
- # leiningen (7)
- # luminus (6)
- # malli (2)
- # off-topic (51)
- # pathom (8)
- # quil (20)
- # re-frame (14)
- # reagent (1)
- # reitit (2)
- # remote-jobs (1)
- # shadow-cljs (39)
- # tools-deps (1)
- # vim (12)
- # xtdb (5)
I have a couple questions about the package cache with tools.deps: • Is there a way I could copy a cache folder to allow for building on another machine without internet access? • Are package caches per-machine or per-project? Is there a way to re-use the same package cache for several projects (if that's not already the case by default)?
I've done some experimentation and it seems I can at least partially answer myself: The cache folder for maven packages does not change, it's always $HOME/.m2 (the default for maven). There is also .cpcache folder, which I assume is for other kinds of deps (git?) but I was mostly interested in mvn dependencies.
with tools.deps there are two conceptual entities: deps cache and artifacts. Deps cache is per-project cache of computed classpaths. Artifacts stored separately: normal maven jars - in globally configured maven repository, git-based deps in $HOME/.gitlibs
.cpcache doesn't cache the deps themselves, just the computed classpaths that point to the local cache of the deps (in m2 etc.)
it speeds up startup by allowing reuse of the classpath instead of computing it if the deps have not changed
Hi, in Clojure, are transducer
s (`eduction/sequence`) also chunked? Looking at the source, it seems yes, but double checking.
eduction
& sequence
sequences (i.e. when used as a seq
) are not chunked.
https://clojure.atlassian.net/browse/CLJ-2356
Hello, I am reading this article http://www.learningclojure.com/2013/02/clojures-reader-is-unsafe.html About danger of default reader. What is the best way to do the opposite thing - serialize data structures into a string?
there is also *print-dup*
that allows producing "unsafe-to-read" forms:
(binding [*print-dup* true]
(pr-str [String #'clojure.core/inc]))
"[#=java.lang.String #=(var clojure.core/inc)]"
So, lazy-seqs... How do I treat them correctly? I thought map
is lazy. But calling map
on a lazy-seq puts me into an infinite loop it seems...
No doall
or anything alike. Just using seq?
to see if it is a sequence, then map
, and the caller calls take 3
on the result.
I don't call print anywhere though. Just using the result of (take 3 (function-that-maps lazy-seq-thing))
in a test
(defn mainblock-inputs-gen [{:keys [input url] :as state} parse-fn & {:keys [fetch-fn]}]
(cond
(and (nil? input) (or (keyword? url) (string? url)))
[(mainblock-url-fetching parse-fn url state)]
(and (nil? input) (or (coll? url) (seq? url)))
(map #(mainblock-url-fetching parse-fn % state) url)
(string? input)
[(parse-fn input)]
(coll? input)
input
:else
[input]))
with url
being the lazy sequence.If url
is a lazy seq of lazy seqs of lazy seqs ad infinitum, it will be an endless recursion.
Are you sure that's the infinite loop though and not just mainblock-url-fetching
never returning?
Yes, in the test, I've set mainblock-url-fetching
to (fn [parse-fn url _] (parse-fn url))
and parse-fn
to identity
Well, I just tested it with url
being (range)
and just called (take 3 ...)
on it. It works perfectly, no infinite loops.
No, identity
gets called inside the mainblock-url-fetching
which gets called inside the map
looks like it's not your map, but rather you trying to put mainblock-url-fetching into a vector
so mainblock-url-fetching is effectively (identity url) according to your description
now replace [(mainblock-url-fetching parse-fn url state)]
by (mainblock-url-fetching parse-fn url state)
Hmmm I think I found the problem... The function generating the lazy sequence returns a map containing the lazy seq, not the lazy seq directly...
Yes, use a coordinate like {:local/root “/path/to.jar”}
Hello guys, anyone messed around with https://github.com/FundingCircle/jackdaw ? I installed confluent CLI and start the repl. then loaded the pipe example
user=> (ns pipe)
nil
pipe=> (confluent/start)
Syntax error compiling at (/private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/T/form-init10224179169549008804.clj:1:1).
No such namespace: confluent
What do I miss?There's actually a separate #jackdaw channel that some of the FundingCircle guys lurk in - they're good at responding too.
this is a regression in the example, I'm going to see if I can find the correct namespace in the edit history of that ns
OK - the example never worked, I'll ping the author
I'm certain the confluent
in the confluent/start
referenced here is this file, if you just load it before pipe.clj it should work https://github.com/FundingCircle/jackdaw/blob/7403f8714f4b77573be03ac69368200d856fa902/examples/dev/confluent.clj
I think that the old confluent.clj became this system.clj https://github.com/FundingCircle/jackdaw/blob/master/examples/pipe/dev/system.clj
worth a try!
I added this - if I get some free time I might attempt the fix since I have access to the repo https://github.com/FundingCircle/jackdaw/issues/222
Thank you very much. I made a lot of progress in setting this up. Anyway, I try the word-count.clj example now, and I found some errors there too, I make a post about it in #jackdaw .
oh, nevermind, I succeeded 😄
please do follow up on my bug ticket above with what worked if you have a chance! I didn't get around to digging deeper into this yesterday
well it didn’t, I started confluent separately, and moved to the word-count example, and that one worked well with clj -A:dev. Now I can learn more about it.
What are some good Clojure books for someone who is not completely new to the language, but also haven't fully grokked it? (Yes, I.) I enjoy 4clojure and other puzzles, but feel the need for something more systematic. I don't mind if it gets advanced, but it needs to start reasonably basic. And if there is some video course that I should consider, those tips are welcome as well.
(btw. Packt Publishing has an offer right now, many ebooks for $5, also Clojure!)
Not much but maybe one can find something useful there https://www.packtpub.com/catalogsearch/result/?q=clojure
Are the clojure books available on packt good? IME the quality of their books is usually questionable
I really liked https://www.amazon.com/Professional-Clojure-Jeremy-Anderson/dp/1119267277, unlike many of the other introductory/mid-level clojure books it's more focused on the application side and has a lot of hands on examples with full-stack development. The Programming Clojure book (https://www.amazon.com/Programming-Clojure-Pragmatic-Programmers-Miller/dp/1680502468/ref=sr_1_2?keywords=programming+clojure&qid=1579709713&s=books&sr=1-2) was also fantastic, and is a step above in difficulty than Getting Clojure
Zack Tellman's book is excellent as well: https://leanpub.com/elementsofclojure
+1 on Programming Clojure (by @U064X3EF3). I'm a Scala programmer, so not completely new to functional or the JVM and found it hit the sweet spot. I've also read Elements of Clojure and found it more thought provoking than immediately useful. I'm in the middle of Getting Clojure and I'm finding it a bit too basic for me.
“Elements of Clojure” is more of a best-practice and patterns book, isn’t it? @U06DEA21F
I mostly stopped reading programming books years ago (I have a ton of O'Reilly books), but since I'm doing Clojure as a side project and all by myself, I feel I need a bit more of an overall feel/high-level guidance than what you get in random StackOverflow posts.
Oh yeah Elements definitely transcends just clojure, highly recommended. It provides guidance in the less instructory aspects of a language, like idioms, higher level design, and I particularly liked its section on understanding abstraction. Lots of fun references to completely non-programming texts and interesting reads from philosophy and social theory that have surprising connections to programming in clojure.
@U4E39A29Y yes, and realistically it's stuff you pick up as you gain experience as a while, written very well
it's probably the second book I'd give to a new hire after they've gained some experience in the language
Surprised no one mentioned Clojure Applied
@U04V70XH6 Clojure Applied is good as well, I'm partial to the cover, most of these weren't out when I started Clojure so I don't know how great they are from a 'getting started' standpoint
Clojure Applied is good for someone with some Clojure background, wanting to get more advanced/real world insight.
I pretty much just buy every Clojure book out there (except the Packt stuff, most of which is awful).
Programming Clojure -> Clojure Applied as the details books. Joy of Clojure -> Elements of Clojure as the rationale/ideas books. Recommend doing the both in parallel.
@UQY3M3F6D, I have watched two of the free videos now. I love the pace. Video/audio resources can sometimes stress me up, because they go a bit too slow. Not these. They are to-the-point and zero-nonsense. There is a pause button there, after all. Really good work, @U07FP7QJ0 ! (I can't afford the payed tier right now, but hopefully my next employer will realize how smart it would be to give me full access.)
And thanks all of you here for all this input! I've started with Brave online. It allows me to fast forward to the pieces that are missing for me. But I see more tips here that I will follow up on.
Have you filled out the 2020 State of Clojure Community Survey yet? It's a great source of info in understanding the community, and we'd welcome your participation if you have a few minutes. https://surveymonkey.com/r/2020clojure
#object[java.util.Locale 0x28caec3 "nl"]
is the 0x28caec3
the hashcode?
Answer: no
user=> (import 'java.util.Locale)
java.util.Locale
user=> (def l (Locale. "nl"))
#'user/l
user=> l
#object[java.util.Locale 0x562fcb0 "nl"]
user=> (.hashCode l)
104804738
But what is it?
Makes sense
More convincing 😉
Thanks!
Maybe this should have been posted in the beginners channel - bear with me:
From https://clojure.org/guides/learn/syntax: "Many languages have both statements and expressions, where statements have some stateful effect but do not return a value. In Clojure, everything is an expression that evaluates to a value. Some expressions (but not most) also have side effects."
When I read this, I get the impression that Clojure does not have statements, but isn't
(def x (+ 3 4))
equivalent to a statement?
Right, but is is the side effect that we are interested in?
it is the side-effect that we are interested in, yes. that's true lots of times. like when we call println
however it's not true "most" of the time. in most well written clojure programs I would say it's probably only true <1% of the time
eh, maybe <10% of the time I guess if you include def
defn
and ns
which as you correctly note are useful for their side-effects
I mean: using def
is not very "pure" to me
(pure functional)
but practical, I guess
https://clojure.wladyka.eu/posts/when-use-exclamation-mark/ this is in the topic of side effects. Maybe will be useful.
I am very wrong about definitions but in Clojure data is code and code is data, so:
(foo 1 2 3)
is a list
where first item is a name of the function. But you can generate the same list
by other function and run it as you expect or threat as a data only.
My point was only, that I suspect def is used a lot to hold state
(def hostname (-> (InetAddress/getLocalHost)
(.getHostName)))
^ example of dynamic thing during start the app
But in most cases (def conf-status #{3 5})
etc.@U050ECB92: thanks 🙂
I am used to OOP and a newbie in functional programming, so that kind of advice is worth remembering
@USNL3G7GE it's not that clojure doesn't have side effects, it that clojure has no forms that don't return a value
these things are related, but it's a nuance - you can say (def foo-var (def foo 42))
- foo-var holds the var that holds foo
@@foo-var returns 42, @foo-var returns a var that currently holds 42, but could hold something else later
that's not really what you asked - a lot of things return nil, you can use for example (let [x (f 1) _ (println x) y ...] ..)
and clojure doesn't error about the println in a binding context - it returns nil, which is a valid thing to bind to
but don’t bother too much about this theory, this is not something what you would think about during coding later. Things come naturally.
it's true
@USNL3G7GE the primary way this comes up: (let [x (if (f) 0 1)] ...)
- since everything returns a value, you can use if for a value instead of a side effect, which is very useful
I think you should bother about code structure - I cannot imagine that it is not possible to write programs in Clojure with a clumsy structure
@U050ECB92 Oh - I guess you meant that def
sets global state (and nothing else)
But I think global state should be minimized...(?) https://wiki.c2.com/?GlobalVariablesAreBad
sure, but you need at least one
(the usage)
the idea with def
is we don't use it for in-app logic, we use it for iterative debugging and development of a live system
in order to be productive as a programmer I want to be able to replace the buggy version of f (a globally visible function) with a new one, that's a mutation but it's not a mutation in my app logic, just my dev flow
Ohh - yes 🙂
So just dont redefine it 😉
Well, a mutable constant 🙂
I realize that isn't necessarily clarifying anything for someone just learning it, but it really is mutable, since you can change it at run time. It is considered good style/practice to def a function at run time when developing, to fix things or try things out. It would be considered bad style/practice by most Clojure devs to do that in a production system, except perhaps in emergencies involving manual intervention by a live human, which is like the development time scenario.
And that last scenario would be considered bad practice by many developers.