Fork me on GitHub
#hoplon
<
2019-05-29
>
George Ciobanu00:05:57

hi I have a silly question: is Hoplon alive and well? I really like the philosophy behind it but I noticed that commits are quite infrequent for it and that commits for Castra stopped almost 2 years ago. I'm not assuming that a project needs to be constantly added to / improved, I'm totally ok with the idea that sometimes a product is just done and we can stop adding bells and whistles. I just want to make sure that I'm investing in a framework whose parents are still caring for it 🙂

George Ciobanu00:05:38

@danieleneal would you mind sharing the reddit post?

alandipert02:05:49

@geo.ciobanu it’s definitely alive, i think it could benefit from more users… but there are users, and @flyboarder actively maintains

alandipert02:05:50

among frameworks i think hoplon is distinctive, as we have removed from it over time, and it has no underlying deps such as react

George Ciobanu03:05:59

removing from something is rare 🙂

flyboarder03:05:15

I also intend to remove some more overhead that I didnt fully develop, 7.3 has been a long time coming

flyboarder03:05:23

it’s almost ready

flyboarder03:05:02

gotta fix the reload appending issue, which seems to be a recurring problem when we work on the element init

George Ciobanu03:05:10

I have what I know is a simple question to you but quite a mystery to me. I understand how to use cell and cell= but I'm baffled by how it actually works (and not smart enough to figure out from the source code) When I have a (cell (clicks 0)) and I do 1. (def clicks-even? (cell= (even? clicks))) this works as expected. But when I do 2. (even? clicks) I get an error. In Clojure evaluating form 1 would evaluate (even? clicks) first and then everything else. However form 2 tells me that even? expects an integer. The source code uses a macro for cell= so there is some magic at play. Is there a simple way to explain what the macro does? If not possible don't worry I'll come back to this question once I learn more

George Ciobanu03:05:44

Either way I'm bought into the model an committed to using Hoplon. Quite surprised more people don't use it, it's super intuitive and elegant

dave13:05:06

i also find that surprising! it's so easy to keep in your head, compared to the whole react ecosystem

dave13:05:53

@geo.ciobanu re: cell=, it is a macro, and it does some code-walking to try and figure out which values are cells. when it encounters a cell, it treats it as an input parameter, such that any time the value of one of the cells within that form changes, the formula cell's value recomputes within the context of your example, clicks is a cell, and when you make a formula cell like (cell= (even? clicks)), the formula cell's value updates each time the clicks cell's value updates, and cell= lets you express the new formula cell value in a more concise way, where the cell values are sort of "unpacked" i think it takes a while to fully wrap your head around that idea. it took me a while, anyway. but it does become second nature after a while

dave13:05:25

(even? clicks) by itself produces an error because clicks isn't a number, it's a cell

dave13:05:59

you can do (even? @clicks) to get at the value of clicks, but in practice you will almost never dereference a cell directly like that

dave13:05:32

in my experience, any time i find myself putting an @ symbol in front of a cell, i've found that i'm doing something wrong

Ahmed Hassan10:06:06

Aren't there some places where @ in front of cell is necessary?

Ahmed Hassan10:06:31

Like when passing attribute value from parent to child, you have to deref it.

dave12:06:24

there are exceptions, for sure

dave12:06:42

one example is when you're implementing a :click handler

Ahmed Hassan12:06:50

I use (defn event-target-node-val [evt] (-> evt .-target .-value)) for :click handler to get value of event.

dave12:06:17

a click handler is a function that gets run at the point in time when you click, and it's separate from the hoplon workflow of input and formula cells, so if your click handler needs to use the values of cells, you have to deref those cells

👍 4
micha13:05:52

there is one benefit to cell= in my opinion, from an abstraction point of view

micha13:05:53

i.e.:

(defn foo [x]
  (cell= (+ y x)))
^^ here x can be a cell or a regular value, either one will work

micha13:05:19

this is key in my opinion, or you end up needing to box everything

dave13:05:28

+1. i've used that trick quite a bit

dave13:05:57

if you do it right, you basically end up in a world where you don't have to think about whether things are cells or unboxed values

micha13:05:23

the formula-of is also key, of course

micha13:05:48

