Fork me on GitHub
#clojurescript
<
2020-08-13
>
steveb8n03:08:25

Q: I’m trying to validate a long value, a datomic :db/id decoded via transit. some of the values print at #object[Long] or Long { low_: 329, high_: 16175104 }. I presume this means that they are decoded into goog.math.Long. I can’t find a predicate in the goog.math api to validate these values. Any suggestions?

steveb8n03:08:01

I would be happy with just a type check. can’t work out how to do that in Closure either

steveb8n03:08:13

looks like I could use “instanceof” but how do I invoke that from cljs/interop?

steveb8n03:08:57

ah. found it in cljs.core. can use (instance? goog.math.Long x)

Risetto14:08:31

is it possible to export an entire namespace?

dnolen14:08:46

well to be clear - there's not such thing as exporting conceptually in Clojure anyway

Risetto14:08:31

It seems like I could use :modules in my project file to expose an entire namespace as a module, is that right?

dnolen14:08:57

oh, perhaps we're overloading some terms

dnolen14:08:09

what are you trying to do? export a namespace for a JS library to consume or something?

Risetto14:08:33

Yea exactly

Risetto14:08:48

That should be possible, right?

dnolen14:08:05

:modules is not used for that, that's for code splitting

dnolen14:08:51

to directly answer your question - there's no built in way to export a namespace - you use ^:export to do this per definition

dnolen14:08:53

however, you have macros and a programmable build system - you could probably sort it out if you really want that convenience

Risetto14:08:08

Alright, I will go ahead a try. Thank you!

Sam Ritchie15:08:36

I have a separate multimethod eq that can handle equality between goog.math.{Long, Integer}, js/BigInt and js/Number (and the ratios and BigDecimal I need to add next), and I bail out to that from the -equiv implementation if the second arg is not a js/Number

Sam Ritchie15:08:45

(extend-protocol IEquiv
       number
       (-equiv [this other]
         (cond (core-number? other) (identical? this other)
               (number? other)      (eq this other)
               :else false)))

Sam Ritchie15:08:54

bailing out full-stop without the core-number? check is a big performance hit, as you'd expect.

misha17:08:29

I wonder, what is the reason behind:

ExceptionInfo: failed compiling constant: 1/4; clojure.lang.Ratio is not a valid ClojureScript constant.
precision?

noisesmith17:08:00

1/4 should be exactly representable as base 2

noisesmith17:08:15

the clojure ratio type is not a normal number - it can hold rationals that can't be represented as floats without losing precision, what's the context of that error?

noisesmith17:08:50

most of the time I replace (/ x y) with (/ x (double y)) to avoid constructing rationals

lilactown17:08:17

hmm that is a difference between CLJ and CLJS that I hadn’t encountered before

lilactown17:08:46

Clojure:

user=> 1/4
1/4
ClojureScript:
cljs.user> 1/4
------ REPL Error while processing ---------------------------------------------
1/4
Error in phase :compilation

lilactown17:08:20

I’m pretty sure ClojureScript treats all number types as JS number , so it doesn’t have explicit support for rationals like Clojure does

lilactown17:08:14

not sure why the literal isn’t supported (and just returns a JS number), but there you go 🙂

mfikes17:08:43

Perhaps owing to the reader differences, you will get a number for fraction literals in self-hosted ClojureScript

lilactown17:08:49

it seems to fail in non-self-hosted clojurescript thought?

misha19:08:41

noisesmith, context - is a silent :compilation phase error in older version of shadow-cljs, because I had a 1/4 pasted from repl in some form in cljc file. https://clojurians.slack.com/archives/C6N245JGG/p1597334746145300

noisesmith19:08:36

aha, I missed (and found it surprising) that it would blow up like that for a literal

misha19:08:05

the (maybe) weird thing is, cljs main compiles

(ns foo.bar)
1/4
just fine, but throws on
(ns foo.bar)
[1/4]

noisesmith19:08:09

looks like the problem is well explained by prior comments, it seems reasonable to ask that cljs just generate the appropriate float when reading that literal

misha19:08:51

yeah, float was my first expectation too, hence the "precision?" question

noisesmith19:08:33

right, but a power of two divisor should not be a problem...

noisesmith19:08:15

that's literally moving the decimal point in the float representation that js uses

misha19:08:38

I think I'd rather have all ratios throw than just some of them

noisesmith19:08:17

right - what I'm trying to say is we proved that precision isn't the problem

noisesmith19:08:31

it's a type error, in the reader

misha19:08:00

maybe "precision of all possible ratios" then? opieop

noisesmith19:08:35

it's a broken code path

misha19:08:08

I think it is intentionally left as is

noisesmith19:08:38

my hunch is that (ns foo.bar) 1/4 compiles fine because there's no reason to compile the rational - you know a-priori that it's garbage

misha19:08:51

well, [1/4] is a garbage too, although nested, so immediate handling function might not see entire form, and that it is top level one

noisesmith19:08:19

right - top level handling has special cases, but once again it's just a hunch on my part

noisesmith19:08:50

you could also try (ns foo.bar) (do 1/4)

noisesmith19:08:50

the plot thickens

cljs.user=> (do 1/4 :OK)
:OK

thheller19:08:30

constants are just discarded in "statements" (ie. the result is not used). so top level and in do like that is the same.

misha19:08:34

cljs main -compile and -eval worked different for me today for 1/4 and [1/4] , while I was chasing exact behavior.

Sam Ritchie19:08:22

hey all, I found this yesterday -

👍 3
Sam Ritchie19:08:49

let me send the link to the version whre support for this literal dropped

Sam Ritchie19:08:31

this was the change, to defer to tools.reader

Sam Ritchie19:08:58

ratio-pattern lives in reader.impl.commons now, and I don't think the normal codepath includes match-ratio anymore

Sam Ritchie19:08:19

but you can see the old behavior here

phronmophobic23:08:16

it might be because it doesn't make any practical different in this example. no code is waiting on the browser to close.

👍 3
Karol Wójcik12:08:43

That's true, but still we should resolve it so that Promise is not wrapped by chan.

👍 3
dnolen21:08:55

perhaps ported from a JS example where they didn't await in that case either?

lpan22:08:57

in the first screenshot (JS example) there is an await there. maybe it is a typo in the http://clojurescript.org guide :thinking_face: