hoplon

The :hoplon: ClojureScript Web Framework - http://hoplon.io/
2017-12-31T01:56:18.000035Z

@flyboarder oh nice, you setup karma for the tests :thumbsup:

flyboarder 2017-12-31T01:56:46.000008Z

yeah looking to get it working for chrome and firefox, attempting a rebuild right now

flyboarder 2017-12-31T01:57:26.000049Z

https://travis-ci.org/hoplon/hoplon

flyboarder 2017-12-31T01:57:43.000040Z

phantomjs is no problem, however the others are failing right now

2017-12-31T01:58:23.000013Z

mmm, also i'm wondering if we should move to circle

flyboarder 2017-12-31T01:59:01.000010Z

yeah, was looking at that also

2017-12-31T01:59:10.000014Z

i've got some example config files

flyboarder 2017-12-31T01:59:29.000024Z

i attempted to get it working on circle before

flyboarder 2017-12-31T01:59:36.000016Z

but that was before the new tests

2017-12-31T02:00:02.000073Z

circle have also changed their setup totally in 2.0

flyboarder 2017-12-31T03:41:28.000047Z

@thedavidmeister so im going to revert those tests, the karma server fails to run the tests for non phantomjs engines, I see the same behaviour on my local machine on the first run

2017-12-31T07:56:44.000036Z

@flyboarder i'm not surprised tbh, it's always a bit fiddly to get new test runners setup

kennytilton 2017-12-31T08:05:13.000004Z

I think you hit all the right points. Benchmarks are a dicey game — the moment we put aside the real code to test performance we are perforce (pun unintended) testing the performance of something else. More specifically, your point about Javelin serving a greater good (app state coordination) omitted by the benchmark is another fatal objection to that example.

kennytilton 2017-12-31T08:08:17.000018Z

A good response in the future would be to ask if a performance problem had been observed in the field, and if so if that code could be shared. Performance problems arise most often from problems in the larger algorithm, not low-level constructs.

kennytilton 2017-12-31T08:12:16.000004Z

Or maybe the user has a good use case worthy of getting the hood up on Javelin. I had one user using my hack to drive a C++ game engine in real time. Having the whole model/cell architecture would never have scaled. My recollection is fuzzy, but he himself hacked in a way to have a dependency on a key’s value in a hash-table. Worked great.

kennytilton 2017-12-31T08:17:23.000026Z

Over in MobX land they have something I guess akin to your lenses. I just have never run into the need, so Matrix (ne Cells) lacks that. But it would be a straightforward hack. I do have something I call Synapses, basically anonymous cells spawned within a formula that can perform any arbitrary transformation on values coming from referenced cells, such as throttling, converting to a delta — whatever. Those are fun, and useful lately in resolving XHR callback hell.

2017-12-31T08:31:15.000009Z

don't stress it, there's always version n+1 to chase up anything causing problems 🙂

2017-12-31T08:42:23.000033Z

@hiskennyness thanks for the review 🙂

2017-12-31T08:43:15.000004Z

i have tried your approach of asking for use cases with specific performance issues and been hit with the retort "it's because javelin isn't being used that you can't see the performance issues"

2017-12-31T08:44:20.000006Z

don't know what to say to that... seems like bad logic to me

2017-12-31T08:45:10.000015Z

can you share an example of a synapse?

2017-12-31T08:45:38.000029Z

i've put up that lens in context of performance, but actually it's quite a general pattern that i'm using more and more, "higher order cells" or something

2017-12-31T08:48:51.000034Z

so i'll write a low level API/wrapper like normal for some system, then i'll write a function that produces a lens on top of the API, so setting the value of the lens automatically does the right things to the API (validation, method calls, throttling, etc.) - similar to how storage cells interact with storage APIs, but it could be XHR or anything else

kennytilton 2017-12-31T08:56:09.000038Z

Wait, what? “it’s because javelin isn’t being used that you can’t see the performance issues” Someone not using Javelin said they were experiencing a performance problem with Javelin? I will guess we have segued from the benchmark report to folks just trolling Javelin without using it. Life is too short.

2017-12-31T09:03:19.000010Z

yes, it's a myth perpetuated by people who haven't seriously (or even casually) used javelin, often in defence of their choice of some other (probably more complicated) framework

2017-12-31T09:05:01.000040Z

almost knee jerk... when newbies jump into the main clojurescript slack channel asking what framework they should use, it's usually something react based - i suggest hoplon and it's often "performance! monolithic! not for "real" projects!"

2017-12-31T09:05:05.000001Z

all myths >.<

kennytilton 2017-12-31T09:05:12.000030Z

“it’s quite a general pattern” Yes, we Celluloids have broken through to a substantial cave system, have we not?

2017-12-31T09:05:57.000009Z

indeed... that's what it feels like

2017-12-31T09:07:33.000038Z

i have a nice example where i have a cell that is (roughly) a datascript entity and an "item attribute cell" function, where you pass it an entity and an attribute - it has the value of that attribute from datascript at all times, and when you set the cell it updates datascript after validation against spec, and then that datascript cell ships the updated value off over the wire

kennytilton 2017-12-31T09:07:36.000020Z

