This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-08-21
Channels
- # announcements (15)
- # beginners (82)
- # calva (19)
- # cider (7)
- # clj-kondo (7)
- # clojure (81)
- # clojure-brasil (8)
- # clojure-dev (37)
- # clojure-europe (2)
- # clojure-italy (7)
- # clojure-nl (8)
- # clojure-spec (5)
- # clojure-uk (14)
- # clojurescript (67)
- # cursive (13)
- # datomic (29)
- # defnpodcast (2)
- # figwheel-main (19)
- # fulcro (9)
- # graalvm (5)
- # iot (3)
- # off-topic (16)
- # other-languages (1)
- # overtone (1)
- # pathom (4)
- # protorepl (2)
- # re-frame (25)
- # reagent (1)
- # shadow-cljs (126)
- # spacemacs (9)
- # sql (2)
- # test-check (24)
- # tools-deps (11)
hallo... i'm conj'ing maps into a sequence... sometimes i want to remove a map from the sequence, how can i delete a map from a sequence (in an atom) using swap?
I'm making an online japanese vocabulary quiz for the kanji (imported chinese glyphs) and their compounds.
Someone suggested that it would be cool to select which glyphs you already know so you can be fed only compounds that satisfy from the set of "known glyphs" you indicate
so i'm working on that! i'm stoked, it's pretty cool, but there are some weird things. is it okay to store these individual kanji like so?
(def all-tango (atom [{:tango "日" :kanji "日"}
{:tango "月" :kanji "月"}
{:tango "一月" :kanji ["月" "一"]}
{:tango "十月" :kanji ["月" "十"]}
{:tango "同月" :kanji "月"}
{:tango "会う" :kanji "会"}
{:tango "出る" :kanji "出"}
{:tango "出す" :kanji "出"} {:tango "同じ" :kanji "同"}]))
(def individual-kanji (atom [{:kanji "日"} {:kanji "会"} {:kanji "同"} {:kanji "月"} {:kanji "一"} {:kanji "十"} {:kanji "出"}]))
As you can see, the individual pieces are noted, and you can click on them on the app and add them to an active set, i want to compare the active set with the :kanji list in the all-tango. (Tango means "vocabulary, words") so you can see each word and then what kanji are part of it.
Right now I don't know how to compare a collection of "known kanji" against the constituent parts of each vocab word in the all-tango atom.
@sova sets are perfect for this use case. you may use a set to store the constituent kanji of a tango (e.g., {:tango "一月" :kanji #{"月" "一"}}
). you may use another set to store the "known kanji" (e.g., (def known-kanji #{"日" "同" "一" "出"}
). from there on, you can use clojure.set/subset?
to filter out tango(s) from the tango vector whose constituent kanji set is a subset of the known-kanji
set.
@abdusalam sets rule! thanks ^_^
i’m not in front of a computer right now. but i have a question: why are you keeping all-tango
and individual-kanji
in atom
s?
it seems like these represent a known set of things that you can pick elements from and shouldn’t have a reason to change at runtime.
Great question! I'm making an online quiz. Maybe you can help me figure out what's most natural in Clojure. There's a set of all characters, you can click on them and add them to a known kanji atom (changes at run-time, during runtime) because it'll generate quizzes for you on compound words based on the ones you know.
Tango and All-Kanji never change, like you say, so what's a more relevant data structure? I've ingrained the atom access pattern it's all i use! haha
this is how i would do this:
1) figure out a way to get a list of tango from all-tango
based on known-kanji
for one round of the game (i.e., state for a single round).
2) leveraging what's in 1), use loop
/`recur` to generate state for each round of a continuous game.
that's great. thank you, i agree! i didn't think about loop and recur, i will have to employ them !
I got it working. Set thinking was the way to go. I do a simple check if the intersection of kanji and the compounds is a superset of the compounds that make up a compoundword, and if that's true then i print it out. works very pretty so far ^_^
I need some help writing that filter
I'm using deps.edn in clojure in macOS
but It's not detecting my namespaces
{:paths ["src/main"]
:deps {org.clojure/clojure {:mvn/version "1.10.1"}}
:aliases {:test {:extra-paths ["test/main"]
:extra-deps {lambdaisland/kaocha {:mvn/version "0.0-529"}}
:main-opts ["-m" "kaocha.runner"]}}}
it's like this the deps.edn
the tree of files is:
.
├── README.md
├── bin
│ └── kaocha
├── deps.edn
├── src
│ └── main
│ └── core.clj
└── test
└── main
└── core_test.clj
the namespaces are: and for core.clj =>
(ns main.core)
and for core_test.clj => (ns main.core-test)
is there something wrong?
it worked, why
thanks 😃
np! the namespaces start from the path, so with "src/main" it was expecting to find the files in src/main/main/core.clj
.
yeah, I did
thanks!
I am defining a rather long regex and am trying to split it over multiple lines. Currently I'm using re-pattern
and constructing my string up of multiple fragments split over a few lines, though this means having to double escape. Is there a way to build up a regex over multiple lines without having to perform that double escaping? (e.g., #"\d{2}"
must be written "\\d{2}"
)
user=> (re-pattern (str #"\d" #"\w"))
#"\d\w"
you can use the regex reader by using the #"" notation for each of the substrings
it combines as expected
you can also use format
with %s
instead of str
if that makes things clearer (%s also does the right thing with an re input)
i have a hash map with a key :@timestamp
when i try to get the value it throws a syntax error Invalid token: :
i've tried putting it in double quotes and escaping it with \
i guess i could change it into a string... any other options folks may know of?
thanks!
(and yes)
hello! I had some questions on my solution for the Collatz Conjecture
problem on exercism:
(defn collatz [num]
(if (or (neg? num) (zero? num))
(throw (Exception. "Input must be a positive number"))
(loop [num num
count 0]
(cond
(= 1 num) count
(even? num) (recur (/ num 2) (inc count))
(odd? num) (recur (+ 1 (* 3 num)) (inc count))))))
The tests for (collatz 0)
and (collatz -15)
were checking for thrown? Throwable (collatz 0)
which I've never encountered before so I just hacked together my solution with assumptions of what they were looking for. Any advice or is that ok for simple error checking? Error checking in general is a huge blind spot. Any resources you recommend? I own a few Clojure books but haven't really hit on that subject yet.
I feel my brain is just stuck on loop/recur for solving problems. I resort to it a lot in exercism and 4clojure. Is this ok and you found you moved more towards reduce
and higher order sort of functional solutions as you progress or am I really building bad habits by keep reaching for this current method? At the moment I find it much easier to wrap my head around.
that if / first branch could jjust be {:pre [(pos? num)]}
I don't think reduce
makes any sense here as there's no incoming seq to consume
perhaps (->> (iterate ...) (take-while ...) (last))
?
or drop-while / first
ok, good stuff already! I definitely want to learn about this pos?
check. I was trying to think of a good way to do that.
Yeah, for this particular one I wasn't thinking reduce
would be good. But in general I've been told I should be trying to move away from loop/recur
when possible but my brain keeps taking me there.
pre automatically throws assertion error, which should work in your case
what exactly is frowned upon with loop/recur
? Is it just not a good idiomatic way for functional programming?
it's low level
it does things by hand that can be done in a less error prone way via higher level constructs
consider this version
(->> 12
(vector 0)
(iterate (fn [[c n]]
[(inc c)
(if (even? n)
(/ n 2)
(inc (* 3 n)))]))
(map second)
(take-while (comp not #{1})))
it returns a lazy-seq of values of the function until it hits 1
that''s another advantage to not using loop/recur - you can do lazy processing
oh wait - that's weird, one moment
fixed - returns the thing you want (count) plus the values along the way
(->> 12
(iterate (fn [n]
(if (even? n)
(/ n 2)
(inc (* 3 n)))))
(take-while (complement #{1}))
((juxt count identity)))
you can turn that (juxt ...) into count to just get that
it could be my clojure stockholm syndrome, but to me that's much more direct in describing the algorithm than the loop version
1) iterate this function on N 2) keep getting values until you get the value 1 3) count the results
it's got an off-by-one in there that's easy enough to fix lol
interesting stuff right there. i hope to get to that level some day. at my current ability my solution (I've refactored a little cleaner) is much more understandable but I can just see that yours is super Clojure-y. hahaha. I like it.
note that the name of the clojure function iterate is precisely the term for the mathematical operation your loop is doing
and the iterate function really does do what the core of your loop does (repeatedly call f on its result)
awesome. I've saved this away and will work through it some more. I'm definitely taking away some great ideas here
if I was doing this in a project, I would define and use this function also (based on take-while but it also takes the first item failing the predicate as well)
(ins)user=> (defn take-until [pred coll] (lazy-seq (when-let [[e & es] (seq coll)] (cons e (when (pred e) (take-until pred es))))))
#'user/take-until
(cmd)user=> (take-until (complement #{10}) (range))
(0 1 2 3 4 5 6 7 8 9 10)
hey @U051SS2EU, you might be happy to know I already used that :pre
catch to great effect to solve another problem. And I got rid of a loop to use some sweet threading macros and map functions. Thank you again!
(defn dna->rna [dna]
(case dna
"G" "C"
"C" "G"
"T" "A"
"A" "U"))
(defn to-rna [dna]
{:pre [(every? #{\A \C \G \T} dna)]}
(->> dna
(map str)
(map dna->rna)
(apply str)))
btw you could skip (map str)
by putting a char -> char mapping in dna->rna
and dna->rna could just be a hash-map:
(def dna->rna
{\G \C
\C \G
\T \A
\A \U})
since hash-maps act as lookup functions when called
that was actually really eye opening advice. I've never used a def to a map like that and feeding it values as if it was a function or something. It's just so fun when you starting seeing these patterns in the way clojure is designed.
it comes from the formal definition of a function - mathematically a pure function is equivalent to a map
so why not use a map as a function (with a very specific domain, of course)
I got it working. Set thinking was the way to go. I do a simple check if the intersection of kanji and the compounds is a superset of the compounds that make up a compoundword, and if that's true then i print it out. works very pretty so far ^_^