in some places you're making glue or plumbing code, so you know which things are cells and which arent

micha13:05:06

especially when you need an anonymous formula that no other code will ever have access to

micha13:05:15

vs. say defining a function with arguments

dave13:05:08

i like formula-of because i sometimes find the ~ cell indicator thingy used within cell= to be confusing, so formula-of gives me an escape hatch when i want to be more explicit about what the inputs are to my formula

micha13:05:26

yeah totally

micha13:05:09

lol i'm an idiot, all the cell constructors can handle cells or values, i don't know why i thought it was just cell=, sorry for the confusion

dave13:05:54

oh, i didn't know that either! i assumed it was just cell= too

micha13:05:18

formula and formula-of etc. also have that property

danielneal13:05:33

has anyone done benchmarks of hoplon wrt react

micha13:05:25

we have a pretty large, complex application with a ton of data and many screens and it's very snappy

micha13:05:22

however there are limits to what you want to do in cells, naturally

danielneal13:05:24

🙂 I was just more thinking with all the recent excitement around svelte, it would be funny if hoplon had been there the whole time, quietly outperforming react...

flyboarder17:05:10

Yes we are probably more performant, but only since the recent 7.x releases

micha13:05:59

if anything hoplon does fewer DOM updates on average, i would expect

micha13:05:21

but that's because cells do more work

danielneal14:05:13

yeah that would be my intuition

George Ciobanu15:05:35

@dave and @micha thank you so much for your insightful replies, I’m deeply grateful

George Ciobanu15:05:58

I haven’t used/seen formula-of but will look into it

George Ciobanu15:05:56

But yes when I just need to things get done thinking about cell= as literally a calculated sheet cell makes it super easy

George Ciobanu15:05:51

I initially tried to reason it as a subscriber to the cells and values it uses - but the spreadsheet model is much more universal and easy to reason about

George Ciobanu15:05:52

One more question: we can do (p clicks) (Clicks is a cell defined as in the tutorial (clicks (cell 0)) ) So (p clicks) works but (p (+ 1 clicks)) does not, and we have to use a cell= instead. It's a bit intriguing to me that I can use the cell itself as a value in a p macro/function AND it gets updated properly but cannot process that value in any other way - I have to use cell= to do that. Just to be clear I love the system and I am using it easily, it's just my curious side that's intrigued. Essentially since these are macros (p and cell=) I am ok to assume they do lots of work behind the scenes and just use it as a black box, but I wanted to raise it as something that, if I understand, I'll gladly create a PR for the tutorial to clarify it for other potential newcomers with the same question.

George Ciobanu15:05:29

@dave I would definitely add the x+y example to the tutorial as well it's really eye opening

George Ciobanu15:05:10

Glad to create a PR for it (with thoughtful explanations around it) sometime this week

dave15:05:14

i think those would be great things to add to the tutorial

dave15:05:02

having the hoplon.core elements (`p` et al) include an "implicit cell=" is an intriguing idea. i wonder if there would be any negative implications

dave15:05:43

can cell= be nested? if not, that could cause problems

micha15:05:07

you don't usually want to nest them

micha15:05:21

really you never do

micha15:05:25

@geo.ciobanu when you do (p "foo") for example, it evaluates to a DOM element equivalent to the following javascript:

document.createElement("P").appendChild(document.createTextNode("foo"))

micha15:05:56

however, when you do (p bar) where bar is a cell, the p function sees that its argument is a cell and wires that cell up to update the text node whenever the cell changes

micha15:05:34

so in your case when you do (p (+ 1 bar)) you have an issue because the + function doesn't understand how to add 1 to a cell

micha15:05:11

but (p (cell= (+ 1 bar))) works because in that case the p functions argument is just a cell

micha15:05:26

strings and numbers are converted into text nodes by the element functions (eg. p, div, etc)

micha15:05:19

you can also do (p :id "foo" "bar") to have <p id=foo>bar</p>

micha15:05:00

or (p :id (cell= (str a "-" b)) "bar") where the value of the id attribute is a cell

micha15:05:13

then the attribute is updated reactively

George Ciobanu17:05:34

@micha that makes sense thank you so much! I'll make sure to update the documentation asap in case others wonder the same thing in the future

micha17:05:20

👍 any time!