“people who haven’t seriously (or even casually) used javelin” Please picture me standing behind you on TV holding up “Matthew 22:14".

2017-12-31T09:08:03.000020Z

hah

2017-12-31T09:08:53.000028Z

i can then pass the item attribute cell to hoplon components - dropdown selects, text fields, checkboxes, whatever... they all just need to know to update a cell on user input

2017-12-31T09:08:57.000004Z

it's quite cool 🙂

kennytilton 2017-12-31T09:09:14.000005Z

OK, enough politics. Where are we holding the annual dataflow conference? No annual conference, no traction. I say Vegas.

2017-12-31T09:09:41.000009Z

haha, i think there was a "hopcon" on google hangouts once and i missed it >.<

2017-12-31T09:09:44.000011Z

damn timezones

kennytilton 2017-12-31T09:09:58.000020Z

Ivan Sutherland is still around, he can keynote the first.

kennytilton 2017-12-31T09:11:13.000067Z

When you ask for a synapse example, do you mean the code or the functionality?

2017-12-31T09:11:24.000039Z

i mean both would be nice

kennytilton 2017-12-31T09:13:57.000038Z

digging

kennytilton 2017-12-31T09:19:23.000018Z

I am shuffling repos so several (most) links are broken, but I wrote this up recently: https://github.com/kennytilton/tag/blob/master/cljs/Synapses.md

kennytilton 2017-12-31T09:26:49.000035Z

Basically at any depth within a cell C formula I can reference a seeming cell creation C’ and Just Use(tm) the value returned its formula. Some slick macrology memoizes C’ so it does not get created each time C runs and then can maintain private state it can use to throttle or transform its input. eg, C’ can read a value V’ changing a zillion times a second but return (> V’ 42), thus trigger C only when V’ crosses that threshold.

2017-12-31T09:27:40.000066Z

"This write-up assumes the reader has read the Matrix overview; " - broken link 😛

kennytilton 2017-12-31T09:27:48.000019Z

Actually, that ^^^ example does not require state.

kennytilton 2017-12-31T09:28:50.000025Z

Well, a fellow Celluloid does not need that link.🙂 But lemme go sort those links out anyway…

2017-12-31T09:29:58.000054Z

right, so it's something like my throttled cell example but has an explicit internal state rather than relying on managing an external local scope?

2017-12-31T09:31:32.000005Z

you can do it with one cell instead of 2+ cells

kennytilton 2017-12-31T09:32:34.000032Z

In the broken write-up there is an example in which the synapse makes an atom where it can stash each value of V’. The rule in pseudocode then is (if prior-value (- this-value prior-value) 0). ie, it is a synapse returning the delta of V’.

kennytilton 2017-12-31T09:34:11.000014Z

Sure, examples are like benchmarks: it is hard not to lose essential elements during distillation.

2017-12-31T09:35:12.000049Z

yeah i agree, there's a limit after which point you need to experience fixing a real "hard problem" in a nice way to truly get it

kennytilton 2017-12-31T09:35:16.000026Z

And to a degree we are talking about syntactic sugar, if you will.

kennytilton 2017-12-31T09:37:27.000004Z

I almost never use synapses. They were dead handy in addressing XHRT callback hell, however (the second approach, “Shake ’n Bake”): https://github.com/kennytilton/xhr/blob/master/cljs/XHR.md

2017-12-31T09:38:33.000044Z

"The telltale signature of CBH is (a) the deep indentation of (b) asynchronous handler within handler." - this is something i'm skeptical of

2017-12-31T09:38:53.000013Z

like when using a promise to "fix CBH" by removing nesting

kennytilton 2017-12-31T09:41:12.000074Z

Yeah, at the end I say sth like “the indentation is still there, but that is implicit in the problem so it should be there”. ie, Agreed, the flattening is an unwise security blanket.

2017-12-31T09:42:07.000010Z

it's focussing on a symptom rather than the problem imo

2017-12-31T09:42:34.000012Z

you can nest and reference and whatever else as much as you want with cells and it's not really confusing at all

2017-12-31T09:43:43.000010Z

referencing values, or calculations that derive values just seems easier to understand and manage than referencing async callbacks - no idea why, maybe one day i'll figure it out 😛

kennytilton 2017-12-31T09:45:55.000028Z

Yep. The real problem is asynchronicity. Synapses let me hide that. Well, I have not applied XHR in anger yet, so not sure yet.

2017-12-31T09:46:23.000009Z

we're doing pretty similar things i think

2017-12-31T09:46:50.000017Z

i don't have a writeup

kennytilton 2017-12-31T09:47:35.000058Z

Preaching to the choir provides a bit of relief from forever jawing with the trolls…

2017-12-31T09:47:59.000032Z

well i think we're going off and facing similar problems and discovering how cells fit into that

kennytilton 2017-12-31T09:51:21.000027Z

The one thing I see in binding.scala, MobX, and your response (and past writings of mine) is a certain defensiveness and/or comparison-with-X. I am striving to avoid that now and trying to accentuate the positive. MobX is blazing a path for us by showing a better way to drive ReactJS, so that will make it easier to hawk our wares.

