Fork me on GitHub
#om
<
2015-12-11
>
dnolen00:12:05

@caleb I guess the docstring does talk about that

dnolen00:12:28

but I’d want to know what people are using this for

dnolen00:12:37

I added it separately from idents

dnolen00:12:43

as way to tag transactions on the reconciler

caleb00:12:12

@dnolen I was planning on using it to perform remote queries on specific items in a list. To lazy load associations

dnolen00:12:18

anyways I would not use it for now, or you should be OK with the fact that it might go away by beta.

caleb00:12:08

@dnolen: Okay I’ll avoid it then simple_smile thanks

dnolen00:12:19

those things don’t seem to need :ref to me while they may be convenient

dnolen00:12:40

anyways will need to audit this stuff for conceptual unity as we approach beta

dnolen00:12:49

but yeah just leave :ref alone for the time being.

dnolen00:12:34

I’ve amended the transact! docstring

caleb00:12:34

I’m having a hard time conceptually understanding how to fetch additional data on top of an existing query

tony.kay00:12:40

@caleb: One way to do what you want is to transact on the abstraction "load this thing now", in which case you can include the ident as a parameter to the mutation

tony.kay00:12:01

then modify the app state in such a way that your read code (for the remote interaction) can determine what you want to do

caleb00:12:06

I saw the defered loading example in the FAQ, but I can’t wrap my head around a more complicated example

tony.kay00:12:32

I'm assuming there is a user interaction that triggers the load

caleb00:12:54

Yeah. So I have alist of Projects, and each project has lots of measurements

caleb00:12:08

I want to load measurements for a project on demand

caleb00:12:13

(on a user action)

tony.kay00:12:29

