Fork me on GitHub
#clojurescript
<
2020-08-28
>
Chris11:08:34

Hi guys, I’m having problems using the promesa library. For example I’m trying to evaluate this small piece of code I got from the promesa user guide:

@(-> (p/resolved 1) (p/then inc))
But I’m getting:
=> #object[Error Error: No protocol method IDeref.-deref defined for type object: [object Promise]]

Chris11:08:25

I’m trying to build a small clojurescript frontend using shadow-cljs and reagent

thheller11:08:37

you cannot deref promises

Chris11:08:07

So that part is only for using the JVM probably

thheller11:08:25

yeah, JS is single threaded so you cannot block to wait for something since that would never arrive

Chris11:08:38

I was trying to play around with promesa because I’m having another problem with it. I have the following code:

(defn note-exists
  [identifier]
  (p/promise
   (fn [resolve reject]
     (ajax/GET (str BASEURL "/api/notes/" identifier "exists")
               {:handler resolve
                :error-handler reject
                :response-format (ajax/ring-response-format)}))))

(defn- handle-create-note
  []
  (-> (note-exists @active-note)
      (p/then #(.log js/console %))
      (p/catch #(.log js/console %))))
handle-create-note is being executed on button click. However, the following is being printed:
function note_exists(resolve, reject)

Chris11:08:45

It seems as if the value of the promise is the inner function and it does not execute the ajax request

thheller11:08:40

I have never used promesa so no clue what it does sorry

Chris11:08:04

I have found a solution, seems like some examples on the Internet are not up to date anymore, at least regarding cljs. I had to use (p/create ...) instead of (p/promise ...) . Now it works fine. Thanks!

👍 3
jjttjj14:08:28

Assume IFn's -invoke is implemented for js/Element so I should be able to invoke the elem here.

(defn mksvg [tag]
  (fn [& args]
    (let [[attr kids] (parse-args args)
          xmlns ""
          elem (.createElementNS js/document xmlns tag)]
      (elem attr kids))))
But when I call this, I get TypeError: elem is not a function . I can get around this by using apply just wondering if this is expected behavior.

thheller15:08:11

in shadow-cljs this sort of breaks since it assumes JS types don't implement IFN for an optimization I did. see https://github.com/thheller/shadow-cljs/issues/742

👍 3
thheller15:08:18

still need to add the flag to turn that off 😉

p-himik15:08:28

Perhaps it could be solved by treating an ^IFn tag in a special way? So that

(let [elem ^IFn (.createElementNS js/document xmlns tag)]
  (elem attr kids))
would emit a code that uses -invoke.

p-himik15:08:28

Oh maybe that would be an unjustified complication given that apply already works.

thheller15:08:14

nah I'll just add a flag to turn off the optimization for people that don't care 😉

👍 6
thheller15:08:52

^IFn elem (.createElementNS js/document xmlns tag) might already work. this is only an issue because elem inherits the js tag from js/document

jjttjj15:08:09

Thanks for the info!

thheller15:08:19

in cases where the type isn't known it won't use the optimization

p-himik15:08:42

BTW is there any difference between (let [^IFn elem (...)]) and (let [elem ^IFn (...)])?

p-himik15:08:02

Not for this particular problem but in general.

thheller15:08:28

I don't think ^IFn (...) does anything but not actually sure. don't think I've ever used this variant.

p-himik15:08:59

clojure.core uses both FWIW.

thheller15:08:36

then I suppose it does something 😛

thheller15:08:58

so I don't forget to actually add the flag: https://github.com/thheller/shadow-cljs/issues/783

thheller15:08:35

wouldn't recommend using IFn on JS types too much though

misha17:08:10

greetings! is there faster way to split vector in 2 parts, insert another vector between those, and glue those back together as a vector?

(let [r (vec (range 20000))]
  (do
    (time
      (into 
        (into 
          (subvec r 0 10000)
          [\a \b \c])
        (subvec r 10000)))
    nil))
"Elapsed time: 11.960002 msecs"

phronmophobic17:08:34

https://www.clojure-toolbox.com/ has some interesting options under "Data Structures". I think https://github.com/clojure/core.rrb-vector might be what you're looking for

misha17:08:24

reading, thanks

misha17:08:42

(let [r (vec (range 20000))]
  (do
    (time
      (into 
        (into 
          (subvec r 0 10000)
          [\a \b \c])
        (subvec r 10000)))
    nil))
"Elapsed time: 28.849998 msecs"
=> nil


(let [r (vec (range 20000))]
  (do
    (time
      (rrbv/catvec
        (rrbv/subvec r 0 10000)
        [\a \b \c]
        (rrbv/subvec r 10000)))
    nil))
"Elapsed time: 7.060001 msecs"

Alex Miller (Clojure team)18:08:33

note the memory impacts too - subvecs just takes slices out of the original vector, which is retained in full

👍 3
grounded_sage19:08:31

This will seem like an odd question. But whats a simple function that would result in a js error. It’s for testing a macro that does error handling.

phronmophobic19:08:01

my goto is (/ 1 0)

p-himik19:08:28

And you got Infinity, not an error.

dpsutton19:08:29

(get-in 3 :bob)

👍 3
grounded_sage19:08:33

This is actually ininity xD

dpsutton19:08:01

(seq :a)

👍 3
p-himik19:08:04

IMO the simplest and the most obvious is (throw (js/Error. "hello")).

phronmophobic19:08:14

whoops. I guess I'm usually in clj

grounded_sage19:08:02

Yea I guess I just stick with the throwing. It just didn’t seem right to me for some reason.

grounded_sage19:08:30

There is some looping functions also. So the get-in one seems like a good option for that

Milan Munzar20:08:46

Do you guys know why the build watcher triggers twice each time I make a change? First time it compiles, second time it just copies some jar files witch are copied in the first step too. I have took the function from https://funcool.github.io/clojurescript-unraveled/#watch-process . Thank you :)