@flyboarder oh nice, you setup karma for the tests :thumbsup:
yeah looking to get it working for chrome and firefox, attempting a rebuild right now
phantomjs is no problem, however the others are failing right now
mmm, also i'm wondering if we should move to circle
yeah, was looking at that also
i've got some example config files
i attempted to get it working on circle before
but that was before the new tests
https://github.com/thedavidmeister/wheel/blob/master/.circleci/config.yml
circle have also changed their setup totally in 2.0
@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
@flyboarder i'm not surprised tbh, it's always a bit fiddly to get new test runners setup
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.
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.
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.
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.
don't stress it, there's always version n+1 to chase up anything causing problems 🙂
@hiskennyness thanks for the review 🙂
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"
don't know what to say to that... seems like bad logic to me
can you share an example of a synapse?
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
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
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.
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
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!"
all myths >.<
“it’s quite a general pattern” Yes, we Celluloids have broken through to a substantial cave system, have we not?
indeed... that's what it feels like
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
“people who haven’t seriously (or even casually) used javelin” Please picture me standing behind you on TV holding up “Matthew 22:14".
hah
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
it's quite cool 🙂
OK, enough politics. Where are we holding the annual dataflow conference? No annual conference, no traction. I say Vegas.
haha, i think there was a "hopcon" on google hangouts once and i missed it >.<
damn timezones
Ivan Sutherland is still around, he can keynote the first.
When you ask for a synapse example, do you mean the code or the functionality?
i mean both would be nice
digging
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
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.
"This write-up assumes the reader has read the Matrix overview; " - broken link 😛
Actually, that ^^^ example does not require state.
Well, a fellow Celluloid does not need that link.🙂 But lemme go sort those links out anyway…
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?
you can do it with one cell instead of 2+ cells
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’.
Sure, examples are like benchmarks: it is hard not to lose essential elements during distillation.
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
And to a degree we are talking about syntactic sugar, if you will.
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
"The telltale signature of CBH is (a) the deep indentation of (b) asynchronous handler within handler." - this is something i'm skeptical of
like when using a promise to "fix CBH" by removing nesting
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.
it's focussing on a symptom rather than the problem imo
you can nest and reference and whatever else as much as you want with cells and it's not really confusing at all
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 😛
Yep. The real problem is asynchronicity. Synapses let me hide that. Well, I have not applied XHR in anger yet, so not sure yet.
we're doing pretty similar things i think
i don't have a writeup
Preaching to the choir provides a bit of relief from forever jawing with the trolls…
well i think we're going off and facing similar problems and discovering how cells fit into that
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.
the performance stuff yes, for sure
I’ll have to get to those links the next time I am up. Crashing now.
i feel there is a myth to dispel there, and a need to defend against something incorrect being said
but i also started this:
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
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.
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!
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.
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.
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!”
Indeed, I believe I have seen IJW in the context of ReactJS. We just take it further, beyond the view.
OK, the links here are fixed anyway: https://github.com/kennytilton/tag/blob/master/cljs/Synapses.md
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.)
@hiskennyness well the cells stuff is all technically javelin, hoplon itself is "just HTML" + some minor convenience functions like with-timeout
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
Oh, OK, I do have trouble keeping Hoplon and Javelin apart.
maybe "just HTML" is a shitty tagline 😛
I am working on a relevant comment on the issue. 🙂
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.
Nice puzzle!
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
so i can share my personal experience with that learning curve before i forget it
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
people can understand it, they just don't want to for some reason
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.
sure, but i still think we can do better 🙂
7.1 and 7.2 are really good cleanups for hoplon, with improved tests and simpler/more extensible internals
and there's plenty of low hanging fruit for the homepage
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.
haha, i just keep using it and reporting problems
they seem to only get fixed by making things simpler and better tested, funny that 😉
aight, i put another comment on the issue
Yes, building stuff with it is the best revenge! 🙂