Fork me on GitHub
#hoplon
<
2016-12-13
>
laforge4913:12:32

Having a problem with hoplon. I want to present things different ways. Some times I want to show the parts separately, other times all at the same time. So I broke my code into several functions, call them in two different places, and use toggle to control which view show be present.

laforge4913:12:42

One of the parts has all the controls--buttons and state display. When I have it display by itself, it is fine. But when displaying it in a table with the other parts, it comes up blank.

laforge4913:12:57

Here's the piece which handles the toggle:

thedavidmeister13:12:57

when you say “blank"

thedavidmeister13:12:01

is it actually in the DOM

laforge4913:12:13

How can I tell?

thedavidmeister13:12:02

like, with inspect element

laforge4913:12:53

is that part of the developers console for chrome?

laforge4914:12:01

ok, I found element in the console. Thanks @thedavidmeister !

laforge4914:12:51

The part that is blank is not present in the dom.

thedavidmeister14:12:50

so it’s an issue with updating the dom, not the toggle

thedavidmeister14:12:59

i’ve seen in my code that you can’t reuse elements

thedavidmeister14:12:35

(let [e (div)] [(div e e)]) will be <div><div></div></div> for example

thedavidmeister14:12:40

that might be it?

laforge4914:12:48

I'm trying to create them twice, not reuse them.

laforge4914:12:10

Things like div just return functions, yes?

thedavidmeister14:12:55

div returns an actual DOM element

laforge4914:12:20

And each time it is called it returns the same dom element?

thedavidmeister14:12:20

(let [e (div)] [(div e e)]) won’t work but (let [e div] [(div (e) (e))]) will

thedavidmeister14:12:31

it literally returns a dom element

thedavidmeister14:12:49

div is a function that returns a new dom element

laforge4914:12:55

So I should get 2 elements if I call it twice?

thedavidmeister14:12:56

it isn’t higher order

thedavidmeister14:12:06

if you call it twice, yes

laforge4914:12:23

I do. the second call works.

thedavidmeister14:12:13

could you link the line number of the code that’s not working?

thedavidmeister14:12:21

that file you linked is pretty long

laforge4914:12:18

the call to do-commands in this snippit generates no dom elements:

laforge4914:12:00

But the call to do-commands in this snippet does:

thedavidmeister14:12:49

do-commands is not a function

laforge4914:12:54

the code for do-commands is quite long.

thedavidmeister14:12:02

but it’s just a dom element

laforge4914:12:33

it is defined as a function...

thedavidmeister14:12:54

(def do-commands (h/div …))

laforge4914:12:22

yup. but that is also how do-all and everything else are defined.

thedavidmeister14:12:27

