Fork me on GitHub
Adam Kalisz00:06:58

Trying to use on "#uuid \"a8367bc1-690e-4a73-aecf-f2b9b3ff586e\"" but it fails with "No reader function for tag uuid." what am I doing wrong?

Adam Kalisz00:06:48

ExceptionInfo repl-input.cljs [line 1, col 25] No reader function for tag reader/read-string. {:type :reader-exception, :ex-kind :reader-error, :file "repl-input.cljs", :line 1, :col 25} (errors.clj:34) (errors.clj:24) (errors.clj:40) (errors.clj:36) (errors.clj:206) (errors.clj:205) (reader.clj:861) (reader.clj:848) (reader.clj:73) (reader.clj:68)*/fn--1314 (reader.clj:925)*/fn--962 (reader_types.clj:322)

Adam Kalisz00:06:05

Oh, ok, it seems tagged literals are Clojure only...


@adam.kalisz tagged literals work find in CLJS too. but the stacktrace shows that you are using not how are you using it?


No reader function for tag reader/read-string looks like you are using #reader/read-string?


Can this ClojureScript snippet become more Idiomatic? I converted this JS snippet (

const R = 6371e3; // metres
const φ1 = lat1 * Math.PI/180; // φ, λ in radians
const φ2 = lat2 * Math.PI/180;
const Δφ = (lat2-lat1) * Math.PI/180;
const Δλ = (lon2-lon1) * Math.PI/180;

const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
          Math.cos(φ1) * Math.cos(φ2) *
          Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

const d = R * c; // in metres
to this CLJS
(defn gps-distance
  "calculates distance between gps coordinates in km
   from: {:lat :lon}
   to: {:lat :lon}
  [from to]
  (let [R 6371 ;;km
        pi (.-PI js/Math)
        phi-1 (* (:lat from) (/ pi 180))
        phi-2 (* (:lat to) (/ pi 180))
        delta-phi (* (- (:lat to) (:lat from)) (/ pi 180))
        delta-lambda (* (- (:lon to) (:lon from)) (/ pi 180))
        a (+ (* (.sin js/Math (/ delta-phi 2))
                (.sin js/Math (/ delta-phi 2)))
             (* (* (.cos js/Math phi-1) (.cos js/Math phi-2))
                (* (.sin js/Math (/ delta-lambda 2)) (.sin js/Math (/ delta-lambda 2)))))
        c (* 2 (.atan2 js/Math (.sqrt js/Math a) (.sqrt js/Math (- 1 a))))
        d (* R c)]


You can use map destructuring to turn (:lat from) into from-lat. You can extract (/ pi 180) because you use it four times. You can extract (* x x) into a separate square function or use js/Math.pow to avoid having to compute the same thing twice. You could extract common math functions into extra defs to make gps-distance more readable.

🙌 4

And I think you should be able to use Greek characters in CLJS sources with no problems. Whether it's idiomatic or not - depends on the area, I'd say.


I mean it is a 1:1 translation of the js code. Maybe the code is meant to be explicit? But I think what @U2FRKM4TW suggested seems the right way in general.

nate sire15:06:46

I really liked how you put the comment at the top explaining what the code does

🙌 2
nate sire15:06:10

I am a fan of using comments to explain why functions are there


Just in case - that's not a comment, that's a proper docstring. It's available in the var's metadata as well, i.e. as (:doc (meta #'gps-distance)).

👍 2
nate sire15:06:24

is it good practice to use ( ( to square ints... versus expt from the math lib...

nate sire15:06:16

:require [clojure.math.numeric-tower :as math

nate sire15:06:42

because of 1 less dependency?


Yes. It's better to use built-in functions (e.g. *) and platform functions (e.g. js/Math.pow) when they do exactly the same as some function from some third-party dependency.

nate sire15:06:52

I like your idea of extracting some of it into functions... because you can help me remember some pieces of the equations... with a well named function

nate sire15:06:53

e.g.. area versus circumference as a function name instead of pi r ^ 2... just as an example


Is using a top-level let like this, a reasonable way of defining one-off fns, assuming they aren't usable elsewhere in the namespace?

(let [R 6371 ;; km
      square #(* % %)
      PI (/ (.-PI js/Math) 180)
      cos #(.cos js/Math %)
      sin #(.sin js/Math %)
      atan2 #(.atan2 js/Math % %2)
      sqrt #(.sqrt js/Math %)]
  (defn gps-distance
    "calculates distance between gps coordinates in km"
    [{lat1 :lat lon1 :lon} {lat2 :lat lon2 :lon}]
    (let [φ1 (* lat1 PI)
          φ2 (* lat2 PI)
          Δφ (* (- lat1 lat1) PI)
          Δλ (* (- lon2 lon1) PI)
          a  (+ (square (sin (/ Δφ 2)))
                (* (cos φ1) (cos φ2))
                (square (sin (/ Δλ 2))))
          c  (* 2 (atan2 (sqrt a) (sqrt (- 1 a))))]
      (* R c))))
Also, will the tiny fns like the cos and sin be inlined by Google Closure in advanced mode? PS: Dunno if this is even allowed in CLJS. Haven't learned it yet.


That's allowed. I can't answer the question about inlining, but I wouldn't worry about it. You have CLJS compiler running on top of GCC compiler, where the code ends up running on JS VM. You're so removed from the actual execution, that worrying about inlining such functions should be the last thing IMO.

🙌 3
👍 4

Am not too hands-on with cljs of late, but I suppose #(.cos js/Math %) (and the likes) can simply be replaced with js/Math.cos - right?

💯 3


👍 3

I have an image tag that contains a url from the web:

[:img {:height 599
            :width 500
            :alt "Mike Wazowski"
            :src ""}]
However, upon loading this component, I’m getting a 404 in the console for this url, even though the image at the source exists.


Sounds like it has nothing to do with #clojurescript and everything to do with how processes requests. A server can choose to reply with any code, including 404, to any request.


agreed. this sounds like wikipedia saying they won't pay the hosting costs for images for your website


Maybe try without the /revision/latest/top-crop stuff after .jpeg


What is the best way to catch a click outside a div (like a modal) in cljs+reagent? • .addEventListener that should be attached on componentDidMount and detached on unmount • a global overlay div attached to the bottom of the body


If it's just handling of clicks and nothing else, then I don't think there's any functional difference. But if you want to apply some styles to the backdrop (e.g. opacity), then it needs to be a proper DOM node.


Okay thanks!