Fork me on GitHub
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?


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


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 🙂


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


it’s almost ready


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


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


@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


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


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


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.


there are exceptions, for sure


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.


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

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



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


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


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


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


the formula-of is also key, of course


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


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


vs. say defining a function with arguments


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


yeah totally


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


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


formula and formula-of etc. also have that property


has anyone done benchmarks of hoplon wrt react


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


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


🙂 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...


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


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


but that's because cells do more work


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


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


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


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


you don't usually want to nest them


really you never do


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



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


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


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


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


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


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


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


👍 any time!