The :hoplon: ClojureScript Web Framework - http://hoplon.io/
Bhougland 2020-03-12T14:27:01.068600Z

Is this project still actively developed?

micha 2020-03-12T14:27:28.068800Z


Bhougland 2020-03-12T14:28:18.070100Z

That was fast! Btw, I just watch two YouTube speaches of yours. Loved them, very convincing.

micha 2020-03-12T14:28:42.070400Z

thanks, glad you like them 🙂

Bhougland 2020-03-12T14:30:11.072800Z

I am new at web programming and am looking at utility class CSS. Seems like it would be a good fit for Hopping. Is that the case?

micha 2020-03-12T14:31:42.073400Z

i am not familiar with that CSS framework, but hoplon doesn't interfere with how you use CSS

micha 2020-03-12T14:32:17.074Z

it's easy in hoplon to conditionally assign classes to DOM elements reactively

micha 2020-03-12T14:33:07.074800Z

most of the CSS frameworks i'm familiar with have APIs consisting of classes that are composed on DOM elements

micha 2020-03-12T14:33:32.075300Z

very straightfoward and intuitive to do that with hoplon in your app

micha 2020-03-12T14:33:59.075500Z

are you new to clojure as well?

Bhougland 2020-03-12T14:34:37.076100Z

Would panoply still be a good relevant demo?

Bhougland 2020-03-12T14:36:14.078500Z

Yes, I am still new to clojure. I have read a couple of books and have practed it for a while, and want to build something real

micha 2020-03-12T14:36:25.078800Z

that one uses a number of libraries, might be helpful to use a minimum number of libraries at first

micha 2020-03-12T14:36:54.079400Z

hoplon+javelin themselves don't do a lot, which i think is good

Bhougland 2020-03-12T14:38:08.081600Z

Utility class CSS is just a functional way to do CSS. This type of CSS is like tailwind and tacyons. It is actually close to inline styles.

micha 2020-03-12T14:38:39.081900Z

ah i personally like inline styles in hoplon

micha 2020-03-12T14:38:56.082500Z

i make javelin cells containing the styles and they update reactively

Bhougland 2020-03-12T14:39:22.083600Z

I thought it might be good for this use case

micha 2020-03-12T14:39:23.083800Z

but a lot of times i have to use bootstrap or something, so then you make cells containing classes

micha 2020-03-12T14:39:57.084500Z

yeah i really like the inline styles technique, because you can really get the most out of functional programming in CSS that way

Bhougland 2020-03-12T14:41:58.087700Z

Well, I will give it a whirl. I am going to try to create a small app based on the book "The Myth of Stress". It has worksheets you fill out that would seem to be very simple. I might drop in every now and again to ask questions. That's for the responses!

micha 2020-03-12T14:42:46.088Z

you can do a lot at first without a backend too

micha 2020-03-12T14:43:01.088400Z

just have functions that mock up the backend endpoints

micha 2020-03-12T14:43:05.088800Z

and use local storage

micha 2020-03-12T14:43:23.089500Z

reduce the number of things to learn at the same time

Bhougland 2020-03-12T14:43:47.090300Z

Can you use datascript? Would it be a good fit?

micha 2020-03-12T14:44:05.090700Z

you can use datascript, depending on how much data you have

micha 2020-03-12T14:44:28.091100Z

if you have large databases you can run into performance issues if you store them in cells

micha 2020-03-12T14:44:58.091600Z

i mean maybe those issues have been mitigated, i haven't done that in a while

micha 2020-03-12T14:45:51.093300Z

but one thing about javelin is that cells test whether an updated value is equal to the previous value, it only propagates a change to formula cells when the value changes

micha 2020-03-12T14:46:04.093700Z

so for a large datascript db the equality test can be expensive

Bhougland 2020-03-12T14:46:10.093800Z

Is the idea of updating the Dom similar to svelte in is?

micha 2020-03-12T14:46:21.094100Z


Bhougland 2020-03-12T14:46:30.094600Z


micha 2020-03-12T14:46:30.094700Z

i am not a svelte expert but it looks pretty cool

micha 2020-03-12T14:46:46.095100Z

but hoplon does not have a virtual dom

micha 2020-03-12T14:47:16.096Z

instead you bind individual attributes of dom elements to reactive cells

Bhougland 2020-03-12T14:48:00.097300Z