2017-12-31T09:52:04.000003Z

the performance stuff yes, for sure

kennytilton 2017-12-31T09:52:53.000021Z

I’ll have to get to those links the next time I am up. Crashing now.

2017-12-31T09:53:17.000052Z

i feel there is a myth to dispel there, and a need to defend against something incorrect being said

2017-12-31T09:53:22.000001Z

but i also started this:

2017-12-31T09:54:11.000060Z

i think we could present things in a way that is much more obviously good than we currently do, to avoid getting into the situation of needing to be defensive in the first place

kennytilton 2017-12-31T13:44:50.000023Z

I heard somewhere that the way to go is to target the select few early adopters who are more inclined to experiment and soldier thru a learning curve, then let them spread the word. So everything we do needs target only the top enginers. Sounds right (and easier) to me.

kennytilton 2017-12-31T13:47:11.000020Z

One problem for us is TodoMVC. Yes, we need to toe that line, but it does not exercise interesting state management at all — every dependency goes back to the Todos!

kennytilton 2017-12-31T13:51:42.000015Z

My plan is to cobble together a more interesting demo app and evolve it gradually in a series of small write-ups. By the end the implicit state dependency graph should be substantial, and cover XHR requests and PostGres persistence and a 3rd party charting library, leaving the reader in a good place to build their own app.

kennytilton 2017-12-31T13:54:17.000035Z

I do not think we can convey the greatness of programming with cells by explaining it. Instead, we must somehow arrange for the audience to experience coding with cells.

kennytilton 2017-12-31T13:57:17.000013Z

I will comment more over in the issue, but I would like to suggest a stronger rallying cry than “It’s just HTML!“. That is an important feature, but a defensive one. I suggest something that gets to the experience we have as we build more and more elaborate applications without linearly simple code: “It Just Works!”

kennytilton 2017-12-31T13:58:02.000044Z

Indeed, I believe I have seen IJW in the context of ReactJS. We just take it further, beyond the view.

kennytilton 2017-12-31T14:36:06.000033Z

OK, the links here are fixed anyway: https://github.com/kennytilton/tag/blob/master/cljs/Synapses.md

kennytilton 2017-12-31T14:38:21.000025Z

Now I just have to fix the links in the links. 🙂 Btw, re me not using synapses much, I brought them up just to point out that should there be a performance problem requiring throttling we are ready. (We also have like four varieties of lazy cells. Those I do find use for.)

2017-12-31T14:57:42.000011Z

@hiskennyness well the cells stuff is all technically javelin, hoplon itself is "just HTML" + some minor convenience functions like with-timeout

2017-12-31T15:01:29.000037Z

not that i don't love cells, but i think what hoplon brings to the table is equally important in terms of web app development as it trivially facilitates composability, testability, interoperability, and extensibility for the DOM

kennytilton 2017-12-31T15:02:34.000043Z

Oh, OK, I do have trouble keeping Hoplon and Javelin apart.

2017-12-31T15:02:37.000065Z

maybe "just HTML" is a shitty tagline 😛

kennytilton 2017-12-31T15:03:27.000068Z

I am working on a relevant comment on the issue. 🙂

kennytilton 2017-12-31T15:04:43.000029Z

tl;dr: we creators are too close to our creations to explain them to others even though we are the ones who see most precisely why they rock.

kennytilton 2017-12-31T15:05:13.000033Z

Nice puzzle!

2017-12-31T15:06:33.000003Z

haha, well i didn't create hoplon, i had to learn it from scratch at the same time as learning cljs - which is where the biggest potential audience is

2017-12-31T15:06:49.000001Z

so i can share my personal experience with that learning curve before i forget it

2017-12-31T15:13:29.000019Z

well i tried to introduce hoplon in the last team i worked in, and currently i bring it up periodically at an agency i do some contracting for

2017-12-31T15:15:06.000051Z

people can understand it, they just don't want to for some reason

kennytilton 2017-12-31T15:22:29.000022Z

It may be a good news-bad news joke: Good: cells really are a dramatically superior paradigm shift. Bad: folks do not like their paradigms shifted. This gets back to worse-is-better: incremental steps such as ReactJS can succeed, but complete solutions will be rejected like a mismatched transplant.

2017-12-31T15:25:52.000094Z

sure, but i still think we can do better 🙂

2017-12-31T15:26:20.000001Z

7.1 and 7.2 are really good cleanups for hoplon, with improved tests and simpler/more extensible internals

2017-12-31T15:26:30.000046Z

and there's plenty of low hanging fruit for the homepage

kennytilton 2017-12-31T15:33:09.000044Z

Hey, I am once-more-into-the-breaching on the 17th…never say die!! But it is a wonderful challenge: how to give away tickets to heaven.

2017-12-31T15:40:51.000050Z

haha, i just keep using it and reporting problems

2017-12-31T15:41:27.000014Z

they seem to only get fixed by making things simpler and better tested, funny that 😉

2017-12-31T15:45:21.000006Z

aight, i put another comment on the issue

kennytilton 2017-12-31T23:52:29.000062Z

Yes, building stuff with it is the best revenge! 🙂