This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-22
Channels
- # arachne (8)
- # bangalore-clj (1)
- # beginners (72)
- # boot (95)
- # braveandtrue (5)
- # business (1)
- # capetown (1)
- # cider (180)
- # cljs-dev (8)
- # cljsrn (20)
- # clojure (104)
- # clojure-art (1)
- # clojure-brasil (8)
- # clojure-czech (1)
- # clojure-greece (15)
- # clojure-korea (13)
- # clojure-poland (2)
- # clojure-russia (53)
- # clojure-sg (5)
- # clojure-spec (60)
- # clojure-uk (35)
- # clojurescript (186)
- # community-development (3)
- # core-async (24)
- # cursive (18)
- # datascript (11)
- # datomic (39)
- # devcards (4)
- # emacs (2)
- # events (1)
- # funcool (23)
- # hoplon (148)
- # juxt (1)
- # ldnclj (2)
- # luminus (1)
- # off-topic (22)
- # om (27)
- # onyx (35)
- # overtone (2)
- # pedestal (7)
- # perun (8)
- # protorepl (2)
- # rdf (6)
- # re-frame (15)
- # reagent (2)
- # ring-swagger (10)
- # untangled (54)
and as an evolution to the 1st example - if you prefer brevity at the cost of a little complexity:
(let [opt (partial radio :marital :status)]
(row :p (* 2 p) :g g :b 1 :bc transparent-grey
(opt :single "Single")
(opt :married "Married")
(opt :divorced "Divorced")
(opt :widowed "Widowed")))
@onetom: so i'm thinking we should do away with elems
as a concrete part of the ui interface and replace them with piles
and flows
.
although both would be of type elem
, so to speak, and maybe an elem
is the terminal node.
@jumblerg: are those like columns and rows?
no. piles
stack elems back to front, over each other. flows
lay things out left right top bottom.
the biggest thing we're missing in ui right now is a way to put elements in front or behind of each other in a general way without disturbing the ltrb flow that makes everything intrinsically responsive.
we need a notion of a z axis, basically. this is also one of the missing abstractions that has prevented us from implementing controls like dropdown boxes in a general way. or dialogue/modal boxes that appear over a page.
a modal, for example, could be done like this:
(pile :s (r 1 1) :p 10
(flow :s (r 1 1)
...)
(flow :s (r 1 1) :a :mid :v (cell= (if alert true false))
(flow :s 200 :a :mid :b 2
"Alert!")))
the reason we want two different functions is because they take different arguments; gutters, for example, would not apply to piles.
piles could also be called stacks, i suppose, but pile seems a bit more irreverent. 🙂
maybe there are stronger words found in the vocabulary used by typesetters or something.
btw, if you are looking for inspiration, i highly recommend going thru http://www.rebol.com/docs/view-guide.html 😉
VID (Visual Interface Dialect) is still the most intuitive layout language i've ever seen
i mean it was the easiest to learn and keep in mind. it just felt natural. but it was not really meant for resizable layouts, so maybe that's why i can be so simple...
there's defininitely some good stuff here. interestingly enough, when i googled flows and stacks just now, qt came up.
and actually i haven't done conditional forms in it, neither multi-step forms and maybe it breaks down on those 😕
talking about qt, i showed you https://gridstylesheets.org in the past; did u have a chance to look into it?
also @laura told me that she was doing more and more swift programming and she really likes their constraint based layout model (and gss is also similar to that)
but i was thinking that since we have nice lexical scoping in clojure, so we don't need to come up with silly (gensym)
"pointers", maybe the constraint solver could actually get dom elements as parameters...
they're losing me with:
#light[years] == 100 !weak;
#light[years] == 200 !medium;
#light[years] == 300 !strong;
<ftp://ftp.cs.washington.edu/pub/constraints/papers/constraint-hierarchies-lisp-symb-comp.pdf>
we could allow each elem attribute that accepts a numerical value to also accept a set of constraints at some point. the practical value of this is unclear to me right now.
it might be way to express some of the functionality we already have more generally. i think this is something to investigate more thoroughly after we get all the basic layout features working across the board.
Hi, i have a question regarding state (we use hoplon/castra) I like to differentiate between ui-state and data-state (data coming from the be to display). Some ppl recently started to modify data-state on the fronend, depending on the result from the be (quoting about pure functions, ie: remove-item, should not return an updated list of all items). It feels quite hard to maintain this approach I usually would just want to have the backend being responsible for data-state (since its usually persisted, ie: remove-item either updates the list of all items on success, or returns error-cell and leaves data-cell as it was -- which is what mkremote is doing) using lenses and formula cells i can also pass muliple data-cells which are effected by a user action. Im not sure which approach is the better one, the latter feels much easier to maintain for me.
I know Micha is an advocate of the latter approach. If you are satisfied by the latency/UX of this approach then I'd say you should go with it.
we have much bigger bottlenecks for performance right now, query on db-after after transaction is not even noticeable with the eye on the amount of data we are working with
Updating data on the frontend and syncing with the backend is a very hard problem to do generically
@peterromfeld: if i understand your query correctly, the latter approach is probably the best place to start: it makes for a more stable system.
you can short-circuit the cqrs loop, so to speak, but this is an optimization, and i think the "optimize last" heuristic probably applies here.
thanks for reassuring my thoughts
i've found that one of the interesting benefits of working with versioned data, however (for example, if using a db like datomic), is that it becomes relatively safe to do these kinds of optimistic transactions.
but in my experience, the benefit is negligible, and may not be worth the trouble. depends on your use case, i guess.
if you have occasionally connected clients/concurrent updates - it becomes much harder, but then you can't escape doing stuff on the client anyway
@dm3: if your data is versioned, it becomes a lot like syncing git repos. but you can still end up with some nasty complexities; for example, i can imagine a scenario where one transaction is contingent upon some other value that was changed by another client if offline for a significant duration of time. then you have to implement some sort of backtracking scheme to get your client back to the right state, and it becomes unclear to the user what was written and what was not.
in a system with any significant amount of complexity, the longer the duration between synchronizations, the greater the odds the client could end up trying to write transactions based on stale data.
thats why you wanna have notify and refresh similiar to pivotal?
was looking very short into it but could not yet figure out, but did not had enough time
i'm not sure what pivotal tracker does, but when i was experimenting with optimistic transactions i decoupled the alerts from my views since the user could transition through several views of an application before getting a notification pertaining to some previous write.
it needs to be pretty clear to the user when data is being written, and when it is not.
@jumblerg you have a few solutions depending of the domain, but you need to merge histories somehow. E.g. OT works well for something like google docs
I'm a big fan of expressing the actions explicitly instead of trying to synchronize the dumb data though
yeah. on the other hand, if you wanted to snag shares of AAPL for $100, and then you purchased them for $125 an hour later, then maybe not-so-much.
maybe the system causes this super-late transaction to fail, as it should, due to the time difference. but the user might believe he made a small fortune, only to discover later on the purchase never went through. and should the client rewind the user back to the purchase form corresponding to the this failed transaction when the client fails to sync?
so, yeah, @dm3, i think it depends a lot on the domain whether it is worth the trouble.
this problem of late transaction rollback is getting magnified by the various (public) blockchains, where the transaction times are on the several seconds range by default and the global consensus can actually rewrite large portions of the history
@peterromfeld here are some refresheres for those "some ppl": https://github.com/hoplon/castra/blob/master/img/arch-full.png https://github.com/hoplon/castra/blob/master/img/arch-client.jpg
i try to avoid doing it, usually, since the backend can be optimized to perform validation as fast as you can ever need
btw, does anyone else experience non-updating cljs sources in chrome? it seems it's a long running problem: https://bugs.chromium.org/p/chromium/issues/detail?id=508270
@raywillig sure, but i don't have any "ring thing" for my frontend project, just a boot-jetty/serve
for files in assets/ and on the classpath
hmm @onetom saw something about a jetty.xml file for config. I wonder if the jetty running in boot-jetty would find it?
@micha im trying to straighten out our CQRS loops and im wondering how to load inter-dependent state.
im trying to chain a sequence with do-watch
but every time boot-reload
reloads the file, new watches are added but the old ones are not removed.
(defonce _ (do-watch ...))
works but of course i have to reload the whole page if i change anything it depends on
ah there problem is here: https://github.com/hoplon/hoplon/blob/master/src/hoplon/core.cljs#L46
iirc you might not have this issue because you always reload the whole page using the :on-load
option, no?
but while i was playing with this, i've also realized that a lot of the cell graph is regenerated on reload
it means any computation the old formula cells were doing is still done in the background
the kind of thinking required to hot patch running code is exactly the kind of thinking that javelin normally saves you from 🙂
ok, consider this: i have to load the current user first - if any then load some domain object based on what URL am i on - if there is a current user indeed then load more details of that domain object into a modal dialog - which is indicated to be open, also based on the URL, but also based on a property of the domain object
nvm, i will come up with some more tangible minimal example, then it's easier to discuss
With the latest version of cursive, the ide no longer supports .cljs.hl files--treats them as plain text. 😞
can't reproduce at the moment--keeps finding the old code which I thought I moved to the css directory.