That is what I find so appealing. I love lisp and don't like the idea of having to learn about the whole React ecosystem (and being so tied to it)

micha 2020-03-12T14:48:38.097800Z

reagent, for example, seems pretty similar to hoplon

micha 2020-03-12T14:49:18.099500Z

and the reframe philosophy is basically the way you do things in hoplon naturally

micha 2020-03-12T14:49:56.101300Z

so it's all sort of converged to the same basic techniques

Bhougland 2020-03-12T14:50:11.101500Z

By the way, I asked if hoplon was still maintained on r/clojure. I can remove the post, answer it, or let someone in the core team answer it if you want the response to be public. Let me know.

micha 2020-03-12T14:51:35.103700Z

i'm not part of the core team btw, i haven't contributed anything lately, but the project is very much alive

micha 2020-03-12T14:52:04.105100Z

there just isn't much need for changes at this point

Bhougland 2020-03-12T14:52:19.105600Z

It is comforting that it does have convergence with reframe and reagent. What do you think of the URL driving data like in keechma?

Bhougland 2020-03-12T14:52:55.106700Z

Is that not needed because of the cell state machines?


I love hoplon and use it daily, I do think the main repo could use a little love/tidying up

micha 2020-03-12T14:53:13.107200Z

i'm not familiar with that, is that where state is stored in the url?

micha 2020-03-12T14:53:43.108Z

there was a project in like 2005 called seaside i believe that took that approach

Bhougland 2020-03-12T14:53:54.108600Z

http://Keechma.com it is based on reagent/reframe

micha 2020-03-12T14:55:07.109900Z

hoplon just provides DOM bindings for javelin, which provides reactive spreadsheet-like cells

micha 2020-03-12T14:55:29.110400Z

you can manage your state in any way you prefer, it's just clojure

Bhougland 2020-03-12T14:56:04.111300Z

Any best practices that you follow to manage state?

micha 2020-03-12T14:56:08.111500Z

we generally use unidirectional dataflow for sure

micha 2020-03-12T14:56:34.112100Z

cells will nudge you in that direction naturally, because formula cells are read-only

micha 2020-03-12T14:56:58.112600Z

so you'll usually end up with unidirectional dataflow in your program

micha 2020-03-12T14:57:33.113200Z

core.async is not used anywhere in javelin or hoplon, but that doesn't mean you can't incorporate that if you wanted to

micha 2020-03-12T14:57:49.113600Z

but in my opinion it doesn't have a compelling story

micha 2020-03-12T14:58:41.115200Z

but like consider the "ui components are decoupled and reusable" bullet point in the keechma features

micha 2020-03-12T14:59:08.115800Z

in hoplon your ui components would not need to declare dependencies, because lisp has lexical scope

micha 2020-03-12T15:00:23.117700Z

i personally find that lisp itself provides the abstraction i need for organizing the program components and so on

Bhougland 2020-03-12T15:00:58.117800Z

I appreciate the time and I will pop in again. Thanks to you both for the input!

micha 2020-03-12T15:01:29.118Z


micha 2020-03-12T15:01:38.118300Z

that's an optional library you can use if you want

micha 2020-03-12T15:02:11.119400Z

there is a diagram that shows how you can manage state with unidirectional dataflow

Bhougland 2020-03-12T15:02:28.120200Z

Can you use it with Vega charts, or libraries like OZ?

micha 2020-03-12T15:02:45.120600Z

if those are javascript libraries then yes 🙂

micha 2020-03-12T15:03:02.121400Z

hoplon doesn't have a virtual dom so it works fine with js libraries usually

Bhougland 2020-03-12T15:03:36.122900Z

Vega is a JavaScript library and oz is a clojure wrapper


I don't get the obsession with react these day. I see people recommend the react libs for cloure beginners all the time and think, this person now not only has to know html/css/clojure which are hard enough, but react too, as well as the subtle differences the cljs react libs introduce

Bhougland 2020-03-12T15:04:22.125Z

@jjttjj this is exactly why I want to try hoplon

rlander 2020-03-12T15:04:26.125300Z

@benjamin.hougland your post is at the top of /r/Clojure 😃