maybe you meant (def do-commands #(h/div …))

thedavidmeister14:12:47

sure, you have a bunch of detached dom elements that you are composing

thedavidmeister14:12:02

which is actually awesome for testing, as you can probe your detached elements however you want without needing a whole page

thedavidmeister14:12:28

but yeah, if you want more than one you have to promote what you’re doing to a function 🙂

laforge4914:12:51

I am still new enough at hoplon that the code-walking makes me bug prone, as sometimes I need to dereference a cell (when outside of code walking) and sometimes not.

candera14:12:30

Me too. So now I only use cell= for really simple cases.

alandipert14:12:18

if you want to make formulas more explicitly, you can also use the formula function

alandipert14:12:38

i.e. (cell= (+ x y)) = ((formula +) x y)

alandipert14:12:42

(formula is a function)

candera14:12:42

formula-of expands to formula.

candera14:12:56

I could have been clever and called it “formulet"

laforge4914:12:16

I also do not like magical things in general. So, for example, I've been converting my .cljs.hl files to .cljs files and using :as. I think it lowers one of the barriers to acceptance. Too much hoplon magic means only hoplon devs will be happy with my code, at best.

alandipert14:12:16

oh derp, you're using formula in your macro there

candera14:12:53

Yeah, it’s just let+formula, really.

candera14:12:13

Which is all I want a lot of the time.

alandipert14:12:41

so now that i've actually read the code and your comment introducing it, i think it's great

alandipert14:12:51

my only suggestion would be to perhaps call it with-formulas

candera14:12:06

“formulet” too cute? 🙂

alandipert14:12:57

i do enjoy that name hehe

candera14:12:09

I have no real objection to with-formulas, though, other than vague uneasiness that it co-opts the with metaphor.

candera14:12:32

But it’s consistent with how hoplon names things.

alandipert14:12:36

yeah, which is kind of not perfect, since the names here are lexical

alandipert14:12:45

vs. dynamic as in with-open

candera14:12:02

Well, the names in with-open aren’t dynamically scoped, are they?

candera14:12:12

I mean, I guess the resource’s lifetime is.

candera14:12:20

But that’s basically true here, too.

alandipert14:12:32

i guess it's not the name that's dynamic, but the resource. ie if you capture the file in a closure and return it, the file will have been closed

candera14:12:36

Anyway, I don’t really think of the formulae as resources.

candera14:12:20

formula-let is probably a better (albeit less creative) name.

alandipert14:12:31

the real reason i prefer with- is because editors indent 'defun-style' by default usually

candera14:12:56

Yes, that has been annoying in my code.

alandipert14:12:58

which is petty, and i'm lazy

candera14:12:39

TBH, I don’t care much what it’s named.

alandipert14:12:04

i think it's cool tho

candera14:12:16

Well, feel free to steal it.

candera14:12:46

Eh, screw it: it should be formulet. 🙂

laforge4914:12:09

Could you give an example with map? 🙂

candera14:12:11

It’s in the docstring, but let’s say you have this: (def foo (cell {:x 1 :y 2}))

candera14:12:31

You could do (formula-of {{:keys [x y]} foo} (+ x y))

candera14:12:59

And you can bind more than one cell, as in the docstring example. Arbitrary destructuring, since it just turns into let.

candera14:12:33

The vector form always just binds the names to the corresponding cell values.

candera14:12:38

So the map form is more general.

candera15:12:31

In the map, the keys are the binding forms, and the values are the cells against which to bind.

candera15:12:52

This is similar to generalized map destructuring in a let (which no one ever uses :))

laforge4915:12:50

Looking at (formula-of {foo x {:keys [a b]} y} (+ x a b))

laforge4915:12:10

Shouldn't it be (formula-of {foo x {:keys [a b]} y} (+ foo a b))?

candera15:12:25

Yes. Thanks.

candera15:12:49

Which is why I never use the generalized map binding in Clojure. 😉

candera15:12:41

Docstring updated for clarity:

laforge4915:12:17

That really makes it clear. 🙂

candera15:12:32

OK, so Hoplon question. In lots of places, I’m conditionally building up UI, and I would like nil to mean nothing. Instead, it seems to stop rendering. E.g.:

candera15:12:19

Instead, I wind up using (if-not foo? [] (div “Fooey”))

candera15:12:23

Which, meh.

alandipert15:12:41

yeah - that's a bug

candera15:12:29

OK, thanks.

alandipert15:12:29

(def NIL ()) 😎

candera15:12:45

Just threw up in my mouth a little. 🙂

alandipert15:12:58

actually if you have a minute to make a ticket, that would be helpful

candera15:12:04

Sure, I can do that

alandipert15:12:11

this has come up before but we keep forgetting 🙁

alandipert15:12:48

oh wait - think there might already be a PR, https://github.com/hoplon/hoplon/pull/160

alandipert15:12:38

yeah - that's the one

alandipert15:12:00

i think micha was gonna do a javelin release today (2x perf!), i'll try to do a hoplon one also

candera15:12:14

Yep, that’s it. Thanks!

flyboarder15:12:19

I think we may want to attempt something else there tho, like a flatten 😹

flyboarder15:12:48

Or remove nil?

micha15:12:30

@candera the way i handle the case where i want to swap! on a cell inside a formula is like this:

micha15:12:20

(cell= (if foo (~(partial swap! bar) + baz) bar))

candera15:12:00

Ah, I didn’t realize interpolation was available.

micha15:12:10

the unquote symbol is coopted here to do evaluation at cell construction time

candera15:12:19

Have to say, I prefer formulet. 🙂

candera15:12:26

That’s a bit magical for my taste.

micha15:12:28

the name is most excellent

micha15:12:24

the binding map is interesting

micha15:12:58

what was the reason for using a map for binding forms?

candera15:12:00

Because it’s a map. 🙂

candera15:12:06

From cells to binding forms.

candera15:12:15

Well, the other way around.

candera15:12:44

I mean it’s inherently an association.

micha15:12:04

is that different from a vector that is constrained to have an even number of forms in it?

micha15:12:10

like the way clojure let works

candera15:12:34

No, not really. But I wanted vector to have another meaning, so it would be ambiguous.

micha15:12:15

i see now

candera15:12:21

:thumbsup:

micha15:12:58

perhaps two macros

micha15:12:12

formulet and with-cells or whatever

micha15:12:26

nm bikeshed is good how it is

candera15:12:30

I definitely like having two names for two things, and would not object to two forms since the semantics are different. In this case I think the harm is small, but generally the impetus towards not overloading things is one I like.

micha15:12:33

cell= could support this itself, too

candera15:12:47

Really? That sounds gross. 🙂

micha15:12:52

possibly lol

micha15:12:12

(cell= [x y z]
  (+ x y (/ z 2)))

candera15:12:18

Yeah, yuck.

candera15:12:30

What does (cell= [a b]) mean?

micha15:12:43

always returns nil, naturally

micha15:12:55

that would just be what it is now

micha15:12:10

yeah not good

candera15:12:33

We have an infinite number of names available. Rip off another one. 🙂

candera15:12:08

Rich’s joke (or was it Stu?) was a good one: there are more names than GUIDs.

candera15:12:43

We can stop acting like they’re a limited resource. Good names are hard, but I think we need to stop overloading as much as we do. Talking about myself mostly here - not Hoplon in particular.

micha15:12:47

lol only a computer programmer would say such a thing

candera15:12:33

Seriously Slack? I thought I left this sort of nonsense behind when I stopped using HipChat.

micha15:12:05

i'm excited about the performanec improvements in javelin

micha15:12:18

hopefully it will be noticeable in real world application

micha15:12:56

a large part of the annoying startup time is javelin related i think

candera15:12:53

My weather app has a fair amount going on - I should be able to tell you if there’s an improvement pretty easily, as I already have some metrics in place and can add more.

micha15:12:17

i think there is an issue with the hoplon optimizations

micha15:12:24

but the javelin ones should be good to go

micha15:12:04

the weather map would be a good benchmark

micha15:12:14

many cells involved there

candera15:12:38

Not quite as many as you’d think - I can't use cells for the individual squares, because slow. But still a fair number.

jjttjj17:12:56

@alandipert I think that PR I submitted for the nil hoplon element args was kinda a naive fix and I hadn't really considered or properly understood the performance implications, which i remember @micha had some comments on. I will play around with it now a bit though and test things out with the hoplon master. and get a better sense for how much extra work is happening as a result of that change

micha17:12:32

@jjttjj i think my PR handles the nil child case

micha17:12:48

we reworked the way the flattening of children is done

micha17:12:56

that was the performance issue before

jjttjj17:12:06

ok awesome

micha17:12:21

now we roll the nil checks into the body of the flattening loop

micha17:12:59

i think there might be some issue with that PR though

micha17:12:31

jumblerg said something wasn't right when he tried it on his application

laforge4918:12:07

Different problem now. I call do-commands to generate the same dom elements in two differrent places and use toggle to select the one that should be visible. But initally both are visible. Any ideas? Here's the code:

laforge4918:12:54

In the above, the do-all function also calls do-commands.

laforge4918:12:24

Am I missing something about toggle? @micha?

