A question regarding lazy-seq. I'm not sure why I cannot use conj instead of cons here:
(defn simple-range [i limit]
(lazy-seq
;; nil returned by when will terminate the range construction
(when (< i limit)
(print ".")
;; notice you cannot use `conj` because get StackOverflowError in the `take 10` below
(cons i (simple-range (inc i) limit)))))
(take 10 (simple-range 1 1e20))
;; => (1 2 3 4 5 6 7 8 9 10)
;; conj doesn't work
(defn simple-range2 [i limit]
(lazy-seq
;; nil returned by when will terminate the range construction
(when (< i limit)
(print ".")
;; notice you cannot use `conj` because get StackOverflowError in the `take 10` below
(conj (simple-range2 (inc i) limit) i))))
;; StackOverflowError
#_(take 10 (simple-range2 1 1e20))
🤷 works for me
my.ns> (defn simple-range [i limit]
(lazy-seq
;; nil returned by when will terminate the range construction
(when (< i limit)
(print ".")
;; notice you cannot use `conj` because get StackOverflowError in the `take 10` below
(conj (simple-range (inc i) limit) i))))
#'my.ns/simple-range
my.ns> (take 10 (simple-range 0 10))
..........(0 1 2 3 4 5 6 7 8 9)
oops, nvmd. it overflows if the limit is really high
conj
is implemented as coll.cons(x)
so it's going to require that collection to be unwound far enough to cons that last element on.
conj
is a collection function, rather than a sequence function -- and it's easier to think of those as eager whereas sequence functions are usually lazy (not accurate, but a reasonable heuristic)
Hello 🙂 i have a dependency from github, i used https://github.com/reifyhealth/lein-git-down ,using the code from the Example of the project readme
classes are found,but it isnt working normally,i think exceptions happen,any help? or alternative way to do it ?
i am using leiningen
What exception? What dependency?
i don't know it is handled from inside the code,the way i did it using that plugin , is the common way to do it using leiningen ?
i try to use this
but from github not from maven
But you say that it isn't working normally - how do you know that it isn't? What are the symptoms?
its a music player,gets audio from youtube,but produces TrackExceptionEvent , when the maven same version doesnt
but its working in general,other things from that code works,its the first time i used github dependency,and i dont know if lein-git-down is the right way to do it
if the plugin is working ok,i guess its my fault somewhere
Moving to a thread to avoid spamming the main channel.
By "same version" you mean 1.3.50
and 60441fc5
?
And does the TrackExceptionEvent
have any stack trace that you could share?
On maven i use this
https://mvnrepository.com/artifact/com.sedmelluq/lavaplayer/1.3.50
on github the same is this i think
https://github.com/sedmelluq/lavaplayer/commit/60441fc5a4f58e80a5466fa36b9366fb8501a8f5
my project.clj looks like
(defproject test-project "0.1.0"
:description "A test project"
:plugins [[reifyhealth/lein-git-down "0.3.7"]]
:middleware [lein-git-down.plugin/inject-properties]
:dependencies [[lavaplayer "60441fc5a4f58e80a5466fa36b9366fb8501a8f5"]]
:repositories [["jcenter-bintray" "<https://jcenter.bintray.com/>"]
["bintray-rotate" "<https://dl.bintray.com/sedmelluq/com.sedmelluq>"]
["public-github" {:url "<git://github.com>"}]
["private-github" {:url "<git://github.com>" :protocol :ssh}]]
:git-down {lavaplayer {:coordinates sedmelluq/lavaplayer}})
i dont have the stack trace,i dont know how to get it, i get an Event object,that is made from that Exception handler i guess
When you see that TrackExceptionEvent
string somewhere - can you share a screenshot?
The probability of it being an issue with lein-git-down
is quite high IMO because lavaplayer
has not only Java code that can already be tricky with Git dependencies, but also native C code that's much more trickier.
still i didnt found the stacktrace,but i found the Exception
com.sedmelluq.discord.lavaplayer.player.event.TrackExceptionEvent "com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Something broke when playing the track."
its the first time i used github dependency,how people do it?
i saw the deps.edn new cli , i dont know , but never used it,only leiningen i used
"FriendlyException", ha! - with a completely unfriendly message. Says absolutely nothing.
thank you for helping me,its not so important thing, but its usefull to know how to use github dependencies in general
Git dependencies are hard. Deps CLI will not help you here as it's designed to work with the dependencies that don't need any compilation - you can't even have Java files if you don't have precompiled class files for them.
how to use a java project from github? even in local way
I couldn't find any build instructions for lavaplayer
. Potentially, the maintainers can do anything before they publish the jar to the Maven repository.
But even if there were some build instructions, there's no tool out there that would be able to follow them automatically.
anyway its ok , i will leave it for now , thank you for helping me
i will check it again sometime 🙂
With regular Java and regular build steps, such tools like lein-git-down
should indeed help.
You can also have such a dependency not as a regular jar dependency but as vendored sources in your project - just as if it was part of your project. But don't do that unless you need to modify the sources of the dependency.
No problem, HPH.
yeah lein-git-down seems to work,maybe that lavaplayer is exception , thank you 🙂
anyone got any dns libraries laying around/to recommend? Been using https://github.com/brweber2/clj-dns but recently started using java 11 and seems *sun*.*net*.*spi*.*nameservice*.*NameServiceDescriptor*
doesn't exist since Java 9, so no longer works. Interested in doing lookups of TXT records only
Something like https://docs.oracle.com/javase/7/docs/technotes/guides/jndi/jndi-dns.html via java interop, perhaps?
Thanks @jason358, yeah, by the description it seems like it'll do the trick, trying to figure out how to actually use it (never done any serious Java programming)
seems to have the most cumbersome API I've seen in the Java world, but I haven't seen too much of it so.
(-> (javax.naming.directory.InitialDirContext.) (.getAttributes "<dns://ns-246-b.gandi.net/ice-9.eu>") (.get "TXT"))
seems to work for me
or even (-> (javax.naming.directory.InitialDirContext.) (.getAttributes "dns:///ice-9.eu") (.get "TXT"))
, actually
It does indeed. I had just got half-way through the docs and even further from understanding. Still not sure how naming.directory comes to do DNS resolution, would expect that to be in some of the networking parts of Java
anyways, you're a hero @jason358, thanks a lot for helping out
for future reference, lazy wrapper to collect the record values as strings:
(defn txt-records [domain]
(let [results (atom [])
query-res
(-> (javax.naming.directory.InitialDirContext.)
(.getAttributes (str "<dns://9.9.9.9/>" domain))
(.get "TXT"))
enum (.getAll query-res)]
(while (.hasMore enum)
(swap! results conj (.next enum)))
@results))
(-> (javax.naming.directory.InitialDirContext.) (.getAttributes "<dns://9.9.9.9/ice-9.eu>") (.get "txt") .getAll enumeration-seq)
?
hmm, ho do I do map
if every item in a result coll depends on a previous one?
aha, very cool. thanks!
e.g. there is a "state" that is accumulated while mapping
you use reduce
but the result is always the same length as initial coll
So?
I was thinking there could be a lazy way to do that
iterate
but iterate is on a single value, and it's infinite
while my result is finite
I'll just use reduce I guess
@vlaaad see the function on https://clojure.atlassian.net/browse/CLJ-2555
iteration
but there is no side effects in my case
then iterate will work fine
it's a map
with some intermediate state calculated from inputs that has to be updated and read on each step
I just find it a bit strange that the thing I want to think of as a "map with accumulated state" turns into this big chunk of code:
(:acc
(reduce
(fn [{:keys [state acc]} [dt [event n]]]
(let [state (case event
:price (assoc state :last-price n)
:div (update state :stock + (* (:stock state) (/ n (:last-price state)))))]
{:state state
:acc (conj acc [dt state])}))
{:state {:stock 1 :last-price 0}
:acc []}
(sorted-map ;; example input
0 [:price 10]
1 [:div 1]
2 [:price 20]
3 [:div 2])))
be careful with anything under the javax package
I think there is actually a licensing violation if you ship software using that package name with classes not provided by oracle (or something like that)
(defn running-total-of-price [price-points]
(loop [price-points (seq price-points)
state {:stock 1 :last-price 0}
price-history []]
(if (empty? price-points)
{:state state :acc price-history}
(let [[dt [event n]] (first price-points)
new-state (case event
:price (assoc state :last-price n)
:div (update state
:stock
+
(* (:stock state)
(/ n (:last-price state)))))]
(recur (rest price-points)
new-state
(conj price-history [dt state]))))))
the way we learned map in school was just "recursion with linked lists"
so writing if empty? ... else (recur ... )
stuff is maybe more readable to me than it should be
but at least I can parse it better than the equivalent reduce
I don't know if thats helpful or not
eh, interesting and very annoying. Thanks for the headsup @emccue
Why is that annoying, why would you want to ship any class names under javax.
not provided by Oracle (and how does that relate to the dns lookup code above, exactly)?
@victorbjelkholm429 did you see that you don't need atom
and the imperative stuff?
reductions
?
@vlaaad I've been messing with this for that type of thing: https://gist.github.com/jjttjj/c0acfb066c4d58bbb823501a9ffc0687
If you're just interested in the previous item you could do
(defn map-prev
([f]
(fn [rf]
(let [vold (volatile! nil)]
(fn
([] (rf))
([result] (rf result))
([result x]
(let [old @vold
new
(if (some? old)
(vswap! vold f x)
(vreset! vold x))]
(rf result new)))))))
([f xs]
(map f xs (rest xs))))
(I've been focusing more on the transducer versions)
thanks @jjttjj
Yeah, using mutable volatile is a fine option for single-threaded processing!
note with that map-prev nil is not a valid value, and it just sets the previous state the first time it sees a value.
but otherwise it's like map but the function you pass it just takes [old new]
agree on readability @emccue
hmm, looks like what I need
thank you!
Is there any recommended way to get jsonista to losslessly encode keyword values so this returns equivalent data?
user=> (-> (j/write-value-as-string {:system/status :status/good} json-mapper) (j/read-value json-mapper))
#:system{:status "status/good"}
Transit+json does the job fine, but it's much slower.@jeaye conceptually, for it to work regardless of your data format you need to "tag" keywords where-ever they appear
(separate from the library)
but also because keywords can appear as keys in maps, you need to manipulate the json structure quite a bit to losslessly encode and decode
What you could do though, if you are feeling kinda lazy, is just put a prefix
so make a custom object mapper to give to the library
that when it encounters a keyword
instead of mapping it to
:some-keyword
=> "some-keyword"
do
:some-keyword
=> "💩some-keyword"
and just look for the prefix when round tripping
as a consequence you might need to filter the poop emoji out from user input
(transit gives the "right" answer, but there are tons of hacky ones like this)
Yeah, I've considered that approach. I was hoping for something less clunky, but it may not exist.
yeah if you want this
{"a" :abc :def "hijklmnop"}
to round trip correctly, you would have better luck just figuring out how to speed up the transit library to match your needs
well, the issue with maps is just that they always require string keys in the json repr
so in your own does-kinda-the-same-as-transit-but-not you can
:a => ["k", "a"]
"a" => ["s", "a"]
{:a 2} => ["m", ["k", "a"], 2]
{:a 2} => ["m", ["s", "a"], 2]
[:a 2] => ["v", ["k", "a"], 2]
#{:a} => ["@", ["k", "a"]]
always box everything
or you can just use xml
<map>
<entry>
<key> <keyword value="a"></string> </key>
<value> <number value=3></number> </value>
</entry>
</map>
or just use edn and give up
{:a 3}
This is driving me nuts - either I’m doing something very stupid and I’m too tired to see it, or I’m misunderstanding something subtle:
(def common-errors #{{:unexpected :except, :expected #{":only" ":rename" ":exclude" :eof}}
{:unexpected :include-macros, :expected #{":as" ":only" ":refer" ":rename" ":exclude" :eof}}})
=> #'user/common-errors
(->> (take 5 errors)
(remove (fn [error]
(every? #(do (prn %)
(println (contains? common-errors %))
(contains? common-errors %))
(errors-from (:new error)))))
(count))
{:unexpected :default, :expected #{":as" "sequential" ":only" ":refer" "symbol" ":rename" ":exclude" :eof}}
false
{:unexpected :except, :expected #{":only" ":rename" ":exclude" :eof}}
false
{:unexpected duration-inst, :expected #{"sequential"}}
false
{:unexpected :except, :expected #{":as" "sequential" ":only" ":refer" "symbol" ":rename" ":exclude" :eof}}
false
{:unexpected :include-macros, :expected #{":as" ":only" ":refer" ":rename" ":exclude" :eof}}
false
=> 5
(contains? common-errors {:unexpected :except, :expected #{":only" ":rename" ":exclude" :eof}})
=> true
I have a common-errors
set of error forms. I’m trying to filter those out of my list of errors. When I test a form manually against the set contains?
returns true, but inside the remove
it doesn’t.
I’ve copy-pasted the manual test from the prn
ed version, so it should be the same structure. There’s no metadata involved either.
when all else fails I like to capture the actual data, so I can check the types (eg. a symbol with a colon that prints like a keyword) - though it looks like you have that data and could just jump into checking that the printed values and assumed types match up
the second one in this list should have matched true? maybe chop down the the common-errors to just the first one and change it to equality rather than contains? and perhaps run it through data/diff. Is there any chance there's some shadowing going on here so common-errors isn't what you think it is?