and all for what? React's main selling point in clojure is efficient rendering of elements, but at a kind of high cost of adding a layer that isn't compatible directly with the whole non-react ecosystem. I find the hardest part of building web apps is not ending up with a big pile of spaghetti code in 6 months, and i don't think the issues that react addresses (from a cljs perspective) help much with that. Because the real hard parts end up being state management, server interaction etc

micha 2020-03-12T15:08:46.130900Z

yeah i don't think perf is a huge factor for the apps i make

micha 2020-03-12T15:08:59.131500Z

we have very large hoplon apps that don't have perf issues

rlander 2020-03-12T15:09:13.131900Z

@jjttjj Yep. Every react project that I've been part of eventually had to come up with a few horrible hacks to accommodate dom-manipulating imperative libs.

micha 2020-03-12T15:09:16.132300Z

i'm making business apps though, not games

rlander 2020-03-12T15:09:25.132700Z

I think Hoplon should ride the Svelte train. That's how I got back to Hoplon: I watched a pretty convincing talk by Svelte creator Rich Harris and though "Wait, I've seen these same arguments before... Hoplon... Maybe I should give it another try"

Bhougland 2020-03-12T15:09:50.134Z

But isn't svelte supposed to be much faster than react? So I don't think the virtual Dom can claim that title.


yeah i hadn't seen Svelte, it does look cool, and like "hoplon for js"

micha 2020-03-12T15:09:58.134300Z

@rlander yeah svelte was a breath of fresh air, i enjoyed his demos

rlander 2020-03-12T15:13:41.136300Z

@benjamin.hougland Although it is faster than React in most cases, I think the performance bit is the least important part but, because it grabs the attention of younger devs, it has more visibility than it should.

Bhougland 2020-03-12T15:15:10.138900Z

I want to test it more because I want to leverage my clojure knowledge as much as possible

rlander 2020-03-12T15:15:33.139700Z

@micha @alandipert Did you see the reddit post? I think its a nice opportunity to throw some love Hoplon's way.

Bhougland 2020-03-12T15:15:59.140200Z

Seems simpler. I am a consultant by trade, so I know spreadshe:joy: ets

micha 2020-03-12T15:16:26.140600Z

seems to me that javelin might provide some advantages over js data in svelte

micha 2020-03-12T15:16:44.141300Z

like how clojure has strong concepts of identity and equality

micha 2020-03-12T15:16:55.141800Z

immutable colletions

rlander 2020-03-12T15:18:07.143300Z

