Fork me on GitHub
#hoplon
<
2016-11-20
>
thedavidmeister01:11:45

@flyboarder yeah, it’s weird though because the div being added/removed is not a parent but a sibling of an ancestor

flyboarder01:11:45

Do you have a link to the element?

thedavidmeister02:11:03

not sure what you mean by that @flyboarder ?

flyboarder02:11:37

@thedavidmeister: like a link to the github file

thedavidmeister02:11:22

oh right, nah i don’t

thedavidmeister02:11:43

it’s in a private repo and has a lot going on anyway

thedavidmeister02:11:56

it looks something like this though

thedavidmeister02:11:30

(div (if-tpl c (div “foo”)) (div (input)))

thedavidmeister02:11:02

and c can change from true to false as the user types in input

thedavidmeister02:11:32

(div (div (input)) (if-tpl c (div "foo")) ) does not lose focus

thedavidmeister02:11:53

(div (div (if-tpl c (div "foo”))) (div (input))) also seems ok

micha04:11:31

@thedavidmeister could have something to do with the hanging alternative clause

micha04:11:40

does when-tpl have the same issue?

alandipert04:11:03

i have happened upon a braintickler re: settimeout ordering

alandipert04:11:28

maintaining your own queue only seems to work if you have a uniform timeout amount in ms

thedavidmeister04:11:30

@micha ooh, worth trying out

thedavidmeister05:11:20

@alandipert yeah.. unless you had a master loop and something like a crontab?

alandipert05:11:03

it wasn't very hard to see it go out of order

alandipert05:11:06

i can't believe i never knew this

alandipert05:11:36

well, i dont personally want cron exactly

thedavidmeister05:11:48

but that kind of thing waves hands

alandipert05:11:56

but yeah, 'discrete event simulation' its called, i think

alandipert05:11:34

i need it to have a proper SLEEP function in my basic interpreter aw_yeah

micha05:11:51

wait so you're saying that if i do like

micha05:11:20

setTimeout(function() { console.log("one") }, 0)
setTimeout(function() { console.log("two") }, 0)

micha05:11:24

it could print

micha05:11:02

is there a demo of it?

micha05:11:25

i am skeptical

thedavidmeister05:11:25

it’s like… a browser specific thing according to that post

micha05:11:53

it must put the things on a queue

micha05:11:11

like when you call setTimeout it needs to return and keep executing your code

micha05:11:17

so it has to put the callback somewhere

micha05:11:21

on a queue of course

micha05:11:43

and it has to finish putting the first callback somewhere before it can start evaluating the second setTimeout call

micha05:11:19

color me skeptical af

micha05:11:45

if you do like

micha05:11:27

setTimeout(function() { console.log("one") }, 150)
// some other code
setTimeout(function() { console.log("two") }, 150)

micha05:11:04

then maybe

alandipert05:11:43

hm yeah, i can't get it to break in ff or chrome

alandipert05:11:54

i think i do need to make my own master loop for my sleep code tho

alandipert05:11:11

since i can't let other timers pre-empt my thing

micha05:11:17

i don't think it's true

alandipert05:11:03

it's like the pool dye that turns blue with pee

alandipert05:11:39

i did a similar thing

(def n 1000000)
  (def xs (vec (range n)))
  (def ys (atom []))
  (dotimes [i n]
    (.setTimeout js/window #(swap! ys conj i) 0))
  (.setInterval js/window
                (fn [] (when (= (count @ys) n)
                         (println "equal?" (= xs @ys))))
                1000)

micha05:11:24

there cleaned up and simplified

thedavidmeister05:11:20

sure, i don’t have any ie boxes on this computer

thedavidmeister05:11:33

so i can’t check that

alandipert05:11:38

(def queue (atom cljs.core/PersistentQueue.EMPTY))

(defn handle []
  (let [[not-before thunk] (peek @queue)
        now                (.getTime (js/Date.))]
    (if (<= not-before now)
      (do (thunk) (swap! queue pop))
      (.setTimeout js/window handle (- not-before now)))))

(defn enqueue
  [ms f & args]
  (let [not-before (+ (.getTime (js/Date.)) ms)]
    (swap! queue conj [not-before #(apply f args)])
    (.setTimeout js/window handle ms)))

alandipert05:11:53

this solves the non-0 timer delay problem, by giving you your own queue

alandipert05:11:32

i guess it depends on the idea that all calls to enqueue will result in different values of now, which i'm not sure is true

micha05:11:53

not-before is just setTimeout i believe

micha05:11:04

that's the guarantee of it

alandipert05:11:12

you mean the whole code is ident. to setTimeout?

micha05:11:18

i believe so

alandipert05:11:19

i don't think so, since i have my own queue there

alandipert05:11:31

it only compares the time for the thing at the head of the queue

alandipert05:11:45

ie the queue is not ordered by ms

micha05:11:03

how is that different?

alandipert05:11:40

it's different because if you have 2 sequential setTimeout calls, and the first waits longer than the 2nd, the 2nd could go off first

alandipert05:11:45

that couldn't happen in my thing

micha05:11:00

is the timeout for the same number of ms?

micha05:11:10

for the two calls?

alandipert05:11:19

let's say the first call timeout is 10x the 2nd one

alandipert05:11:26

or 100x, whatever

alandipert05:11:38

in my thing the waiting is sequential

alandipert05:11:56

probably only useful for sleep

alandipert05:11:09

(enqueue 3000 println "one")
  (enqueue 0 println "two")

micha05:11:10

it would only ever manifest when you block the event loop for 100x the first timeout

micha05:11:14

which is already fucked

alandipert05:11:35

yeah but this is exactly what i want for sleep in basic

alandipert05:11:40

this is the driver loop for instructions

micha05:11:54

you want to block the event loop?

alandipert05:11:04

not the browser's event loop

alandipert05:11:10

but hte program's

micha05:11:23

only blocking the browser event loop will manifest the issue you describe though

micha05:11:34

otherwise they will always fire in the correct order

micha05:11:48

at least this is my belief

micha05:11:08

eg timeout A set to 1500 ms

alandipert05:11:08

i'm solving a differnt problem

micha05:11:12

and B set to 15 ms

micha05:11:29

the only way A will fire before B is if you block the event loop for more than 1500 ms

alandipert05:11:49

(.setTimeout js/window println "one" 3000)
  (.setTimeout js/window println "two" 0)

micha05:11:58

and even then only if the event queue isn't sorted in the browser

alandipert05:11:59

that should print out two, one, right?

alandipert05:11:18

yeah, not what i want

alandipert05:11:38

if i have two sequential sleep commands, i don't want the code after the shorter one to go first... it needs to wait for both in order

alandipert05:11:43

hence my own queue

micha05:11:52

that makes sense

alandipert05:11:41

now my question is, in a JS program does new Date().getTime() ever return the same number twice

alandipert05:11:45

looks like... yes

micha05:11:52

you could just retry then

micha05:11:00

put a validator on the atom or whatever

micha05:11:18

if the date is the same it could reject it

thedavidmeister05:11:30

yeah i did something like that

alandipert05:11:34

oh right, i could make my own function to get the ms

thedavidmeister05:11:38

i kept track of a “highest seen"

alandipert05:11:49

and it always returns a unique one by running the thing long enough to get at least 2 diff ones

alandipert05:11:02

altho that slows my thing down

thedavidmeister05:11:10

if now > highest seen return now else return highest + 1

micha05:11:18

but ideally though the second settimeout wouldn't be evaluated until the first one fired already

thedavidmeister05:11:23

solving a different problem but maybe that helps?

micha05:11:43

like a settimeout loop that waits until the sleep is done before making another sleep

alandipert05:11:10

actually, i don't think the time problem affects me

alandipert05:11:30

since i'm already ordering the events in a queue, i don't have to worry about order

alandipert05:11:01

ie the enqueue call order governs what happens next. when exactly it happens might be a lil fuzzy but thats ok

alandipert05:11:59

i think if you implement settimeout atop settimeout tho, then you need it

alandipert05:11:22

yeah, not a thing to do

micha05:11:24

starting on a blog post about ah btw

micha06:11:11

it's this thing we use to deploy services on AWS

micha06:11:48

really more of a pattern plus this shell script

alandipert06:11:33

dude awesome

alandipert06:11:01

we need to polish off the s3 secret storage concept also

micha06:11:08

yeah definitely

micha06:11:15

i've been thinking about it lately

alandipert06:11:19

i guess we just need some conventions for ourselves

micha06:11:20

we need that thing

micha06:11:43

lol i made the repo

micha06:11:53

so that's one song in the bag

micha06:11:56

next song

thedavidmeister06:11:37

oh ok, so examples for deploying hoplon, or more general than that?

alandipert06:11:37

the cleaned-up thing, calling it after:

(def default-queue (atom cljs.core/PersistentQueue.EMPTY))

(defn- handle [q]
  (let [[not-before thunk] (peek @q)
        now                (.getTime (js/Date.))]
    (if (<= not-before now)
      (do (thunk) (swap! q pop))
      (.setTimeout js/window #(handle q) (- not-before now)))))

(defn after
  "Enqueues a function for invocation after some number of ms. The function is
  not invoked until after all previously enqueued functions have been invoked."
  ([ms f] (after default-queue ms f))
  ([q ms f]
   (let [not-before (+ (.getTime (js/Date.)) ms)]
     (swap! q conj [not-before f])
     (.setTimeout js/window #(handle q) ms))))

thedavidmeister06:11:47

@micha when-tpl didn’t help with the focus thing, fyi

thedavidmeister06:11:13

all good though, happy enough to just leave my errors sitting in a wrapper div for now

jumblerg06:11:20

@micha: circling back to our previous conversation, are you on board for factoring out the cljs ns+ into ns for cljs.hl files (and a clojurescript pull request for :refer :all)?

jumblerg06:11:43

ns+ is also broken on clojurescript 9.

jumblerg06:11:19

i'm also thinking that, in the next version of castra, we should drop the jquery promise in exchange for an ecmascript 6 promise and a polyfill. something like https://github.com/taylorhakes/promise-polyfill.

jumblerg06:11:09

the advantage of this is that it provides compatibility when chaining together calls with the browser's native apis like websockets, getUserMedia, and webrtc.

flyboarder16:11:46

@jumblerg: We can implement castra via a multimethod so we can factor out the "how" portions to providers

mynomoto17:11:59

I have being thinking about providers is general and I believe it's a bad idea. It's hard enough getting one provider to do what we want and having libraries that work in a sane way. IMO another provider should be a fork. Flexibility is not always good and may be pretty bad.

flyboarder17:11:32

@mynomoto: But I think being able to move between different providers is essential for diverse applications, see feathersjs for example https://docs.feathersjs.com/clients/rest.html

mynomoto18:11:55

Support all possible things is not essential. Not make those impossible I think it's fair. Make abstractions that allow everything is bad practice imo.

mynomoto18:11:47

I have used hoplon with rest and castra, used websockets with it and never needed the provider concept. The cell abstraction was rich enough for all use cases I had.

mynomoto18:11:38

I'm not saying I'm against replacing implementations, I'm against having multiple ones.

micha19:11:46

i think i agree with @mynomoto

micha19:11:11

the problem is with libraries really

micha19:11:50

it would be unfortunate if the libraries get fractured to the point where they only work with some permutation of providers

micha19:11:16

hoplon really should i think standardize that layer

micha19:11:25

so you can write libraries in a well-factored way

micha19:11:33

maybe that means that hoplon should have its own compatibility api

micha19:11:49

like its own Event type, and its own XmlHttpRequest type etc

flyboarder19:11:59

Agreed doesn't hoplon do two things really, give you meaningful abstractions and a default implementation for it

micha19:11:24

it is "hosted" like clojure

micha19:11:33

like clojure doesn't box strings or primitives

micha19:11:39

this lets you do lots of stuff

micha19:11:50

but then it is tied to the platform

micha19:11:57

same with hoplon

micha19:11:21

it doesn't wrap the jquery Event object for example, or the dom element, etc

micha19:11:13

honestly it's hard to see the real benefit of un-jquerying

micha19:11:32

like with castra, i don't really understand what is holding back websockets or webrtc or whatever

mynomoto22:11:40

I think it will be more productive to the Hoplon ecosystem to stick with jquery (not un-jquerying things), keep things simple, so hoplon should only be concerned with creating/updating the dom and adding event listeners. And have a sane release cycle following what Ember does, this would remove the problem of shipping compiled hoplon libraries and make boot-hoplon optional for users.