Hi, Iβm sure I am using for
in the wrong way, but out of curiosity, is there a function to turn a nested list such as (([[#{...} #{}] [#{...} #{...}]]))
into something like [[#{...} #{}] [#{...} #{...}]]
? the function flatten
gives a different result. Thanks
ffirst
?
that would work for your particular example. I don't know whether you have a more general pattern in mind. if so, please give an example where ffirst
wouldn't work
ffirst
seems to work, thanks @euccastro π
If I want to curry a function with 2 arguments, supplying the second argument, partial won't work. Is there anything that allows partial application of out-of-order arguments?
@michael819 That's what anonymous functions are for. And Rich Hickey says they are more idiomatic than partial
anyway. #(f % 42)
for a literal of f
with the second argument provided.
@seancorfield Thanks.
The difference between and @ is , is used to unquote variables and @ used for collections, Is my understanding correct?
@kumarshantanu the only difference between ~(+ x y)
and (+ ~x ~y)
is when the + call happens (during list building, or later when the compiled object is run) - the same variables are added in both cases (but they might have different values later)
You could also use ~
for whole expressions, as long as itβs just one expression.
ok, But my above understanding is correct?
Yes
Thanks, can you give example for expression? is that ~(+ x y)
inserts a single thing (possibly a collection too!) and @ splices a collection
see
user=> (def a [:a :b :c])
#'user/a
user=> `(1 2 3 ~a 4 5)
(1 2 3 [:a :b :c] 4 5)
user=> `(1 2 3 ~@a 4 5)
(1 2 3 :a :b :c 4 5)
@popeyepwr Yes, ~(+ x y)
is a correct example (assuming x and y resolve).
here a
is a variable and it evaluates to a collection
@kumarshantanu both (+ x y) and (+'x 'y) gave error after assigning x and 7 as 5 and 7
@popeyepwr When you use ~(+ x y)
in a macro, x
and y
should be resolvable at compile time. To make it resolve at runtime, you need to use (+ ~x ~y)
.
can you paste the whole expression? ~ is supposed to be used within a quasiquoted (i.e., preceded by a backtick) expression
@euccastro @kumarshantanu, That helped, Thanks π
user=> (def x 5)
#'user/x
user=> (def y 7)
#'user/y
user=> `(:a :b :c ~(+ x y) :d)
(:a :b :c 12 :d)
user=> `(:a :b :c ~(+ 'x 'y) :d)
Execution error (ClassCastException) at user/eval1 (REPL:1).
class clojure.lang.Symbol cannot be cast to class java.lang.Number (clojure.lang.Symbol is in unnamed module of loader 'app'; java.lang.Number is in module java.base of loader 'bootstrap')
the second case is an error because you are trying to add two symbols
` suppresses evaluation, ~ reenables it
you'd get the same error if you just tried to evaluate (+ 'x 'y)
, without using backquote or ~
at all
Hey there, I have some endless seqs of natural numbers, and I want to find the lowest number that is in all seqs. I'm not sure how to do it in a smart way. I could iterate through all natural numbers and check if it checks true for all the generation rules, but the final number is huge, so this will take a really long time. I'm sure there is a number-theory trick as well, but my residue system knowledge is not that good.
(def x0 (iterate #(+ 7 %) 7))
(def x1 (iterate #(+ 13 %) (+ 13 1)))
(def x2 (iterate #(+ 59 %) (+ 59 4)))
(def x3 (iterate #(+ 31 %) (+ 31 6)))
(def x4 (iterate #(+ 19 %) (+ 19 7)))
You could try the Chinese remainder theorem: https://en.wikipedia.org/wiki/Chinese_remainder_theorem
If you scroll down to Existence (direct construction)
, you can use that formula. You need to find or implement an extended eucledian algorithm to calculate M_i
and m_i
though. Other than that, the formula can be calculated within reasonable effort.
here's how you would implement it: https://brilliant.org/wiki/chinese-remainder-theorem/
(and yes, those numbers are coprimes)
there's #adventofcode too π
Oh, I haven't seen this channel, thanks π
I was hoping to solve it myself. I feel like cheating, now that I have a hint.
Hint might be more of a solution...
there's still some work to do
but I think that particular puzzle requires knowing that particular bit of number theory. if not, I don't think you can solve it in any other way than rederiving the theorem yourself, which is a bigger ask than any of the other AoC puzzles
I'd love to finish all days and discuss the solutions with others, is there some division of aoc divided by days?
I even watched some youtube videos on modulo-ring-theory but they did not mention the chinese theorem
there are per-day threads in that channel. unfortunately some are old enough that you can't see them unless you have a paid Slack account
I remember having seen it when studying discrete math, but when I got to solve that puzzle I had already seen the spoiler, so I'll never know whether I would have recalled it on my own..
So far I only had problems with the second adapter in plane part. I do these to learn clojure and it feels bad, when my math knowledge is blocking the path and not the understanding of clojure.
I'm excited to finish it π
Thanks for the channel and the method hint
I think that particular puzzle is the only one where math is a real blocker. in others math insights may get you a faster answer, but problems are still workable if you miss them
I am trying to solve this problem on codewars: "Complete the functionΒ `scramble(str1, str2)`Β that returnsΒ `true`Β if a portion ofΒ `str1`Β characters can be rearranged to matchΒ `str2`, otherwise returnsΒ `false` " - But I am unsure how to approach it. I first did the naive thing and made both strings into sets. However that was not a possible solution, since if a specific character is repeated twice in str2 and only once in str1, then it should return false. Such that: (scramble "javscripts", "javascript") => false
. Then I tried a solution of counting the characters and keeping the count in a dictionary. Then by using merge-with and the "-" function I could maintain if a character appeared more often in the str2
string. I tend to overcomplicate these things a lot and was wondering if there are smarter ways to do this? - This is my code so far
(defn character-count [st]
(reduce #(assoc %1 %2 (inc (%1 %2 0)))
{}
(re-seq #"\D" st))
)
(defn scramble [s1 s2]
(let [s1-count (character-count s1)
s2-count (character-count s2)
total (merge-with - s1-count s2-count)
]
(not (> (count
(filter false?
(for [[k x] total
:when (or (< x 0) (not (contains? s1-count k)))
]
false)))
0))))
Link to task: https://www.codewars.com/kata/55c04b4cc56a697bb0000048/train/clojureI realized that I could have used frequencies instead of the character count function
Hi, I installed CLJ CLI tools on Ubuntu via the following http://clojure.org scripts. How can I uninstall it and remove its dependencies from my system?
"Use the linux-install script to download and run the install, which will create the executables /usr/local/bin/clj, /usr/local/bin/clojure, and the directory /usr/local/lib/clojure:"
curl -O <https://download.clojure.org/install/linux-install-1.10.1.727.sh>
chmod +x linux-install-1.10.1.727.sh
sudo ./linux-install-1.10.1.727.sh
There's no need to walk the entire collection in (not (> (count (filter pred smth)) 0))
-- it's better to use some short-circuiting function like some
, not-any?
etc.
Also, in this particular case, there's no need to check all values in total
afaics -- you only need to check the keys of the second map to both be present in the first and have compatible value.
what do the closures do here :
Instead of using a lazy list, imagine two threads are removing tasks from a pile of work. Our work pile will be the list of all integers from 0 to 10000:
user=> (def work (ref (apply list (range 1e5))))
user=> (take 10 @work)
(0 1 2 3 4 5 6 7 8 9)
And the sum will be a ref as well:
user=> (def sum (ref 0))
Write a function which, in a dosync transaction, removes the first number in work and adds it to sum.
Then, in two futures, call that function over and over again until there's no work left. Verify that @sum is 4999950000. Experiment with different combinations of alter and commuteβif both are correct, is one faster? Does using deref instead of ensure change the result?
I find this a confusing challenge of the "clojure from the ground up" bookwhat closures?
I have to make a function and then the text is saying need in two futures to do something but I do not see what the closures should do and wy I need 2 of them
I think you need two futures to test the thread safety of the ref/dosync mechanism
i.e., that they do the right thing despite contention
the futures just call your function (closure) over and over until (empty? @work)
oke, so both futures do the same , call the function till work is empty
When trying to use https://github.com/thi-ng/geom, when I try to require <http://thi.ng|thi.ng>.geom.viz.core
In my large project I keep getting the error namespace '<http://thi.ng|thi.ng>.color.core' not found
. It works fine in an otherwise empty skeleton project. Any hints as to what might cause this?
Can I the best develop in WSL or can I also do everyhing with Windows ?
I do everything in regular windows (https://github.com/littleli/scoop-clojure makes it easy for me). I've heard good things about WSL2 but haven't tried or needed it personally to do everything in clojure
there's a #clj-on-windows channel that is helpful too
Figured it out. It was a conflicting prefer-method
in my project and http://thi.ng.color.core
@roelof WSL is very good if you are used to the Unix command line. Also VS Code has some integration with WSL, making it easier to use with the Calva extension for VS Code.
it doesn't install any dependencies, but it does install clj and clojure to /usr/local. it also creates some dot directories for cache and settings at runtime of clj and clojure, including ~/.clojure
and ~/.m2
which is shared by other applications using the maving package system
I wonder if there's an authoritative list though
Hi. Does anyone here know how to get CIDER going in Doom Emacs?
(I have also asked this question in the Doom Emacs Discord channel.)
I don't know which is higher: The fraction of Clojure/ClojureScript programmers who use Doom Emacs, or the fraction of Doom Emacs users who program in Clojure/ClojureScript.
Heart of the question is whether uncommenting in the "clojure" line (which sits commented out along with lines for lots of other languages etc by default) in the init.el file in the .doom.d folder (and running 'doom sync' of course) is enough. The loading stuff that triggered in Emacs seems to have included some mention of CIDER, but maybe it's a separate install??
By the way, that init.el file in the .doom.d folder refers to Doom modules, and I'm not clear on what those are. in vanilla init.el file: (defvar my packages '( [...] clojure-mode )) in doom init.el: (doom! :input [...] clojure ) ...but the vanilla config also contains a separate line just underneath: cider
I don't know how to use CIDER yet, but I do see that my doom emacs seems to recognize the 'cider-jack-in' M-x command (or whatever it is), so that in itself seems to prove the doom input clojure thing includes clojure-mode AND cider. Still, it would be nice to know for sure what a Doom Emacs module does.
Can anyone what is a good way to learn to make website's with clojure ? So any tutorials which I can follow or free books to read
@factorhengineering what channel in the Doom Emacs Discord? I think it's more appropriate there and I will try to help out
Someone in this channel might know, but there is also a #cider channel on this Slack community that might be a more knowledgeable environment for your questions.
@roelof Fulcro has lots of videos and a very in-depth book. But it's also a full buy-in framework which I consider very well thought out. This is what I think of when I read free and tutorials. A more simpler option would be to check the beta book of "Web Development with Clojure, Third Edition" but that's not free
there's also luminus, which is extensively documented (it's what "Web Development with Clojure" uses)
how dynamic variable is used in the immutable language ? data-readers
the language isn't immutable, vars are mutable containers
in particular, dynamic vars (which have names that are *earmuffed*
by convention), can be set in a way that's visible to functions you can call, without changing what parent functions see, this is called dynamic binding
we encourage immutable code (and our standard data collections are immutable) - we use dynamic binding because it's safer than regular mutation
@noisesmith Any example to understand it more?
(cmd)user=> (def ^:dynamic *verbose* false)
#'user/*verbose*
(ins)user=> (defn f [x] (if *verbose* (println "found" x)) x)
#'user/f
(cmd)user=> (f 2)
2
(ins)user=> (binding [*verbose* true] (f 2))
found 2
2
so what those vars are often used for is behaviors - where you want a changed behavior inside some block of code without having a config argument to keep track of
with *data-readers*
- the use case is that inside one block of code you are loading a config that uses specific readers
you don't want to change the behavior of all clojure's code that reads data, just the usage inside a specific context
so you use binding
to add / modify the readers, and you know the behavior is only being configured inside that binding block and the things it calls
binding
is based on the call stack, and if you use standard clojure functions, it even works when a new thread is created
(cmd)user=> (future (Thread/sleep 1000) (binding [*verbose* true] (f 2)))
#object[clojure.core$future_call$reify__8454 0x3703bf3c {:status :pending, :val nil}]
user=> found 2
(ins)user=> @*1
2
so for example the case where you had two threads that are each reading a config file, without a dynamic var either you need a complex coordination to manage the global configuration of the readers, or you need to add an argument to the read function that specifies the readers - someone decided that having a dynamic var was simpler
in practice, dynamic vars are used quite rarely in my experience
Yeah I understood @noisesmith, Thanks
what is @*1 ?
*1
is always the last value the repl returned (there's also *2
and *3
for the values before that
(ins)user=> "first"
"first"
(ins)user=> "second"
"second"
(ins)user=> "third"
"third"
(ins)user=> [*1 *2 *3]
["third" "second" "first"]
https://github.com/duct-framework/docs/blob/master/GUIDE.rst
@
is a reader macro that expands to a call to deref
user=> `@f
(clojure.core/deref user/f)
It won't answer all of your questions, but the Clojure cheatsheet can be a handy way to look up some things like that: https://jafingerhut.github.io/. https://clojure.org/api/cheatsheet
@popeyepwr your repl probably prints out an explanation of *1
etc. and other values like *e
at startup - most people don't read things like that though
(we are trained from many examples that big blocks of printout at the start of things are usually irrelevant, usually some kind of advertisement or legal boilerplate)
How would you describe the benefit of this
(into [] (comp (map fn-1) (map fn-2) ...) coll)
over this
(->> coll (map (comp fn-1 fn-2 ...)) (into []))
?
I was thinking that the second example doesnβt leave room in the comp for any filter/removes. Another thing I was thinking was that composing functions (comp fn-1 fn-2 fn-3)
leads to (fn-3 (fn-2 (fn-1 val)))
which builds a larger intermediate stack than what would occur in the first block for each value being processed.the benefit of the transducing version is that the ->>
version creates lazy seqs that aren't needed
the comp
version still builds up a stack, it just doesn't build the lazy-seqs between the stack levels
it actually builds and unbuilds the stack once per item, instead of once per function, but that's good because it's much cheaper than lazy-seq building
Thanks @noisesmith , For your detailed explanation, It helped me
(many people are used to "smart" compilers that automatically do things like removing unneeded intermediates, clojure intentionally avoids that kind of cleverness)
why do I get here a illigalState error message :
; Write a function which, in a dosync transaction, removes the first number in
; work and adds it to sum. Then, in two futures, call that function over and
; over again until there's no work left. Verify that @sum is 4999950000.
; Experiment with different combinations of alter and commuteβif both are
; correct, is one faster? Does using deref instead of ensure change the result?
(defn add-dosync[]
(dosync
(alter @sum4 + (first work) )))
(defn future1 []
(future(seq @work) add-dosync))
(defn future2[]
(future(seq @work) add-dosync))
thank you @noisesmith
@roelof what is the full error message?
@roelof also what is sum4
- for add-dosync to make sense it needs to be a ref to another container you can deref, which seems very weird
; Execution error (IllegalStateException) at ground-up.chapter6/eval14308 (form-init6272265265852733152.clj:88).
; No transaction running
also (future (seq x) f)
calls seq (which does very little) then returns f without calling it
moment
; Instead of using a lazy list, imagine two threads are removing tasks from a pile
; of work. Our work pile will be the list of all integers from 0 to 10000:
(def work (ref (apply list (range 1e5))))
; And the sum will be a ref as well:
(def sum4 (ref 0))
; Write a function which, in a dosync transaction, removes the first number in
; work and adds it to sum. Then, in two futures, call that function over and
; over again until there's no work left. Verify that @sum is 4999950000.
; Experiment with different combinations of alter and commuteβif both are
; correct, is one faster? Does using deref instead of ensure change the result?
(defn add-dosync[]
(dosync
(alter @sum4 + (first work) )))
(defn future1 []
(future(seq @work) add-dosync))
(defn future2[]
(future(seq @work) add-dosync))
(ensure sum4)
you can't alter the number 0
so first off, (alter @sum4 ...)
doesn't make sense
o, I was told by calva to check that work is not empty
(future nil f)
creates a delayed result that returns f
(future something-not-nil f)
creates a delayed result that also returns f
oke, So I have to change to (future @work add-dosync)
that derefs work, does noting with it, then returns a function
this isn't how future works at all
also your illegal state is on the last line (ensure sum4)
ensure is for making a transaction retry if its arg changes before the transaction returns
it doesn't do anything valid outside a transaction
yep, with deref
I get a answer of 0
right, because you never call add-dosync
you just create threads that return it (and never reference the threads again)
in fact, you never even reference the function definitions that would have created those threads (another problem with this code)
hmm back to the book (clojure from the ground up) to find out what I do wrong
that's a good idea
a simplified version: (future (f x))
calls f on x in a new thread - (future f)
doesn't do anything interesting
you probably got it mixed up with the way alter
works (where you pass it some place, and a function that alters what is in that place)
but you also got alter
wrong, by giving it the value in the place, instead of the place itself
So I guess its just a case of deleting the dot directories that I can find?
yes
sure - maybe someone else has the official doc on this (or, also possible, nobody made that doc)
thanks, this is a very difficult chapter
this is the repo for the installer if that helps - I don't see an uninstall or a document describing what it installs https://github.com/clojure/brew-install
if I understand you , I have to do something as add-dosyn <number>
but according to the challenge I have to do something in the function to add a number to the sum
and not in the future
oke, as you can see in later discussion I hit a lot of walls with this one
starting from the part of the code that seems closest to something that could work:
(dosync
(alter @sum4 + (first work) ))
it becomes something almost reasonable if we change it to
(dosync
(alter sum4 + (first @work)))
but there's still the problem that you also have to remove that first item from work so that no other call tries to use that same itemso that becomes, perhaps
(dosync
(alter sum4 + (first @work))
(alter work rest))
which adds the item to the sum, and removes it from work, and that's all in one transaction so you know that no other call to the same function used that item
but perhaps you (or the exercise author) had something else in mind - there's enough wrong in the code that I could be on the wrong track about how to fix it
thanks, I'll check it out, just had a reread of the docs on http://clojure.org; no sign of removal instructions there either
an empirical (but maybe silly) approach would be to make a minimal docker image with java, and run two instances. run the clojure installer in one of them, and find all the differences in the file system
that's probably too much work though
@noisesmith thanks
now I have to find out how to use that in the future
In the below code I assumed fun is evaluated if the input is positive and argument is between 16 and 225
(defn constrained-sqr [x] {:pre [(pos? x)] :post [(> % 16), (< % 225)]} (* x x))
Is my understanding right?
it will throw an AssertionError if the constraints are not met
it's evaluated up until the point one of the constraints fails
it returned value for (constrained-sqr 7) but fails for (constrained-sqr 17)
why so?
because 289 is greater than 255
the result should be less? i though it is arguent
:post
is a test on the result
(or rather, a vector of tests on the result which must all pass)
this gives still zero
(defn add-dosync []
(dosync
(alter sum4 + (first @work))
(alter work rest)))
(defn future1 []
(future @work add-dosync))
(defn future2[]
(future @work add-dosync))
(deref sum4)
if i pass 7, it should check for pos? right ... (pos? x)
right
then it tests if the return value is between 16 and 255, exclusive
%
in the :post
clause is a placehoder for what the function wants to return
(pos? x) should fail for input 7 right.. since it is not +ve value
user=> (pos? 7)
true
My bad sorry!!!! confused with even, My bad!!!!
Thanks @noisesmith
I'd consider it if I had any docker experience.. in the end I deleted ~/.m2
~/.clojure
and any dot directories I could find, then ran timeshift to restore my system to its pre- CLI tools state,
seems like a decent feature request for that repo TBH
thanks, I will look at that one
is there a LIFO stack based list-like type? I'm trying to keep the last 100 x's only
benny a LIFO stack can use a vector with conj
to add, peek
to look at the "head" and pop
to remove the "head" (it actually uses the backend of the vector, not the front end). But "keep the last 100 x's" only sounds more like a FIFO queue to me (where you would pop off the oldest item once you hit the queue limit). There's a clojure.lang.PersistentQueue
for that.
@b ^
@seancorfield oh yes, thanks! FIFO is right π
Are you queueing work or just keeping a collection of things?
@emilaasa just keeping a running tally of events and when a certain trigger happens I want to dump the last 100 events
Sounds like a good use for PersistentQueue! Just wanted to make a quick shoutout to java.util.concurrent which also has a lot of nice data structures for queueing work and orchestrating programs in general.
Hi all! How would you do IPC in Clojure?
@marcus.akre "It depends". Is this communication only ever going to be between two Clojure processes, or might other tech be used at any point for one or more of these processes?
clojure only.. on same machine
There is no single "best" answer to how to do IPC in general but there are lots of possible solutions depending on what sort of trade offs you want to make. Is this bidirectional or more client/server? How robust does it need to be in the face of network issues? What about latency considerations? How large are the data packets you want to exchange? Maybe using a shared database and polling is a reasonable choice. Maybe using an external message queue service is a reasonable choice. Maybe using a REST-style API is appropriate.
Since you say Clojure only on the same machine: are these processes in separate JVMs or could they both run within the same JVM? (then it wouldn't really be IPC and you could use any number of in-memory / in-process mechanisms)
I am not sure. If you start two separate java applications on the same host, will it then be the same JVM?
How could I access shared memory in such cases?
Each Java application you start runs a separate JVM.
I guess at this point, the question is more: what problem are you actually trying to solve here?
(depending on exactly what problem you're trying to solve, maybe you could use a single JVM?)
I am trying to implement a light weight queue handler that other clojure programs can post jobs to
Of course, this can be solved in a number of ways.. ..even just by using existing software.
thanks! π
what is light weight about it? does the queue need to persist to survive restarts? does it have to ensure exact "execute once" semantics? is speed the main concern above the prior bits?
You do IPC same as in any other language, named pipe, socket etc
An interesting case (depending on security concerns) is to use a socket repl (prepl preferred) https://nrepl.org/nrepl/0.8/alternatives.html
Work being planted by sending a form to the worker process
Using a prepl would be a nice Clojure-centric approach -- that thinks outside the box!
Although it is synchronous (unless you send futures).
It just needs to process jobs sequentially as they come in.. no persistence or execute once
I guess it depends on what feedback you want to get from the process, if any.
I'll check prepl
I don't need any feedback from the process either
Not an expert on this topic, but I appreciate the discussion. Lately at work it seems like adding Redis or RabbitMQ seems to be the default overkill solution to any IPC..
I'm curious as to what problem this solves that you couldn't solve with just executing code in a thread pool directly within each program? Using an agent
, for example.
(or a plain old Java executor -- or just using future
directly)
@seancorfield I am trying to learn both Clojure and kind of Java at the same time. π How can I utilize core.async or agent across separate clojure programs?
Because that was the first thing I was thinking about.
e.g. by separating things in libraries etc
core.async
and agent
's are for in-process stuff.
My question was: why write separate programs for this, at all?
If it's just as a learning exercise, fair enough, but you need to figure out what you're trying to learn π Is it about using sockets and reading/writing data on them? Is it about queuing? Or job control in general?
What are the "jobs" that you want to be able to run? Just Clojure code expressions?
How does Java fit into this? (even from a learning p.o.v.) That's a genuine question: I'm not sure what you'd be learning about Java in the scenario above...
It is a command handler for a CQRS system. So it is just Clojure code expressions. I want to put it into a separate program to be able to use it through different interfaces. E.g. via a web server and command line etc. I am not trying to learn Java really, but of course some Java concepts seeps through. :)
@marcus.akre while it's trivial to send clojure code to another process (you can just start up a repl as a socket handler), I don't think it's a very good API for IPC
for the same reason you wouldn't just use SSH and send shell commands
ok thanks