@benjamin.hougland I can't say I have any relevant experience with Hoplon, but I've been writing react-based apps since 2015 and, after porting the Real World App to Hoplon (https://github.com/rlander/conduit) and using it in a few personal projects, I'm not going back to React. At least not for personal projects.

Bhougland 2020-03-12T15:19:03.145200Z

@rlander I will check out your project. Thanks!

rlander 2020-03-12T15:19:32.145900Z

The thing with Hoplon is that you only have to learn one new concept: cells. The rest is just plain cljs.

micha 2020-03-12T15:19:43.146300Z

hahai have to remember how to log into reddit now

Bhougland 2020-03-12T15:20:02.147100Z

But aren't cells just reference types?


@benjamin.hougland Have you been able to introduce hoplon to you project without any issues? I remember hitting snags the last few times I tried to start from scratch from the main repo. It may have been toolchain issues with me though (I don't currently use boot)

Bhougland 2020-03-12T15:20:47.148400Z

My project only consist of an idea at this point


(minor snags, for example new changes being continually appended to dom instead of replacing old changes)

rlander 2020-03-12T15:22:07.149500Z

@benjamin.hougland yes, but they're more than plain atoms with watches.


I would love to help with a push to fix up any little issues and actively promote hoplon more though 🙂

Bhougland 2020-03-12T15:24:32.152Z

I will give it a try and probably ask for lots of help:grin:

rlander 2020-03-12T15:25:32.152700Z

@jjttjj Me too.

rlander 2020-03-12T15:26:45.154700Z

I could take a look at the demos. Last time I tried them, most didn't work.

rlander 2020-03-12T15:27:36.156400Z

But at this point I think Jquery should be dropped. Or at least a jquery-less alternative ( like goog) should work 100%.

rlander 2020-03-12T15:28:50.158800Z

BTW, I love jquery, but in 2020 it's not the ideal marketing tagline "uses jquery".


I'm pretty sure the templates might not be working either. My problem personally is I use the tool.deps toolchain mainly now. For some reason I can't quite get boot working on Windows after a few attempts, and so it ends up being hard just to to get the hoplon template going and trying to debug it

rlander 2020-03-12T15:30:15.160100Z

@jjttjj They're not. I based the RealWorldApp off shadow-cljs because the boot-based templates were fairly old.


Yeah I do similar these days

rlander 2020-03-12T15:31:15.162400Z

shadow-cljs is absolutely awesome



Bhougland 2020-03-12T15:31:31.163300Z

The hoplon mobile site doesn't refer correctly in mobile

Bhougland 2020-03-12T15:31:41.163600Z



http://hoplon.io would benefit from a facelift, i can't believe it's been 5 years since we updated 😯

micha 2020-03-12T15:31:56.164Z

yeah we ran into a jquery issue at work, around properties vs attributes

micha 2020-03-12T15:32:17.164500Z

i don't remember if a PR was made to hoplon or not

micha 2020-03-12T15:32:26.165Z

i haven't been doing frontend stuff for a while


I think the prevalence of shadow might be another minor reason to remove jquery, as that kind of adds a very minor but diverging step to install the jquery dep via npm


i mean not that that's hard or a tricky problem, but I always start with the goog attribute providers anyway so I'm biased 🙂

rlander 2020-03-12T15:33:45.166200Z

I could not make the app work with the goog attr providers.


There was a bug I fixed somewhat recently, there might be others tho



rlander 2020-03-12T15:34:33.167400Z

ah ok. I'm using 7.2

rlander 2020-03-12T15:35:05.167800Z

Thanks for the link


gotcha. I think there still might be other bugs

rlander 2020-03-12T15:38:13.170500Z

@jjttjj coincidentally, a few months ago I was prototyping a dom library and stumbled upon your repo: https://github.com/jjttjj/diy


I was just going to mention that! fwiw, i was messing with a super minimal dom library a little while ago, and gradually realized i just wnated it to be hoplon and eventually just gave up and kind of made it basically slightly more minimal fork of hoplon

micha 2020-03-12T15:39:22.171600Z

i like that


it's now basically is just hoplon with things slightly rearranged internally in a way that im not even sure is better

Bhougland 2020-03-12T15:41:00.174300Z

Does the react cljs ecosystem still get the benefits of the Google clojure compiler? I image hoplon can use this feature of cljs better?

Bhougland 2020-03-12T15:41:19.174800Z


Bhougland 2020-03-12T15:41:45.175400Z

Or am I out to lunch on my understanding?


gclosure benefits cljs usage generally, i'm not sure if there are major differences in the level of benefit between hoplon and react-based libs

Bhougland 2020-03-12T15:43:12.177100Z

Oh okay

Bhougland 2020-03-12T15:44:26.178700Z

@alandipert btw, I liked your talk at clojure/west, finishing it up right now

Bhougland 2020-03-12T15:44:35.179Z

On youtube


@benjamin.hougland oh, thanks! glad you like it


@jjttjj diy is really cool. is the main overlap between hlisp and javelin cell attributes?


@alandipert actually the readme is kinda outdated (I should fix that). I basically ended up scrapping the "mutator" idea sort of


and now I end up just using the diy.hoplon interface, which is pretty much at feature parity with hoplon besides a couple things like the html/`head` singletons


at one point the idea was to sort of separate parse-args and allow people to plug in their own functions to handle the reasulting attributes and children elems, so the hoplon implementation would basically just implement do!/on!


but i kind of doubt at this point that the hoplon way can even be improved upon much

micha 2020-03-12T16:36:22.186200Z

@jjttjj did you see https://github.com/hoplon/hoplonfx, i tried a different approach to attributes there

micha 2020-03-12T16:36:56.187Z

not sure if it's better, but different 🙂


I did! and I've messed with your clojure PR for javelin a bit lately too


actually today I'm currently trying to implemnt javelin for https://github.com/borkdude/sci


so have been trying to wrap my head around the code walking parts

micha 2020-03-12T16:40:27.190200Z

the code walking parts are not strictly necessary


True but I like the magic of cell= :)

micha 2020-03-12T16:40:55.191200Z

ah right on


The goal being an in browser repl ui where i can just type in hoplon dom code that renders right next to it


(I think there are other way to do this besides sci)

micha 2020-03-12T16:42:12.192200Z

i wonder if riddley works with cljs

micha 2020-03-12T16:42:23.192700Z

probably not, but if it does you might look at https://github.com/hoplon/hoplonfx/blob/master/src/hoplonfx/cell.clj


yeah i was looking at that too after looking at your javelin clj stuff, not out of the box

micha 2020-03-12T16:42:43.193400Z

riddley makes the code walking stuff easier to understand i think


yeah I need to look closer at it

micha 2020-03-12T16:43:10.194100Z

a lot of the complexity in the javelin macro is keeping track of lexical bindings and so on



micha 2020-03-12T16:43:28.194600Z

riddley does that for you, mostly


i have been doing a lot of CL lately and picked up a few new ways to macro, i wonder if applying them to cell= would be good


also i wonder about distancing boot and templates from hoplon in the docs


as part of some kinda hoplon PR refresh


public relations that is

micha 2020-03-12T19:21:11.196900Z

sounds like an interesting idea

dave 2020-03-12T20:22:45.197500Z

craig has turned me onto formula-of and formulet. personally, i'd be happy if hoplon didn't give you a cell= and you always had to explicitly specify what the inputs to the formula are

dave 2020-03-12T20:23:16.198Z

sometimes it can be difficult for the human to reason about what the inputs are when looking at a cell= expression

micha 2020-03-12T20:24:12.198400Z

but the existence of cell= doesn't do any harm

micha 2020-03-12T20:24:41.199Z

you can use it if you want, or not if you don't, it's just an extra affordance for convenience

micha 2020-03-12T20:25:21.199200Z

i like having both

dave 2020-03-12T20:35:02.199700Z

i do, too, really. despite what i said above, i still use mostly cell=

dave 2020-03-12T20:35:23.200100Z

i guess i'm more curious about what an alternate universe hoplon would look like that required you to specify the inputs to formulas

micha 2020-03-12T20:35:49.200400Z

haha you can do that though, no?

micha 2020-03-12T20:35:54.200600Z

just don't use cell=?

dave 2020-03-12T20:38:24.201900Z

easier said than done when the codebase you're working on already uses cell= almost exclusively

dave 2020-03-12T20:39:05.203300Z

i basically continue to use cell= for consistency, and then switch over to formula-of or formulet whenever either i don't trust the code walking that cell= does, or i don't understand what the inputs are


i think at runtime cell= could expand to code that knows what are cells, so i can imagine a compile time var that changes the behavior so that every cell= prints out its formula-of equivalent or something

micha 2020-03-12T20:40:42.204900Z

it does do that at runtime, actually


haha true

micha 2020-03-12T20:41:02.205600Z

that's how it can deal with things that are cells or not cells


well it expands to what formula-of does, not a formula-of form

micha 2020-03-12T20:41:24.206100Z

both expand to the same thing basically


ok so a cell= substitute that sends you a PR when its compiled with a particulra option and run




man cell= is pretty hairy though, that would be good to clean up


i think we are smarter now and it could be tighter


maybe i will do this


it would be cool if macros could emit comments

micha 2020-03-12T20:45:24.208700Z

(comment ...)


i guess the comment macro


occupies a token position though

micha 2020-03-12T20:46:01.209400Z

(doto nil "my comment") yea

micha 2020-03-12T20:46:07.209600Z

or whatever




when you're making compilers its nice to be able to spew metadata without affecting the construct you're buildin

micha 2020-03-12T20:49:09.210500Z



has anyone experimented with making apps with cljs, but avoiding cljs data structures at runtime completely? i'm curious how small a deliverable can be that way


e.g. using only JS native types and macros

Bhougland 2020-03-12T21:01:17.213Z

Is react native really the only way to create an app with the clojurescript ecosystem?


@benjamin.hougland i know micha evaluated this recently and landed on javafx instead of cljs for cross platform native apps (and created hoplonfx along the way)


more options may have become available since then, but i don't know of them

micha 2020-03-12T21:23:38.216900Z

unfortunately i couldn't find a real-world way to compile javafx into a cross platform app

micha 2020-03-12T21:23:50.217200Z

so it's the web for me for now

micha 2020-03-12T21:24:31.217800Z

browsers are a lot better now in terms of exposing native capabilities than they were 5 years ago also


@dave out of curiosity, what issues with the code walking do you run into with cell= ?