This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-19
Channels
- # 100-days-of-code (12)
- # beginners (116)
- # calva (2)
- # cider (16)
- # cljdoc (5)
- # cljs-dev (26)
- # clojure (161)
- # clojure-italy (7)
- # clojure-nl (9)
- # clojure-spec (49)
- # clojure-uk (112)
- # clojurescript (50)
- # clojutre (4)
- # core-async (2)
- # cursive (4)
- # datomic (192)
- # emacs (10)
- # events (4)
- # figwheel-main (147)
- # fulcro (94)
- # graphql (5)
- # instaparse (1)
- # jobs-rus (1)
- # keechma (10)
- # leiningen (223)
- # luminus (3)
- # mount (23)
- # nrepl (8)
- # off-topic (44)
- # onyx (10)
- # pedestal (5)
- # re-frame (19)
- # reitit (8)
- # shadow-cljs (62)
- # uncomplicate (3)
About uberjar/running from git… I tried a lumo project recently with npm dependencies. It was a extra effort to turn this into a single deployment artifact (I did manage to) and I learned that many people just run npm/yarn install and then start their project from that directory, so I just did that instead.
Hi! I have an extremely basic question. Do I need any HTML, CSS, or JavaScript knowledge if I want to get into ClojureScript? and if so are there any resources to recommend? Thanks! 🙂
@juanmp If you want to learn the ClojureScript language, no. (ClojureScript isn’t tied to web tech.)
You can largely ignore the JavaScript aspect for quite a while if you aren’t interoperating with any JavaScript libs or doing other platform-specific interop.
I have a similar question: are there any really minimal clojurescript example web apps. I’m thinking something analagous to https://github.com/abishekaditya/elm-counter
@torvaney https://github.com/Day8/re-frame/blob/master/examples/simple/src/simple/core.cljs
I recommend reading the re-frame documentation it's very good. https://github.com/Day8/re-frame/blob/master/README.md
I found this (https://gist.github.com/daGrevis/c55395a3e85a07ea6973) but I was wondering if there was anything simpler, or potentially react-less
You can choose https://github.com/tonsky/rum .
I’ve also been recommended re-frame as something to check out to get started with it, what’s your thoughts on it?
If you are interested in building UIs (web or React Native), IMHO, re-frame
is the simplest and most popular way to go.
(relatedly, ##-Inf
, ##NaN
)
Starting with Clojure 1.9, I think.
Possible run parallel in emacs/cider clj and cljs repl? Because when I start clj after this a send command cljs-start and i see just the cljs repl. If i start a new clj session, that isnt a same session data. Now i jump everytime from cljs to clj and ... is there something easier with emacs?
How do your backend server and frontend page share the same state? If you can solve that you can connect to both as separate repls, if you can't that's an application architecture problem not a tooling problem.
I have frontend cljs and clj backend. I send data to clj part and work with that. I just want to work more dinamically.
Hi ! I need help with a little thing. So what I'm trying to do is to parse logical expressions like A + (B | D) etc.. I'm using regex, but I'm getting some weird error. I'm probably missing something any help would be much appreciated (snippet incoming)
(translate-expr "C | (C ^ E)") works as I would expect it
but (translate-expr "(C + D) | (C ^ E)") fails
returns null (not nil) java nul pointer exeption in Matcher on getlenght, but I don't see where null might get passed to the matcher
I would put a println right after the let binding printing out the value of right operator and left
but, assuming your logical expression grammar is recursive, regexs aren't going to work great for parsing it
(it’s possible to make recursive regexes etc, but my recent experiences show that 1) the more advanced options don’t necessarily work in all languages, and 2) the more complicated options are painfully slow)
thanks for the tips ! I'm refraining from using any libraries that might make life easier for me (it 's for a school project and I want to maximize my learning)
any tips for how to implement a proper parser ? ( maybe I'll just try to reimplement instaparse 😛 )
A homework assignment probably had a simple enough grammar that this classic approach will work https://en.m.wikipedia.org/wiki/Recursive_descent_parser
Do you know when his could happen:
CompilerException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentStack,
@fahd.elmazouni jar of salt needed because I haven’t read through this yet myself, but you might find this of interest: http://craftinginterpreters.com/contents.html
thanks a lot !
@denisgrebennicov using peek or pop on a lazy seq
I thought of using stacks might end up just doing that 😛
I'm building an inference engine with logical expressions as rules
how to compare two Double/POSITIVE_INFINITY
?
Can not use ##Inf
because of clojure version being not 1.9
Example:
(def l ['(Double/POSITIVE_INFINITY 4 3) '(5 4 2)])
(->> l
(map (fn [stack] (if (= (peek stack) Double/POSITIVE_INFINITY) stack (rest stack)))))
using ' to make lists is weird
(= [Double/POSITIVE_INFINITY 2 3] [Double/POSITIVE_INFINITY 2 3])
evaluates to true
. Is that not working?
Double/POSITIVE_INFINITY is a symbol, that when evaluated is the positive infinity value for doubles, but quotation means it isn't evaluated, so it is the symbol
ah, missed that part of Denis G's question.
Are you asking whether it would be better to use a keyword like :my-custom-infinity-keyword
instead of Double/POSITIVE_INFINITY
?
It depends on your use case, but note that (unquoted) Double/POSITIVE_INFINITY
has type Double
. You can do at least limited kinds of arithmetic with it and get back Double results.
You can't do arithmetic on keywords
If you don't need to do arithmetic on this part of your data, then that distinction isn't important.
in this case +infinity is just a flag on the top of the list, so that I don't pop elements from there, in theory it could be anything, I just put +infinity, because it was the first thing I have though (and would do it in Python, Java, C++) The question is, if it is more a Clojury way to use a keyword instead
If the reason for having that marker there has nothing to do with the Double value +infinity, then yeah, a keyword that you choose for this purpose sounds reasonable.
There are a few libraries that wish to allow all kinds of values through a 'channel' or 'queue' of some kind, and they sometimes go to the trouble of creating a brand new Java Object that no other part of the program has access to, and compare against that value. A value used for that purpose is often called a sentinel. Not sure if that is your use case here, just wanted to mention it in case you were ever worried that your new keyword might be part of the data you want to process sometimes.
Even if so, you can create a keyword with a namespace that is part of your application's namespaces, and it maybe becomes unlikely enough to worry about that any data you were processing used that same keyword.
Dunno whether this is beginner or puzzles question, gonna ask anyway. Solving the hackerrank problem using clojure. Finally all good and ... Timeout Problem: https://www.hackerrank.com/challenges/poisonous-plants/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=stacks-queues PS. idea is correct 😉 Question is, how can I speed up this code:
(defn build-stacks [coll]
(reduce (fn [stacks val]
(let [top-stack (peek stacks)
top-elem (peek top-stack)]
(if (> val top-elem)
(conj (rest stacks) (conj top-stack val))
(conj stacks (list val)))))
(list (list (first coll)))
(rest coll)))
(defn merge-stacks [coll]
(reduce
(fn [stacks other-stack]
(let [top-stack (peek stacks)
last-stack-val (last top-stack)
top-other-stack-val (first other-stack)]
(if (>= last-stack-val top-other-stack-val)
(conj (vec (drop-last stacks)) (concat top-stack other-stack))
(conj stacks other-stack))))
[(first coll)]
(rest coll)))
(defn poisonous-plants [coll]
(loop [days 0 stacks (merge-stacks (build-stacks (reverse (concat [Double/POSITIVE_INFINITY] coll))))]
(if (= 1 (count stacks))
days
(recur (inc days) (->> stacks
(mapv (fn [stack] (if (= (first stack) Double/POSITIVE_INFINITY) stack (rest stack))))
(filterv (comp not empty?))
(merge-stacks))))))
The problem was/using concat and last in merge-stacks function. Now all I do is with vecs. Only one test-case timeouts...
(defn peekv [coll]
(nth coll (dec (count coll))))
(defn restv [coll]
(subvec coll 0 (dec (count coll))))
(defn build-stacks [coll]
(reduce (fn [stacks val]
(let [top-stack (peekv stacks)
top-elem (peekv top-stack)]
(if (> val top-elem)
(conj (restv stacks) (conj top-stack val))
(conj stacks [val]))))
[[(first coll)]]
(rest coll)))
(defn merge-stacks [coll]
(reduce
(fn [stacks other-stack]
(let [top-stack (peekv stacks)
last-stack-val (first top-stack)
top-other-stack-val (peekv other-stack)]
(if (>= last-stack-val top-other-stack-val)
(conj (restv stacks) (apply conj other-stack top-stack))
(conj stacks other-stack))))
[(first coll)]
(rest coll)))
(defn poisonous-plants [coll]
(loop [days 0 stacks (merge-stacks (reverse (build-stacks (conj ((comp vec reverse) coll) Double/POSITIVE_INFINITY))))]
(if (= 1 (count stacks))
days
(recur (inc days) (->> stacks
(mapv (fn [stack] (if (= (peekv stack) Double/POSITIVE_INFINITY) stack (restv stack))))
(filterv (comp not empty?))
(merge-stacks))))))
@denisgrebennicov I took a shot at solving this, wondering how it might compare in time
(defn- elim-plants
"Eliminates the plants for one day - returns list
of remaining plants."
[plants]
(let [plants (concat [(first plants)] plants)
tuples (partition 2 1 plants)]
(keep (fn [[left right]]
(when (>= left right)
right))
tuples)))
(defn poisonous-plants
"Removes plants for each day - stopping when the number of plants
is the same as the previous day, because that indicates no more will
die. Returns number of days (iterations) until stopping point."
[plants]
(loop [prev-count -1
plants plants
days 0]
(if (= (count plants) prev-count)
(dec days)
(recur (count plants) (elim-plants plants) (inc days)))))
(deftest plant-test
(is (= 0 (poisonous-plants [])))
(is (= 0 (poisonous-plants [1 1])))
(is (= 0 (poisonous-plants (take 1000 (repeat 1)))))
(is (= 1 (poisonous-plants [1 2])))
(is (= 1 (poisonous-plants (take 1000 (iterate inc 1)))))
(is (= 2 (poisonous-plants [1 3 2]))))
I timed our solutions with my unit tests, and mine takes about 2-3ms to run, while yours takes 80ms 😮
i mean it's clear. But "naïve" O(n^2) solution. I tried to do as less iters as possible
this is why I have this build-stacks function The idea is build-stacks while count of stack is > 1 pop from every stack other than first remove empty stacks merge mergable stacks repeat
Hi. I'm new to namespaces. How do I load thrown?
macro, please? In clj 1.9.0 REPL: (use '[clojure.test]) assert-expr
evaluates, but then thrown?
fails as an unknown symbol.
Not sure off top of my head, but thrown? might not be an independent macro, but a special symbol recognized within the context of a clojure.test (is ...)
expression. Are you trying to use thrown? inside such an expression, or independent of such?
Yeah, so after use'ing clojure.test, you can write expression like (is (thrown? ...))
, but (thrown? ...)
by itself not inside of is
isn't defined
Hi! After executing lein test
I got this stack trace. But I can’t understand where to find string number in which this exception throwed.
I’m trying to find the most concise way of writing the following function:
(defn format-duration [duration]
(if (< duration 1)
"now"
(let [f #(str %1 " " %2 (if (< 1 %1) "s" ""))
[_ xs] (reduce
(fn [[d r] [k v]]
(if (= 0 (quot d v))
[d r]
[(mod d v) (conj r (f (quot d v) k))]))
[duration []]
{"year" 31536000 "day" 86400 "hour" 3600 "minute" 60 "second" 1})]
(condp = (count xs)
1 (first xs)
2 (str (first xs) " and " (last xs))
(let [ys (interpose ", " xs)]
(apply str (concat (butlast ys) ["and " (last ys)])))))))
which prints a number or seconds as “human readable”, example:
(format-duration 35125)
=> "9 hours, 45 minutes, and 25 seconds"
where the human readable format follows english language list rules (including the oxford comma). Any suggestions for improvement much appreciated (where improvement in this case is defined closer to code golfing than readability)@xenmayer When you see a stack trace like that, often you want to skip over any lines mentioning clojure.core, and look for namespaces or function names that are yours, e.g. is csvdb.core
a namespace of yours that contains a function order-by*
? If so, look at line 10 of that output.
Thanks!
Also, avoiding the file name core.clj for your own code can help your file names "stick out" more easily from clojure.core's file with the same name.
I know that Leiningen templates often create such a file for you, but you can delete it.
Unfortunately the stack traces only give the base file name, not a path.
Ok, understood)
@mario.cordova.862 as-> expands to a let block, I wouldn't expect it to break any more than nested lets would (and those work fine)
Thanks @andy.fingerhut and @dpsutton. Confirming:`thrown?` is recognised within is
. However, it doesn't seem to "work." For example, [(assert true) 1]
returns [nil 1]
. [(is true) 1]
returns [true 1]
. Then wouldn't you expect [(is (thrown? ArithmeticException (/ 1 0))) true]
also to return a 2-item vector? But it lists the exception and it doesn't return anything - so it seems not to handle the exception. (https://clojuredocs.org/clojure.test/is#example-542692d7c026201cdc327116)
using is for return value seems weird to me and likely to hit corner cases
it alters a dynamically bound value, and is meant to interact with other code that uses that value
Agreed. I haven't seen any project that uses the return value of (is ...)
forms before.
That isn't to say there is no valid way to do that, but you are in far-less-charted waters there, and you can very likely find a way back to the safer parts of the map that doesn't need to do that.
Thanks. Yes, it was for theoretical purpose (http://www.4clojure.com/problem/65). I worked around.
Be sure to look at adereth's solution to that one. Short and sweet