This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-10-06
Channels
- # babashka (19)
- # beginners (68)
- # calva (9)
- # cider (27)
- # clj-kondo (64)
- # clj-on-windows (2)
- # cljdoc (8)
- # clojure (11)
- # clojure-europe (58)
- # clojure-italy (1)
- # clojure-nl (23)
- # clojure-uk (5)
- # clojurescript (9)
- # cryogen (18)
- # cursive (14)
- # data-science (17)
- # emacs (6)
- # gorilla (6)
- # graphql (1)
- # gratitude (2)
- # holy-lambda (10)
- # introduce-yourself (1)
- # jackdaw (3)
- # jobs (1)
- # leiningen (2)
- # malli (3)
- # missionary (33)
- # off-topic (21)
- # pedestal (7)
- # polylith (8)
- # quil (3)
- # random (1)
- # releases (1)
- # remote-jobs (7)
- # shadow-cljs (18)
- # specter (1)
- # sql (8)
So I started my REPL executed this line of code:
(slurp (io/resource file))
Then changed that file to have different contents, executed the same function, but the result from slurp
hasn’t changed. Just wondering why or if I’m doing something wrongresources are read from the classpath. it seems likely that you're reading that file out of a jar or something, not off the file system
like, don't slurp it - you should get a url to the location
(io/resource file)
slurp works
there are other ways (basically what slurp is doing under the hood - getting a URL connection, reading the stream, etc)
Sorry, figured out what I did wrong. I modified the file at the root of the project but I had my resources points at /resources
keep in mind that resources are loaded by the classloader and I think cached in the loader so you still may not see updates
it will, it just may not see updates after you load the resource
or maybe that's what you were asking
gotcha, I understand, if I modify the file I would have to call (io/resource …)
again
well yes, I was suggesting that might not be enough, but I was wrong - it looks like it will see updates in file system files
and actually, no you don't have to call resource
again, just re-`slurp`
let's say I want to share config / resoiurces between 2 projects, how would you do it? Is there a simpler way than just having the same file in 2 places?
it depends on how those two projects works together. Are they completely independent running projects or one uses another as a dependency?
they dont' depend on each other. It's like a serive and aws lambda that share credentials etc
I'm not too sure what you're trying to achieve, but you can have two programs use the same file that is either on the file system or some remote store. For example, just have them slurp
the same file
I've been deliberating this issue for a while. The library is deprecated, but it's the only one available for clojure and only seems to need a few little patches to work with the current state of the API. My question is if there may be an approach to resolve the issue with a non-breaking change, or if a breaking change would just be the more appropriate thing to do instead. https://github.com/cjsauer/pubg-clj/issues/2
I create a demo use hugsql with vscode. when I run calva and press key Ctrl+Enter and show error. but this demo in clj is ok
You may not have evaluated the namespace form after adding new requires. With Ctrl-Alt-C Enter you can evaluate the whole file again after which the namespace should required.
I press the Ctrl-Alt-C Enter and Ctrl+Enter eval form but it's show error yet.
; Evaluating file: core.clj
; Syntax error (FileNotFoundException) compiling at (d:\E\clojure\hugsql\ted\src\ted\core.clj:1:1).
; Could not locate ted/db__init.class, ted/db.clj or ted/db.cljc on classpath.
; Evaluation of file core.clj failed: class clojure.lang.Compiler$CompilerException
every .clj file with press Ctrl-Alt-C Enter ?I’m trying to write a macro which accepts a sequence of expressions and ultimately yields a map. Right now I’m accomplishing this with (into {} …)
. One way I’d like to improve it is to get the same validations as when using a map literal, e.g.,
user=> {:foo :bar :foo :baz}
Syntax error reading source at (REPL:8:22).
Duplicate key: :foo
Is there any way to accomplish this without re-implementing that check by hand?note that this error is thrown when the map literal is read. https://clojure.org/reference/reader
Yes, as in throw an error
The full details are app-specific. The relevant bit is that I wind up with a sequence of pairs (e.g., ([:foo :bar] [:baz :bork])
) and need to turn this into a map. Currently doing that by handing it to into
, but this means just overwriting duplicate keys instead of erroring on them.
Hello friends. I have a puzzling situation here I haven't been able to figure it out. I have the following piece of code:
(defn haversine
"Distance in km between two points of lat/long. Supply two maps of latitutde and longitude."
[{lat1 :lat long1 :lng}
{lat2 :lat long2 :lng}]
(if (every? float? '(lat1 lat2 long1 long2))
(let [delta-lat (Math/toRadians (- lat2 lat1))
delta-long (Math/toRadians (- long2 long1))
lat1 (Math/toRadians lat1)
lat2 (Math/toRadians lat2)]
(* earth-radius 2
(Math/asin (Math/sqrt (alpha lat1 lat2 delta-lat delta-long)))))
0))
Basically it uses destructuring to fetch out lat and lng from maps and proceeds to calculate the distance between two points.
I've added the (if (every? float?
check, because my maps sometimes, can be nil
. Instead of evaluating to zero, I'm getting the following error:
Execution error (NullPointerException) at clrips.haversine/eval9073 (form-init7532735855317168820.clj:2126).
Is there any catch I'm not aware of? Or is the code just wrong?what's (pst *e)
show? What's alpha
?
it's almost certainly (every? float? '(lat1 lat2 long1 long2))
.
should be (every? float? [lat1 lat2 long1 long2])
I've tried both ways 🙂 both with the same result
float?
will return false for integers, so if you pass 42 rather than 42.0, float?
will be false. You can also try using number?
rather than float?
. It depends on the types of calculations if you want to coerce yourself or force the caller to coerce.
right, but the first is a sequence of symbols and the second is a sequence of the values bound to lat1
, lat2
, etc
> (let [[lat1 lat2 long1 long2] [1 2 3 4]]
(prn ''(lat1 lat2 long1 long2) '(lat1 lat2 long1 long2))
(prn '[lat1 lat2 long1 long2] [lat1 lat2 long1 long2]))
;; (quote (lat1 lat2 long1 long2)) (lat1 lat2 long1 long2)
;; [lat1 lat2 long1 long2] [1 2 3 4]
not sure that helps, but there's a difference between '(a b c)
and (list a b c)
> I've added the `(if (every? float?` check, because my maps sometimes, can be `nil`.
I would also caution against combining error recovery and calculation into this one function.
It might be convenient in this specific use case, but if haversine
is ever used in another context, it's likely that passing nil will be an error and returning 0 will only cover up the error and produce incorrect results that are hard to debug.
maybe dispatching “outside” with a multimethod, protocol/record or something like that seems sensible too.
If it happens to be a very common idiom, it might also be acceptable to combine the two in an appropriately named function like some-haversine
. Seems unlikely in this case, but generally speaking, it might be ok. I might still prefer to keep them separate and have some sort of threading macro.
The mixing between the functionality / error identification / throwing all make sense, thanks for the tips. Let me try a different approach 🙂
I got to this:
(defn haversine
"Distance in km between two points of lat/long. Supply two maps of latitutde and longitude."
[{lat1 :lat long1 :lng}
{lat2 :lat long2 :lng}]
{:pre [(every? float? [lat1 long1 lat2 long2])]}
(let [delta-lat (Math/toRadians (- lat2 lat1))
delta-long (Math/toRadians (- long2 long1))
lat1 (Math/toRadians lat1)
lat2 (Math/toRadians lat2)]
(* earth-radius 2
(Math/asin (Math/sqrt (alpha lat1 lat2 delta-lat delta-long))))))
(defn safe-haversine [a b]
(try
(haversine a b)
(catch AssertionError ex 0)))
This is much cleaner to read actually. looks to be working.
(safe-haversine {:lat 1.0 :lng 0.0} {:lat 0.1 :lng nil})
0
clj꞉clrips.haversine꞉>
(safe-haversine {:lat 1.0 :lng 0.0} nil)
0
clj꞉clrips.haversine꞉>
Thanks!So - do you want to feel stupid, like I did? So I'm testing it out here and created the above code using symbols. you know :lat
:lng
. But nothing was working. My manual tests in calva were working!
Distance was returning, when being called manually. But when I tried to run by reading data from JSON using cheshire, nothing. always zero.
So, here is an example on how things are coming from JSON. :face_palm:
{"lat" 51.54987, "timestamp" "2018-08-10T20:04:22Z", "lng" 12.41039}
BTW - Calva breakpoints are great. Just learned how to use them. Again, thanks for all the help!
BTW, how can I make cheshire to decode the json with symbols instead of strings?
keywordize-keys
will do the trick
Directly from cheshire passing a second argument true
like:
(cheshire/parse-string "..." true)
@U7S5E44DB cool, but the docs are very lean. I'm using parse-stream
. I could not find how to pass options...
Are they the same options for parse-string
?
The second argument can be true
, in which case it defaults to keywordizing the keys, or any function
I think I was looking at a different version of the docs :face_palm:
Thanks!
Hey guys, is there a way to implement how a type should be represented in the repl? I have this cons-cells
(defprotocol cons-cell
(car [this])
(cdr [this]))
(deftype Cons [l r]
cons-cell
(car [this] (.l this))
(cdr [this] (.r this)))
and I would like them to look like an ordinary clojure list, when evaluating them. Is this possible?Printing is controlled by print-method and print-dep multimethods (the caveat being that they will be read back as lists, not your type)
You can implement those methods to get this