(transact! '[(app/load-measurements {:item-id [:item 23]})])

tony.kay00:12:52

have that put a marker in app state

tony.kay00:12:00

then your read method says: if I see this marker, fill it in

tony.kay00:12:30

transact triggers a gather sends, which will allow remote fetch

caleb00:12:54

@tony.kay thank you. that’s perfect

caleb00:12:23

It seems so simple, but coming to this model from a traditional JS background, everything is new

dnolen00:12:36

@tony.kay: it might make sense to write up some of these common patterns on a design page somewhere

tony.kay00:12:40

it really is pretty dreamy how simple it is...but I understand that when you're new to the pieces it seems like you have to bend over backwards...then you realize...oh! I just say what I want to do!

dnolen00:12:56

it may be the case that some of them get converted feature … or not

dnolen00:12:08

but it’s a good way to understand what boilerplate everyone has to do

tony.kay00:12:19

@dnolen: Yeah, I keep trying to get time to work on more docs...I'm hoping the tutorial will eventually encompass a lot of these

caleb00:12:15

Yeah, and learning that Clojurescript can act like a framework of sorts, with composition and multimethods etc is pretty wild… If I come up with a clean example I’ll create a repo somewhere that people might find helpful.

jannis00:12:45

Hm, have we come across this before? If you build with :optimizations :advanced and call om/update-state! in a component (with a query), you get an uncaught No queries exist for component path (#object[Vu \"function Vu() {React.Component.apply... error.

dnolen00:12:05

@jannis: possible bug, not a ton of advanced testing yet

jannis00:12:35

The kanban demo runs fine with advanced and it uses om/update-state! in a component without a query...

dnolen00:12:25

It should be pretty simple to recreate. If you can file an issue.

jannis01:12:02

Heh, tried to reproduce it with a minimal app, getting a completely different error about an undefined prototype. Perhaps I'll try another day

thosmos01:12:13

@jannis: I was getting that in my project when it was using set-query! to change page query params.

jannis01:12:11

Without knowing anything about advanced optimizations it sounds like in certain situations components are optimized so much that Om can't identify them as belonging to particular queries anymore or statics and perhaps other Om "meta information" is lost.

jannis01:12:19

But.. no idea

thosmos01:12:51

this sort of minimalish router example breaks with :advanced: https://github.com/thos37/om-next-router-example/tree/pushy

dnolen01:12:39

The issue is simpler than it seems if it's like the previous cases

dnolen03:12:14

people having issues with advanced compilation should try master

dnolen03:12:20

make sure to clean, etc. etc.

jannis03:12:32

Ok, will try later - time for bed. I'm already messing up my sleep cycle, as evidenced by the Friday 4am commit on https://github.com/Jannis/custard/graphs/punch-card 😉

dnolen03:12:38

so I’m pondering killing off :shared and :shared-fn, as far as I can tell the link based approach is just far superior

dnolen03:12:08

and the support to allow changing :shared after the fact interacts badly with mock-root and devcards testing

dnolen03:12:19

so somebody needs to come up with a really compelling argument to keep it

jannis03:12:26

About that... if you have a structure like Root -> ListView -> ListItem and only Root and ListView have queries but you want to link to some global piece of data in ListView, it'll have to have a query, right?

dnolen03:12:55

but I don’t really see how that’s a problem

jannis03:12:57

Would that imply a need to introduce a read key like {:list-query (om/get-query ListView} only to embed the list view query in the root?

dnolen03:12:19

you would but again I don’t really see how this is a problem

dnolen03:12:27

in practice anyway

dnolen03:12:19

I suppose it’s nice to not have to declare it at the query level

jannis03:12:10

It's not a problem and I'm happy with killing off :shared and :shared-fn. Just wondering how to use "global" links in an elegant way.

dnolen03:12:34

the other option is to make :shared a once only thing and maybe provide a helper to re-render the root if you really, really want to change :shared

dnolen03:12:51

also would like to hear what people need componentWillReceiveProps for, suspecting it’s more trouble than it is worth

chris-andrews03:12:08

componentWillRecieveProps is useful for setting state in response to new props without causing 2 renders

chris-andrews03:12:20

I think that's the main use case

dnolen03:12:29

@chris-andrews: this is not relevant for Om

dnolen03:12:35

we don’t use React’s state mechanisms at all

dnolen03:12:46

:shared is now effectively once only

dnolen03:12:16

I added force-root-render! for people that really want to recompute :shared, not recommended for anything else

dnolen03:12:38

devcards is no longer completely busted

chris-andrews04:12:41

So if that's the case, then it's pretty likely componentWillUpdate would also cover any uses I can think of for componentWillRecieveProps

dnolen04:12:49

@rburns: I’m not really interested in examples

chris-andrews04:12:54

So, if you call set-state! from either shouldComponentUpdate or componentWillUpdate in om.next, will componentDidUpdate have the new props and new state at the same time?

dnolen04:12:06

I just want to hear rationale

dnolen04:12:02

@chris-andrews: not sure you should try it, but we control the semantics

dnolen04:12:27

so we can change them

dnolen04:12:53

we are in no way constrained by React setState behavior at all

dnolen04:12:59

calling set-state! in shouldComponentUpdate seems not useful to me

dnolen04:12:20

componentWillUpdate seems useful as well as a standard behavior for what you see in componentDidUpdate

dnolen04:12:51

second argument must be the query that generated the response

dnolen04:12:09

in order to avoid too much breakage, if not supplied will fall back on the old behavior

thosmos06:12:59

@dnolen: :advanced is now working using master

tony.kay06:12:26

@dnolen: we're using shared for i18n locale. Otherwise we have to pepper it into every query everywhere or access a separate global atom. Definitely don't want to kill it off completely. Having to force a refresh on locale change is fine for that case (in fact, we want to force re-render everything in that case), and I have found no other use for it so far.

tomayerst06:12:08

@tony.kay - loving the tutorials, thanks

tomayerst06:12:33

@dnolen - thanks for putting in all that extra hammock time for om-next 😉

tony.kay06:12:33

welcome sorry they're not more complete simple_smile

tomayerst06:12:23

@tony.kay - on UI Exercises I see this warning: Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using <ul>. See https://fb.me/react-warning-keys for more information.

tomayerst06:12:07

I see it from the given example at the top too, can I ignore it for now while I continue to get up to speed on this stuff

tony.kay06:12:44

yeah, don't sweat it. I'm not sure if my code is missing those, or something in devcards...either way it is harmless at the moment

tomayerst06:12:00

Thanks, also, can I feed back places where I find the instructions confusing? If so, what would be the best way?

tony.kay07:12:58

@tomayerst: file an issue is probably best.

jimmy09:12:03

does anyone know how to run https://github.com/swannodette/om-next-demo/ project ?

griffio09:12:32

@nxqd: You can try … from the todomvc folder lein repl (require '[todomvc.core]) (todomvc.core/dev-start) then http://localhost:8081/ That demo is a lot out of date and is not completed

artemyarulin10:12:46

Going through different example project of om-next I realised that it’s absolutely boring to go through the components itself as it’s contains mainly rendering and query/mutation names. You can get pretty much full picture by checking send, mutate and read logic, nothing else is needed much. This is awesome

nblumoe10:12:15

is component local state considered bad practice for "intermediate app state data"? More specifically: Form element values (pre-validation, non-persisting)

anmonteiro10:12:33

pretty sure it is good practice in such cases

nblumoe10:12:28

yes, exactly! I also found this pattern in the todomvc example. just had a discussion with a friend about whether to do this or not. he said that David explained in a talk, that this should not be done (but he could not refer to which talk this would have been).

nblumoe10:12:41

Does this also apply to handling validation errors on inputs? He was arguing too, that errors should also be pushed into components via props, whereas I am using local state (for now)

anmonteiro10:12:03

not sure if I understand the question, but there's nothing wrong with pushing validation via props and storing it on local state (only when first initializing local state) for later use

nblumoe10:12:48

Oh, sorry. I meant the actual error states. For example a vector holding the current errors (update-state my-component assoc :errors [:must-not-be-empty]) and then make use of that local state during rendering

anmonteiro10:12:37

not sure about that one

anmonteiro10:12:56

I'd say "depends"

anmonteiro10:12:13

which is not really helpful, but there are different scenarios there

anmonteiro10:12:41

if it's e.g. a truly reusable component, then nothing wrong with error states for validation being in local state

anmonteiro10:12:08

if the errors mean something application-wise I wouldn't put them in component local state, but rather in app-state

anmonteiro10:12:12

not only for truly reusable components, that was just an example; if the error state means nothing outside of that component, what's wrong with it being in local state?

nblumoe11:12:08

Allright, makes sense, thank you. simple_smile

jannis12:12:42

@nblumoe: What I've been doing so far is have forms operate on entities in the app state (e.g. a user) with mutations like (app/update-user {:name ~text-input}) and then annotate the entity with error properties (e.g. {:name "" :errors {:name "Name may not be empty"}}. The form would include :errors in its query and can then render the errors. So that's one way of doing via the app state and props.

jannis12:12:58

But I agree, there are cases to be made for both approaches, app state and local state.

jannis12:12:53

If you want to make the approach I described reusable, provide an :update-fn callback to a reusable form and wrap the form in an app-specific component that has a query for the form data and knows up to turn :update-fn into a transaction like the one described.

danielstockton12:12:03

i prefer storing intermediate or unvalidated form data in app-state, reason being that i can get a copy of the app-state from someone and i should be able to trigger the same errors

danielstockton12:12:33

but i don't store the errors themselves in the app-state, i see those as something that should result from the state but doesn't have to be a part of it

danielstockton12:12:41

the same state should trigger the same error validation logic

nblumoe12:12:46

when you put intermediate data into the app state, do you keep it in a separate subtree?

jannis12:12:57

So far I've either been updating existing entities or creating entities with tempids (when creating a new user for instance).

danielstockton12:12:36

yeah, i have a :forms subtree that holds data for the forms

danielstockton12:12:08

once i hit send, it clears the form if valid and updates the 'real' data

danielstockton12:12:44

i don't know if this is the best approach, just how i decided to do it

danielstockton12:12:38

i keep remembering a demo from circleci (i think) where they printed the app state, copied it to another browser and everything rendered exactly the same

danielstockton12:12:06

this is what im trying to follow in the back of my head

danielstockton12:12:25

seems like it could be a useful way of debugging

jannis12:12:54

@danielstockton: The separation certainly helps avoid dealing with conflicts/updates received from the server while editing a form. Do you react to updates happening in the "background" in any way?

jannis12:12:35

You know, like when an editor tells you a file you're editing has been changed on disk and asks whether you want to reload it?

danielstockton12:12:39

@jannis I don't, I guess that would add extra complications, good to think about

danielstockton12:12:13

atm data only really flows in one (circular) direction

jannis12:12:27

If you have explicit an "save" action, it's probably easiest to handle it then. Determine whether the data has changed/moved on, decide what to do in that case.

dnolen13:12:14

@thosmos: thanks for the confirm

jannis13:12:19

@dnolen: I still get the no components exist for component error with master and advanced compilation. But I can't reproduce it outside my app.

anmonteiro13:12:59

@dnolen: as I commented in #536, I thought componentWillReceiveProps was ultra-necessary, but I seem to be able to do everything in componentWillUpdate for my actual use cases

dnolen13:12:06

@jannis would want to see the full stacktrace

anmonteiro13:12:32

(just a "go ahead" to remove support for willreceive if necessary)

dnolen13:12:12

@anmonteiro: still collecting feedback at this point

dnolen13:12:30

but yeah I don’t think anyone actually needs it

dnolen13:12:40

and people will continue to encounter problems with it

anmonteiro13:12:42

I meant from my part, definitely don't wanna impose lol

dnolen13:12:59

@jannis try again with :pseudo-names true

anmonteiro13:12:32

@dnolen: was the removed line in this commit only there because of :shared? https://github.com/omcljs/om/commit/549166d9b74136b171cb69b758660729f9e4dd65

anmonteiro13:12:39

maybe should go ahead and remove the one with ::skip too

anmonteiro13:12:10

since ::skip is not queued anymore

jannis13:12:51

@dnolen: For some reason that doesn't affect the backtrace.

jannis13:12:59

Still as cryptic and short as before

dnolen13:12:47

look at the output JS

dnolen13:12:53

if you don’t have long names something is wrong

jannis13:12:24

Ah. boot cljs requires (cljs :optimizations :advanced :compiler-options {:pseudo-names true}), not (cljs :optimizations :advanced :pseudo-names true).

dnolen13:12:29

@jannis at the moment seems unlikely since that’s exactly what I fixed

dnolen13:12:51

I would double confirm that you have version you believe you do

dnolen13:12:48

@jannis the way to do this is to verify that the body of full-query in your project matches master

jannis13:12:37

It has iquery? and it's the same as master.

anmonteiro13:12:56

@jannis: does it only happen with advanced compilation?

anmonteiro13:12:03

let me try with an app I have

dnolen13:12:29

@jannis hrm, well it’s pretty clear where it’s going wrong

dnolen13:12:45

for some reason the component did not get indexed correctly

dnolen13:12:05

you can see the component path to the instance that failed in the query lookup

dnolen13:12:31

@jannis when does this error happen?

dnolen13:12:45

does your app start up? But then this error occurs if you try a transaction or something?

dnolen13:12:27

so I would dump the query index to verify anything is working at all

dnolen13:12:14

(-> reconciler get-indexer :indexes deref :class-path->query keys)

jannis14:12:24

I'm guessing that looks ok. There's an [App Requirement] entry in there (the 5th).

dnolen14:12:29

@jannis so there is something very strange there

dnolen14:12:36

those should only be constructors

dnolen14:12:40

but obviously that’s not the case

jannis14:12:19

Oh, you mean all the [object Object]s should be "function $web..." like with App?

dnolen14:12:36

that’s right

dnolen14:12:54

@jannis another debugging thing to try

dnolen14:12:20

(-> Requirements get-query meta :component)

dnolen14:12:46

if this returns [object Object] this is the thing to dig into to

jannis14:12:08

You mean Requirement instead of Requirements. That returns #object[$web$components$requirements$Requirement$$ [object Object]].

dnolen14:12:30

right so need to drill down into what the heck that thing is simple_smile

jannis14:12:39

build-index* receives the same thing as class. Only for App it's correct.

dnolen14:12:02

we don’t need to look at build-index*

dnolen14:12:10

it’s already wrong at get-query

jannis14:12:12

Just at how :component is set.

dnolen14:12:02

@jannis eye-balling the source of advanced compiled Requirements would be useful

dnolen14:12:13

@jannis :pretty-print true

anmonteiro14:12:21

@dnolen: is anything preventing us from using / in query params?

dnolen14:12:30

along with :pseudo-names true

anmonteiro14:12:40

e.g. '[(:some/key {:param ?this/param})]

anmonteiro14:12:44

doesn't seem to work

dnolen14:12:47

@anmonteiro: no reason that shouldn’t work

jannis14:12:12

@dnolen: Could it be that get-query needs to use (iquery? x) instead of (implements? IQuery x), like full-query?

anmonteiro14:12:24

getting Uncaught #error {:message "Invalid join, {:dom-com/props ?dom-com/query}", :data {:type :error/invalid-join}}

jannis14:12:27

(Still building, so I can only assume ahead)

dnolen14:12:37

@jannis I don’t think so

dnolen14:12:05

@jannis if you are seeing implements? IQuery

dnolen14:12:12

you are not using the right version of Om

dnolen14:12:17

there are no cases of that anymore

jannis14:12:46

True. What's this... let me look into it.

dnolen14:12:57

@jannis actually sorry mispoke

dnolen14:12:06

get-query and iquery? are the only places that should use it

dnolen14:12:15

and they are both correct far as I can tell

anmonteiro14:12:11

@dnolen: switching from using / to - in the param solves my issue. Is this something I could dig into?

dnolen14:12:20

@anmonteiro: sure go for it, probably something simple

anmonteiro14:12:34

where should I start? actually have no idea

jannis14:12:02

That's where var substitution takes place

dnolen14:12:16

@anmonteiro: the bug is right there

dnolen14:12:21

var->keyword

dnolen14:12:18

@anmonteiro: var? is also busted

dnolen14:12:23

both incorrectly use name

anmonteiro14:12:45

are you fixing it or should I?

dnolen14:12:41

@anmonteiro: please add test cases for it too simple_smile

anmonteiro14:12:42

alright, working on it

anmonteiro14:12:58

@dnolen yup that's where I'm starting

jannis14:12:02

@dnolen: Do you want me to uppload the pretty-printed app.js somewhere?

jannis14:12:11

Or is there anything particular that I should look at?

dnolen14:12:19

@jannis I just want to see Requirements

dnolen14:12:32

@jannis nothing jumping out there

dnolen14:12:48

but will need to think about it some more

dnolen14:12:17

@jannis I see the bug

anmonteiro15:12:53

@dnolen: is it OK for my patch to add "src/test" to the project.clj source-paths?

anmonteiro15:12:05

maybe I shouldn't conflate

chris-andrews15:12:37

@dnolen: since you were looking for feedback about componentWillReceiveProps, I’ll try to describe how I was using it (under the assumption that the lifecycle methods had the same behavior as in React)

jannis15:12:39

@dnolen: Oh, it passed an instance of the object to meta. Nice catch!

jannis15:12:49

I'll try it now

chris-andrews15:12:01

I need to render some things using three.js. Three.js has a very stateful API. As an example, you can't resize a buffer. If you have something where the number of vertices has changed from one pass to another, you actually need to remove that object from the scene and create a new one. For other modifications, like changing colors or position, you can update your original stateful object.

chris-andrews15:12:29

By using the react/om lifecycle methods, I can sort of smooth over that stateful API to get a functional API. What I want to do is pass in as props: the WebGL context where the object will be rendered, vertices, triangles, and color data. From there, the component should handle all of the logic of what three.js actually needs to do. The actual render function always returns nil because the output doesn't have a dom representation.

dnolen15:12:47

@chris-andrews: I understand how you might be using it, but realize it doesn’t actually work the way it’s supposed to in React for fairly arcane reasons

dnolen15:12:56

so the question is really why can’t you move that logic somewhere else

chris-andrews15:12:37

Ok, wasn’t sure I had ever explained it. In my case, I actually realized that there is a way around it for me

dnolen15:12:55

yes this is my suspicion, everyone actually has a fine workaround

dnolen15:12:01

and we can stop pretending we support it

dnolen15:12:03

cause we don't

chris-andrews15:12:18

The workaround for me is actually solved by om providing the key function

anmonteiro15:12:08

@dnolen: param thingy should be fixed in PR #540

chris-andrews15:12:23

For my use case, it’s actually a simpler result to just key components based on certain data, and if that data changes, the old component is destroyed and the new one is created. I would say that since it doesn’t work the same way as react, it might be best to remove componentWillReceiveProps, because really the only uses I can think of depend on it working exactly the same as in react

jannis15:12:18

@dnolen: Perfect, it works (of course)

jannis16:12:00

@dnolen: Would you be willing to push out another release for the fixes since alpha26?

dnolen16:12:23

will do later in the afternoon (for me)

jannis16:12:04

Sweet, thank you

anmonteiro17:12:40

what should I pass as the last argument to parser in case I want to do a remote read?

anmonteiro17:12:48

true or the name of the remote?

dnolen17:12:46

deployed 1.0.0-alpha28

artemyarulin18:12:39

hey guys, check this out - cross platform Om-Next component for mobile and browser + simultaneous editing on both platforms using figwheel: https://github.com/artemyarulin/ktoa/raw/master/omnext.browser.mobile.gif

dnolen18:12:25

haha amazing

artemyarulin18:12:44

nah, all the applause to @bhauman for the figwheel and to decker405 (don’t know your nick here sorry) for figwheel-react-native, I’ve just combined that simple_smile

decker40518:12:54

same one haha, looks awesome!

artemyarulin18:12:12

oh, now I know your nick here simple_smile

jgdavey20:12:05

Let’s say I’m organizing a top-level component that has several sub-level components, each of which has a query. What’s the correct was to handle parsing? I have a read function that tries to call (parser env query) as the value, but that doesn’t seem to handle remotes.

dnolen20:12:00

@jgdavey: do as little recursive parsing as possible

dnolen20:12:19

if you need recursive parsing it’s nearly always about query roots, deferred loading, stuff like that

dnolen20:12:00

using db->tree and/or DataScript should help keep your parsing needs modest

anmonteiro20:12:23

@dnolen: is this correct? when calling the parser with 2 arguments (local read), even if we return {:remote something} it has no effect

dnolen20:12:31

parse can be called any number of times on your query

dnolen20:12:04

in general you can expect that it will be called 1 for local and N more times for each remote you’ve declared

dnolen20:12:15

but you should not really care at all

dnolen20:12:53

other than perhaps branching in your reads so that you’re not doing work for the remote cases that you don’t need to do

anmonteiro20:12:47

cool, thanks

tony.kay21:12:39

@dnolen: I'm seeing the need for general recursive parsing. Any time you want to embed a parameter somewhere you have to walk down to that point. db->tree nor Datascript help with that. The fact that some cases exist in arbitrary places often means walking through stuff that you would have otherwise been able to use db->tree on. Fortunately, it is pretty easy to generate a few helper functions that make it pretty trivial to write (and even hide the recursive calls to parser). My helpers so far are not finished, but it might be something to consider providing as lego blocks.

tony.kay21:12:08

for both the local and remote sides...

tony.kay21:12:50

my sketch of ideas are in the app in the tutorial so far

jgdavey21:12:56

Okay, so what I’m wanting to do is recursive parsing: where downstream components have arbitrary queries, and the things compose together. So that read can handle downstream joins, etc.

tony.kay21:12:56

@jgdavey: I recommend separating remote and local logic at the entry point read function...case by target, then call off to a remote-read vs local-read. Then it isn't all hard to reason about

dnolen21:12:01

@tony.kay: yeah I’m not super interested in that problem

tony.kay21:12:16

@dnolen: OK. It is easy enough to provide as community bit

dnolen21:12:20

if you’re going to distribute parameterization through your query then that you’re own problem to solve

dnolen21:12:51

obviously generalizing that just creates even more burden on storage integration

dnolen21:12:56

for people who may not care at all

tony.kay21:12:57

not IQueryParams, [(:a {:blah 2})]

dnolen21:12:08

no I understand what you are saying

dnolen21:12:12

and I’m saying no way

tony.kay21:12:16

no problem simple_smile

tony.kay21:12:20

I'm not advocating standard functions for dealing with the parameters, just some to help you walk the graph on the way to it

tony.kay21:12:33

e.g. how do I walk through this join/union/etc

tony.kay21:12:42

recursion on remotes is even messier

dnolen21:12:48

this is what the AST stuff is for

tony.kay21:12:56

but consistent, so easy to write helpers for

dnolen21:12:08

the whole point of having the AST is so that if parse can’t solve your problem

dnolen21:12:17

switch to write your own traversal of the AST

dnolen21:12:25

you can build generic walkers

tony.kay21:12:50

fair enough, but it changes the problem domain from one that is more widely understood (recursive parsing) to data transforms on an AST (which are internally recursive). The helpers I've written so far make it trivial to understand and write what you want....just simply splits out the bits of db->tree as reusable components. Because ultimately, you are just doing that...transforming the db to a tree...but all of the logic in db->tree is all jumbled together so it isn't reusable.

dnolen21:12:12

@tony.kay: maybe this is deep in a area where I don’t care about convenience at all

dnolen21:12:23

if you can show that it will work for all kinds of storage, then worth considering

dnolen21:12:01

lots of people aren’t going to use db->tree

dnolen21:12:05

can’t or won't

tony.kay21:12:31

Well, you are providing db->tree, which IS about the default db format, so you do care about supporting that format. The default db format is fast (Datascript will be much slower...it does a lot more). I have a feeling that in practice you'll want to use plain maps. In which case, it makes sense to me to fully support ease of use for that. But, it is your library, and it is trivial to add these kinds of helpers as a separate one, so it probably isn't worth the breath simple_smile

dnolen21:12:08

there’s lot more work to do and more code to add

dnolen21:12:14

everything that isn’t beta is on the back burner

dnolen21:12:23

and eventually I will just starting saying no to helpers

dnolen21:12:34

people will have all kinds of things for all kinds of situations

dnolen21:12:39

and I don’t want to know or care about these things at all

tony.kay21:12:18

not advocating cycles...just talking in response to the comment of the form "you don't really want to do much recursive parsing". That is not my experience so far.

dnolen21:12:37

@tony.kay: right but it just depends on what you are doing

dnolen21:12:46

some people are building symbolic expression stuff

dnolen21:12:54

they don’t need any of this stuff at all

tony.kay22:12:17

agreed. Library design is a bit of an art, and I appreciate your position on it.

dnolen22:12:47

for me it’s mostly a surface area thing

dnolen22:12:00

there’s a lot of subtle code already, and I want to keep it under control

dnolen22:12:14

as long as we’re not interfering with user innovation / additions then we’re on the right track

tony.kay22:12:38

or overburdening them with noise/choices that don't matter

tony.kay22:12:03

yes. we are in total agreement

maackle23:12:10

Can I get a quick description of how to run https://github.com/swannodette/om-next-demo? There’s nothing in the README

jannis23:12:54

@dnolen: I may have found another issue with advanced optimization: web.app/?state is not ISeqable. I'm guessing this is about parameterized queries: https://github.com/Jannis/custard/blob/master/src/web/app.cljs#L18

dnolen23:12:09

More skeptical about that sounds like a bug not in Om

dnolen23:12:17

File an issue with stack trace, won't get a chance to look till probably next week

jannis23:12:33

Ok. I'll dig a bit deeper to see if it's a bug in my app.

jannis23:12:42

Right. The backtick turns {(:foo {:baz ?baz})} into {(:foo {:baz my.app/?baz)}} which I guess Om can't substitute

jannis23:12:00

'{(:foo {:baz ?baz})} would work but with quoting, subqueries can't be merged (e.g. '{(:foo (om/get-query Foo) {:baz ?baz})}).

jannis23:12:58

I just forgot about ~'... and it's working simple_smile