micha18:12:34

there is a simple solution you can use for now

micha18:12:26

it's just an instant when both are visible at the same time, yes?

laforge4918:12:48

No, it sticks until I change display-mode

laforge4918:12:26

But it only happens on reload.

mynomoto18:12:54

@laforge49 I think your :style is overwriting your :css on your second div.

laforge4918:12:21

Oh! Did't notice that. Thanks!

laforge4918:12:52

That fixed it. 😄

flyboarder20:12:35

@micha: I noticed a thing about defelem, it will accept multiple body forms but only display the first one

flyboarder20:12:00

So if you accidentally close the elem form it's hard to debug

micha20:12:07

it should returnthe last one

micha20:12:15

like any function

flyboarder20:12:23

That might be what it's doing

flyboarder20:12:35

I just remember there is nothing to help find the problem

flyboarder20:12:44

Ran into this yesterday

micha20:12:46

it works the same as functions though

micha20:12:17

(fn [x]
  [1 2 3]
  [4 5 x])

micha20:12:24

you never see [1 2 3]

micha20:12:06

the expressions before the last one are for side effects

flyboarder21:12:49

Right, hmm I guess there isn't an easy way to check for this since we can't know what the developer intended

cdine21:12:35

A hoplon newbie here. How can I use an input cell whose value is a reference to an another input cell, inside a formula cell..?

micha21:12:45

usually you don't want to do that 🙂

micha21:12:56

what would you like to do?

cdine21:12:49

Kinda need that for a meta-ish app.. for example, (i do not have the exact snippet handy) a vector of maps like [{:name "a" :ref (cell 1234)}] and an element (defelem) iterating over these to display names and values.

cdine21:12:28

my formula cell has something like (cell= (str (:name element) "," (deref (:ref element))))

cdine21:12:06

the problem that I have is , If i mutate the reference (reset!), the view doesn't get updated

cdine21:12:48

but if the mutation touches both name and ref part of the element , then the view refreshes (as the formula cell uses both name and ref keys)

micha21:12:21

cells are immutable, in the same way as atoms are

micha21:12:36

updating the value inside a cell does not change the identity of the cell

micha21:12:22

so far we have not seen a single case where there is a need to have cells inside cells

cdine21:12:27

think of an app where the data flows into the app (somehow) and the user interface is just an exploratory (drag dropish system) surface where he can define cells, formulae, etc...

cdine21:12:31

the app as such doesn't come with pre defined cells whereas the user defines his views over the data (by defining cells and formula cells)..??

cdine21:12:32

of course a hobby project 🙂

micha21:12:44

since there is no eval in the client via clojurescript you will need to create cells via your own little interpreter

cdine21:12:46

but anyway, your comment answered it all (updating the value inside a cell does not change the identity of the cell)

dm321:12:17

you could do something with cljs-in-cljs, at least I've thought about it

dm321:12:29

but it's just too complicated for any real benefit

cdine21:12:38

Yeah I've been using replumb as a cljs repl (self hosted)

cdine21:12:11

yeah I understand that... its just a hobby project (which i'm sure, i will never complete)

cdine21:12:37

but thanks @micha for your prompt responses..

micha21:12:43

sure any time 🙂

micha21:12:01

i'd like to port javelin to cljs one day

micha21:12:28

i mean the macros

cdine21:12:32

btw, it has been wonderful exploring Hoplon so far

cdine21:12:47

so thanks for that as well.

alandipert21:12:05

that's always nice to hear. what were you using before?

cdine21:12:22

re-frame for almost all my cljs apps so far

alandipert21:12:24

anything seem lacking compared to reframe?

cdine21:12:20

not much.. It was a pleasure using re-frame... sometimes interop with third party js plugins was offputting. ever since the latest release (dynamic subscriptions and effects handlers), it was a breeze.

chromalchemy22:12:33

@jumblerg How do you do :toggle functionality on UI elems? With the :v attribute for visibilty, hidden elems still take up space in the layout flow.