Fork me on GitHub
#hoplon
<
2023-06-01
>
kennytilton05:06:48

Call follow-ups: • regarding a full-blown flutter/mx project, not me, but I was stunned to learn over the winter that someone else was using f/mx to build an app, and now I gather they are close to shipping. More I do not know! • Micha, you have me curious about web components. I will look into them. That said... • ...unless a contract using Web/MX comes up, I plan to concentrate on Flutter/MX. It is just too much fun working on TodoMVC and watching it hot reload simultaneously on a sim, web page, and desktop app. 🙂 And looking at the leap they made in Dart 3, I think Flutter has a great future. And given the unpleasantness of Dart programming, and the absence of a good state solution for Flutter, I believe CLJD has a great opportunity. Thx again for the opportunity to present!

kennytilton11:06:09

btw, I yapped so much we never got to: https://kennytilton.github.io/web-mx-quickstart/#/ That is as terse as I can get!

dvorme18:06:13

I'm so happy to see Hoplon being maintained again! Thanks everyone!

dvorme18:06:00

Lately, I've been gravitating toward using lit and custom HTML elements for Hoplon-esque front-end things and I'm thinking about building an interop layer. Reading the Hoplon source, I come across [boilerplate that (I think) monkey-patches the DOM classes](https://github.com/hoplon/hoplon/blob/master/src/hoplon/core.cljs#LL548C1-L552C1) for each HTML element individually. I'm wondering if this remains necessary to Hoplonify web components or if there might be a way to monkeypatch lit-element and automagically support all web components built using Lit? (At this point I'm out of my league with Hoplon and JS interop. 🙂 )

mynomoto18:06:55

I will have to take a look but we probably could have a custom constructor that would hoplonify lit elements.

mynomoto18:06:29

Is https://lit.dev the one you are talking about?

dvorme18:06:02

> Is https://lit.dev the one you are talking about? Yes. Thanks.

mynomoto19:06:52

I saw a wiki page about using hoplon with polymer when I was checking for stale information about Hoplon and in that case I think there was nothing Hoplon specific happening: https://github.com/hoplon/hoplon/wiki/Hoplon-with-Polymer :thinking_face:

thumbsup_all 2
dvorme18:06:08

A design truism I've relied on for a long time is: "Only invent something new if you have to." One of the things I like about Hoplon is that it seems to follow this principle. With that in mind, after approximately 3 years of coding in Clojure, I'm still confused about why people seem to like hiccup-oriented-programming (HiccOP) so much? Can anyone here help me to understand why--from a HiccOP programmer's perspective? Is there some benefit to HiccOP that Hoplon doesn't have that I'm missing? Thanks in advance.

mynomoto18:06:13

You can treat hiccup as data and do things like

(-> [:div]
    (conj [:span "Hello"]))
This is a simple example but it can be powerful and useful.

mynomoto18:06:04

People also like that you can check the structure without rendering in a browser, you can test that the data returned has some shape or is equal to some vector.

dvorme19:06:31

Okay, but what about:

user=> `(println (str "Hello" ~(+ 41 1)))
(clojure.core/println (clojure.core/str "Hello" 42))
Am I missing something?

dvorme19:06:48

Then:

user=> (def tpl `(println (str "Hello" ~(+ 41 1))))
#'user/tpl
user=> tpl
(clojure.core/println (clojure.core/str "Hello" 42))
user=> (= '(clojure.core/println (clojure.core/str "Hello" 42)) tpl)
true

mynomoto19:06:30

You cannot see what clojure.core/str would produce.

dvorme19:06:25

In my hypothetical, I'm imagining that println is like <p... and str... is like <span... in Hoplon.

mynomoto19:06:21

(def elem1 [:span "Hello"])
(def elem2 [:div :.class])
(= [:div :.class [:span "Hello"]] (conj elem2 elem1))

mynomoto19:06:26

But '(clojure.core/conj elem2 elem1) would not be the same.

dvorme19:06:50

At the end of the day, I'm hearing that the difference is that Hiccup uses vectors and vectors conj onto the tail instead of the head, which is more convenient?

dvorme19:06:31

e.g.:

(-> `(str "Hello,") (concat ["world"]))

mynomoto19:06:18

Well, conj is an example but call a function would have the same effect, if you are using hiccup you would get the final vector and could transform it into something else. Let me try a more clear example:

(defn custom-element
  [greet]
  [:span :.greet greet])
(= [:span :.greet "Hello"] (custom-element "Hello"))

(defn custom-element-hoplon
  [greet]
  (h/span :class "greet" greet))
(= '(myns/custom-element-hoplon "Hello") `(custom-element-hoplon "Hello"))

dvorme19:06:11

Right. In Hoplon, it's conventional to build custom elements via fns versus always working at the meta level, then running the Hiccup interpreter to get the DOM. That said, I think there's nothing stopping us from using quote, syntax-quote, syntax-unquote, and friends to return lists instead of vectors. Then we eval the result. If we're scared of naked eval, we could write an (hl-eval function that sanity checks everything in function-call position... Same level of abstraction; plus we get automatic editor support. Since UI trees aren't that large, I'm thinking that the fact that appending to lists is O(n) probably doesn't matter in real life? Thoughts? My instinct is that I can't be the first person to have thought of this and so I strongly feel I might have missed something here...?

kennytilton20:06:54

I have asked the same. I do not hear much about the ability to program UIs by juggling vectors with CLJ, but I have heard folks say they liked the syntactic bifurcation of code from HTML. Me, I love the syntactic unification of code and DOM we see in Hoplon. Hiccup to me is being forced to change gears, if you will, mid-coding. And as you suggested, @U1U91M1B5, to what end? I have to think another factor is the React and JSX ancestry of CLJS libraries. Hiccup was just a natural translation of JSX into CLJ. And creatures of habit are we. And don't forget Tilton's Law: Never ask me, Why? I am just going to invent an incredibly plausible reason unrelated to why.

dvorme20:06:05

Makes sense @U0PUGPSFR. I'm glad I'm not the only person asking--and for similar reasons. We probably both learned Lisp without syntactic sugar for vectors... 😄 To me, something like this feels natural:

user=> (defn p
       "Paragraph tag stub"
       [& more]
       (apply str "<p>" (apply str (doall (interpose " " more))) "</p>"))
#'user/p
user=> (p "hello" "world")
"<p>hello world</p>"
user=> (defn greet [you]
         `(p "hello" ~you))
#'user/greet
user=> (greet "me")
(user/p "hello" "me")
user=> (eval (greet "me"))
"<p>hello me</p>"
user=>
We just reinvented Hiccup in 0 lines of code. 😛 I think...?

alandipert20:06:11

this is pure philosophizing and retrospective analysis which is usually fraught/absurdly off base

alandipert20:06:29

but my vague impression at the time we made hoplon was that hiccup felt like a greenspun's 10th rule situation

alandipert21:06:15

things that started with it tended to sprout novel evaluation semantics and naming schemes that were parts of lisp, re-imagined somehow around (usually) specially named keywords

alandipert21:06:24

in retrospect and in my own experience, having learned CL in the meantime, i see an insurmountable level and phase distinction between the idea of hiccup and actual HTML. namely, a callback on an actual element is passed this and otherwise has direct control of an embodied resource, at runtime

lambda-prompt 2
alandipert21:06:05

if you go the hiccup route, you have to reimplement everything about runtime events yousrelf for hiccup-time. this doesn't seem like much until you realize it includes event bubbling

alandipert21:06:39

hiccup escapes event re-implementation for the clojurist, but it's still there in the React runtime

alandipert21:06:28

also, i think when it was made available, the fluidity of manipulating pure data in cljs vs. everything else was pretty astounding to most peolpe

alandipert21:06:29

i guess another mark of the mismatch is the ^key business, they need to impose identity semantics

alandipert21:06:41

oh, it's also worth noting i suppose, that hiccup had lots of traction before cljs appeared. it was/is the premier way to produce markup from clj

alandipert21:06:57

https://github.com/cgrand/enlive was another popular way that is interesting

dvorme21:06:47

> Thanks @U04VC31U8.

👍 2
kennytilton01:06:40

Speaking of Lisp, with DOM as CLJ functions, well, we also have DOM as macros, and with macros we have all sorts of options for making code expressive/minimalist, and for producing proxy DOM that can be easily navigated for state sharing.